LCOV - code coverage report
Current view: top level - synthesis/TransformMachines - WProjectFT.cc (source / functions) Hit Total Coverage
Test: casa_coverage.info Lines: 0 777 0.0 %
Date: 2023-10-25 08:47:59 Functions: 0 31 0.0 %

          Line data    Source code
       1             : //# WProjectFT.cc: Implementation of WProjectFT class
       2             : //# Copyright (C) 2001-2016
       3             : //# Associated Universities, Inc. Washington DC, USA
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: aips2-request@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //# $Id$
      27             : 
      28             : 
      29             : #include <casacore/casa/Quanta/UnitMap.h>
      30             : #include <casacore/casa/Quanta/MVTime.h>
      31             : #include <casacore/casa/Quanta/UnitVal.h>
      32             : #include <casacore/casa/Utilities/CountedPtr.h>
      33             : #include <casacore/measures/Measures/Stokes.h>
      34             : #include <casacore/coordinates/Coordinates/CoordinateSystem.h>
      35             : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
      36             : #include <casacore/coordinates/Coordinates/SpectralCoordinate.h>
      37             : #include <casacore/coordinates/Coordinates/StokesCoordinate.h>
      38             : #include <casacore/coordinates/Coordinates/Projection.h>
      39             : #include <casacore/ms/MeasurementSets/MSColumns.h>
      40             : #include <casacore/casa/BasicSL/Constants.h>
      41             : #include <casacore/scimath/Mathematics/FFTServer.h>
      42             : #include <synthesis/TransformMachines/WProjectFT.h>
      43             : #include <synthesis/TransformMachines/WPConvFunc.h>
      44             : #include <casacore/scimath/Mathematics/RigidVector.h>
      45             : #include <msvis/MSVis/StokesVector.h>
      46             : #include <synthesis/TransformMachines/StokesImageUtil.h>
      47             : #include <msvis/MSVis/VisBuffer.h>
      48             : #include <msvis/MSVis/VisSet.h>
      49             : #include <msvis/MSVis/VisibilityIterator.h>
      50             : #include <casacore/images/Images/ImageInterface.h>
      51             : #include <casacore/images/Images/PagedImage.h>
      52             : #include <casacore/casa/Containers/Block.h>
      53             : #include <casacore/casa/Containers/Record.h>
      54             : #include <casacore/casa/Arrays/ArrayLogical.h>
      55             : #include <casacore/casa/Arrays/ArrayMath.h>
      56             : #include <casacore/casa/Arrays/Array.h>
      57             : #include <casacore/casa/Arrays/MaskedArray.h>
      58             : #include <casacore/casa/Arrays/Vector.h>
      59             : #include <casacore/casa/Arrays/Slice.h>
      60             : #include <casacore/casa/Arrays/Matrix.h>
      61             : #include <casacore/casa/Arrays/Cube.h>
      62             : #include <casacore/casa/Arrays/MatrixIter.h>
      63             : #include <casacore/casa/BasicSL/String.h>
      64             : #include <casacore/casa/Utilities/Assert.h>
      65             : #include <casacore/casa/Exceptions/Error.h>
      66             : #include <iostream>
      67             : #include <iomanip>
      68             : #include <casacore/lattices/Lattices/ArrayLattice.h>
      69             : #include <casacore/lattices/Lattices/SubLattice.h>
      70             : #include <casacore/lattices/LRegions/LCBox.h>
      71             : #include <casacore/lattices/LEL/LatticeExpr.h>
      72             : #include <casacore/lattices/Lattices/LatticeCache.h>
      73             : #include <casacore/lattices/LatticeMath/LatticeFFT.h>
      74             : #include <casacore/lattices/Lattices/LatticeIterator.h>
      75             : #include <casacore/lattices/Lattices/LatticeStepper.h>
      76             : #include <casacore/casa/Utilities/CompositeNumber.h>
      77             : #include <casacore/casa/OS/Timer.h>
      78             : #include <casacore/casa/OS/HostInfo.h>
      79             : #include <sstream>
      80             : #ifdef _OPENMP
      81             : #include <omp.h>
      82             : #endif
      83             : using namespace casacore;
      84             : namespace casa { //# NAMESPACE CASA - BEGIN
      85             : 
      86           0 : WProjectFT::WProjectFT( Int nWPlanes, Long icachesize, Int itilesize, 
      87           0 :                         Bool usezero, Bool useDoublePrec, const Double minW, const Double maxW, const Double rmsW)
      88             :   : FTMachine(), padding_p(1.0), nWPlanes_p(nWPlanes),
      89             :     imageCache(0), cachesize(icachesize), tilesize(itilesize),
      90             :     gridder(0), isTiled(false), 
      91             :     maxAbsData(0.0), centerLoc(IPosition(4,0)), offsetLoc(IPosition(4,0)), usezero_p(usezero), 
      92           0 :     machineName_p("WProjectFT"), timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0), minW_p(minW), maxW_p(maxW), rmsW_p(rmsW)
      93             : {
      94           0 :   convSize=0;
      95           0 :   tangentSpecified_p=false;
      96           0 :   lastIndex_p=0;
      97           0 :   useDoubleGrid_p=useDoublePrec;
      98           0 :   wpConvFunc_p=new WPConvFunc(minW, maxW, rmsW);
      99             : 
     100           0 : }
     101           0 : WProjectFT::WProjectFT(Int nWPlanes, 
     102             :                        MPosition mLocation, 
     103             :                        Long icachesize, Int itilesize, 
     104           0 :                        Bool usezero, Float padding, Bool useDoublePrec, const Double minW, const Double maxW, const Double rmsW)
     105             :   : FTMachine(), padding_p(padding), nWPlanes_p(nWPlanes),
     106             :     imageCache(0), cachesize(icachesize), tilesize(itilesize),
     107             :     gridder(0), isTiled(false),  
     108             :     maxAbsData(0.0), centerLoc(IPosition(4,0)), offsetLoc(IPosition(4,0)),
     109             :     usezero_p(usezero),  
     110           0 :     machineName_p("WProjectFT"), timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0), minW_p(minW), maxW_p(maxW), rmsW_p(rmsW)
     111             : {
     112           0 :   convSize=0;
     113           0 :   savedWScale_p=0.0;
     114           0 :   tangentSpecified_p=false;
     115           0 :   mLocation_p=mLocation;
     116           0 :   lastIndex_p=0;
     117           0 :   wpConvFunc_p=new WPConvFunc(minW, maxW, rmsW);
     118           0 :   useDoubleGrid_p=useDoublePrec;
     119           0 : }
     120           0 : WProjectFT::WProjectFT(
     121             :                        Int nWPlanes, MDirection mTangent, 
     122             :                        MPosition mLocation, 
     123             :                        Long icachesize, Int itilesize, 
     124           0 :                        Bool usezero, Float padding, Bool useDoublePrec, const Double minW, const Double maxW, const Double rmsW)
     125             :   : FTMachine(), padding_p(padding), nWPlanes_p(nWPlanes),
     126             :     imageCache(0), cachesize(icachesize), tilesize(itilesize),
     127             :     gridder(0), isTiled(false),  
     128             :     maxAbsData(0.0), centerLoc(IPosition(4,0)), offsetLoc(IPosition(4,0)),
     129             :     usezero_p(usezero), 
     130           0 :     machineName_p("WProjectFT"), timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0), minW_p(minW), maxW_p(maxW), rmsW_p(rmsW)
     131             : {
     132           0 :   convSize=0;
     133           0 :   savedWScale_p=0.0;
     134           0 :   mTangent_p=mTangent;
     135           0 :   tangentSpecified_p=true;
     136           0 :   mLocation_p=mLocation;
     137           0 :   lastIndex_p=0;
     138           0 :   wpConvFunc_p=new WPConvFunc(minW, maxW, rmsW);
     139           0 :   useDoubleGrid_p=useDoublePrec;
     140           0 : }
     141             : 
     142           0 : WProjectFT::WProjectFT(const RecordInterface& stateRec)
     143           0 :   : FTMachine(),machineName_p("WProjectFT"), timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0)
     144             : {
     145             :   // Construct from the input state record
     146           0 :   String error;
     147           0 :   if (!fromRecord(error, stateRec)) {
     148           0 :     throw (AipsError("Failed to create WProjectFT: " + error));
     149             :   };
     150           0 : }
     151             : //---------------------------------------------------------------------- 
     152           0 : WProjectFT& WProjectFT::operator=(const WProjectFT& other)
     153             : {
     154           0 :   if(this!=&other) {
     155             :     //Do the base parameters
     156           0 :     FTMachine::operator=(other);
     157             :     
     158             :     
     159           0 :     padding_p=other.padding_p;
     160           0 :     nWPlanes_p=other.nWPlanes_p;
     161           0 :     imageCache=other.imageCache;
     162           0 :     cachesize=other.cachesize;
     163           0 :     tilesize=other.tilesize;
     164           0 :     if(other.gridder==0)
     165           0 :       gridder=0;
     166             :     else{
     167           0 :       uvScale.resize();
     168           0 :       uvOffset.resize();
     169           0 :       uvScale=other.uvScale;
     170           0 :       uvOffset=other.uvOffset;
     171           0 :       gridder = new ConvolveGridder<Double, Complex>(IPosition(2, nx, ny),
     172           0 :                                                      uvScale, uvOffset,
     173           0 :                                                      "SF");
     174             :     }
     175             : 
     176           0 :     isTiled=other.isTiled;
     177             :     //lattice=other.lattice;
     178             :     //arrayLattice=other.arrayLattice;
     179           0 :     lattice=0;
     180           0 :     arrayLattice=0;
     181             : 
     182           0 :     maxAbsData=other.maxAbsData;
     183           0 :     centerLoc=other.centerLoc;
     184           0 :     offsetLoc=other.offsetLoc;
     185           0 :     usezero_p=other.usezero_p;
     186           0 :     machineName_p=other.machineName_p;
     187           0 :     wpConvFunc_p=other.wpConvFunc_p;
     188           0 :     timemass_p=0.0;
     189           0 :     timegrid_p=0.0;
     190           0 :     timedegrid_p=0.0;
     191           0 :     minW_p=other.minW_p;
     192           0 :     maxW_p=other.maxW_p;
     193           0 :     rmsW_p=other.rmsW_p;
     194             :   };
     195           0 :   return *this;
     196             : };
     197             : 
     198             : //----------------------------------------------------------------------
     199           0 :   WProjectFT::WProjectFT(const WProjectFT& other) :FTMachine(), machineName_p("WProjectFT"),
     200           0 : timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0)
     201             : {
     202           0 :   operator=(other);
     203           0 : }
     204             : 
     205           0 : FTMachine* WProjectFT::cloneFTM(){
     206           0 :   return new WProjectFT(*this);
     207             : }
     208             : 
     209             : //----------------------------------------------------------------------
     210           0 : void WProjectFT::init() {
     211             :   /*  if((padding_p*padding_p*image->shape().product())>cachesize) {
     212             :     isTiled=true;
     213             :     nx    = image->shape()(0);
     214             :     ny    = image->shape()(1);
     215             :     npol  = image->shape()(2);
     216             :     nchan = image->shape()(3);
     217             :   }
     218             :   else {*/
     219             :     // We are padding.
     220           0 :     isTiled=false;
     221           0 :     CompositeNumber cn(uInt(image->shape()(0)*2));    
     222           0 :     nx    = cn.nextLargerEven(Int(padding_p*Float(image->shape()(0))-0.5));
     223           0 :     ny    = cn.nextLargerEven(Int(padding_p*Float(image->shape()(1))-0.5));
     224             :     //cerr << "INIT shape " <<  image->shape()(0) << " " << image->shape()(1) << " new " << nx << " "  << ny << endl;
     225           0 :     npol  = image->shape()(2);
     226           0 :     nchan = image->shape()(3);
     227             :     //}
     228             :   
     229             :   //  if(image->shape().product()>cachesize) {
     230             :   //   isTiled=true;
     231             :   // }
     232             :   // else {
     233             :   // isTiled=false;
     234             :   // }
     235             :   //The Tiled version need some fixing: sof or now
     236           0 :   isTiled=false;
     237             : 
     238             :  
     239           0 :   sumWeight.resize(npol, nchan);
     240             :   
     241           0 :   wConvSize=max(0, nWPlanes_p);
     242           0 :   convSupport.resize(wConvSize);
     243           0 :   convSupport=0;
     244             : 
     245           0 :   uvScale.resize(3);
     246           0 :   uvScale=0.0;
     247           0 :   uvScale(0)=Float(nx)*image->coordinates().increment()(0); 
     248           0 :   uvScale(1)=Float(ny)*image->coordinates().increment()(1); 
     249           0 :   if(savedWScale_p==0.0){
     250           0 :     uvScale(2)=Float(wConvSize)*abs(image->coordinates().increment()(0));
     251             :   }
     252             :   else{
     253           0 :     uvScale(2)=savedWScale_p;
     254             :   }
     255           0 :   uvOffset.resize(3);
     256           0 :   uvOffset(0)=nx/2;
     257           0 :   uvOffset(1)=ny/2;
     258           0 :   uvOffset(2)=0;
     259             :   
     260             :   
     261             : 
     262           0 :   if(gridder) delete gridder; gridder=0;
     263           0 :   gridder = new ConvolveGridder<Double, Complex>(IPosition(2, nx, ny),
     264           0 :                                                  uvScale, uvOffset,
     265           0 :                                                  "SF");
     266             : 
     267             :   // Set up image cache needed for gridding. 
     268           0 :   if(imageCache) delete imageCache; imageCache=0;
     269             :   
     270             :   // The tile size should be large enough that the
     271             :   // extended convolution function can fit easily
     272           0 :   if(isTiled) {
     273           0 :     Float tileOverlap=0.5;
     274           0 :     tilesize=min(256,tilesize);
     275           0 :     IPosition tileShape=IPosition(4,tilesize,tilesize,npol,nchan);
     276           0 :     Vector<Float> tileOverlapVec(4);
     277           0 :     tileOverlapVec=0.0;
     278           0 :     tileOverlapVec(0)=tileOverlap;
     279           0 :     tileOverlapVec(1)=tileOverlap;
     280           0 :     Int tmpCacheVal=static_cast<Int>(cachesize);
     281           0 :     imageCache=new LatticeCache <Complex> (*image, tmpCacheVal, tileShape, 
     282             :                                            tileOverlapVec,
     283           0 :                                            (tileOverlap>0.0));
     284             :     
     285             :   }
     286           0 : }
     287             : 
     288             : // This is nasty, we should use CountedPointers here.
     289           0 : WProjectFT::~WProjectFT() {
     290           0 :   if(imageCache) delete imageCache; imageCache=0;
     291           0 :   if(gridder) delete gridder; gridder=0;
     292             :   /*
     293             :   if(arrayLattice) delete arrayLattice; arrayLattice=0;
     294             :   
     295             :   Int numofmodels=convFunctions_p.nelements();
     296             :   for (Int k=0; k< numofmodels; ++k){
     297             :     delete convFunctions_p[k];
     298             :     delete convSupportBlock_p[k];
     299             : 
     300             :   }
     301             :   */
     302             :   // convFuctions_p.resize();
     303             :   //  convSupportBlock_p.resize();
     304             : 
     305           0 : }
     306             : 
     307             : 
     308           0 : void WProjectFT::setConvFunc(CountedPtr<WPConvFunc>& pbconvFunc){
     309             : 
     310           0 :   wpConvFunc_p=pbconvFunc;
     311           0 : }
     312           0 : CountedPtr<WPConvFunc>& WProjectFT::getConvFunc(){
     313             : 
     314           0 :   return wpConvFunc_p;
     315             : }
     316             : 
     317           0 : void WProjectFT::findConvFunction(const ImageInterface<Complex>& image,
     318             :                                 const VisBuffer& vb) {
     319             :   
     320             : 
     321             : 
     322             : 
     323             : 
     324           0 :   wpConvFunc_p->findConvFunction(image, vb, wConvSize, uvScale, uvOffset,
     325           0 :                                  padding_p,
     326           0 :                                  convSampling, 
     327           0 :                                  convFunc, convSize, convSupport, 
     328           0 :                                  savedWScale_p); 
     329             : 
     330           0 :   nWPlanes_p=convSupport.nelements();
     331           0 :   wConvSize=max(1,nWPlanes_p);
     332           0 :   uvScale(2)=savedWScale_p;
     333             : 
     334             :   
     335             :   
     336           0 : }
     337             : 
     338           0 : void WProjectFT::initializeToVis(ImageInterface<Complex>& iimage,
     339             :                                const VisBuffer& vb)
     340             : {
     341           0 :   image=&iimage;
     342           0 :   toVis_p=true;
     343           0 :   ok();
     344             :   
     345             :   //   if(convSize==0) {
     346           0 :   init();
     347             :   // }
     348           0 :   findConvFunction(*image, vb);
     349             : 
     350             :   
     351             :   // Initialize the maps for polarization and channel. These maps
     352             :   // translate visibility indices into image indices
     353           0 :   initMaps(vb);
     354             :   
     355             :   //  nx    = image->shape()(0);
     356             :   //  ny    = image->shape()(1);
     357             :   //  npol  = image->shape()(2);
     358             :   //  nchan = image->shape()(3);
     359             : 
     360             : 
     361           0 :   isTiled=false;
     362             :   // If we are memory-based then read the image in and create an
     363             :   // ArrayLattice otherwise just use the PagedImage
     364             :   /*if(isTiled) {
     365             :     lattice=CountedPtr<Lattice<Complex> > (image, false);
     366             :   }
     367             :   else {
     368             :    }
     369             :   */
     370             :   //AlwaysAssert(lattice, AipsError);
     371             :   
     372           0 :   prepGridForDegrid();
     373           0 : }
     374             : 
     375           0 : void WProjectFT::prepGridForDegrid(){
     376           0 :   IPosition gridShape(4, nx, ny, npol, nchan);
     377           0 :   griddedData.resize(gridShape);
     378           0 :   griddedData=Complex(0.0);
     379             :   
     380             : 
     381           0 :   IPosition stride(4, 1);
     382           0 :   IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2,
     383           0 :                 (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
     384           0 :   IPosition trc(blc+image->shape()-stride);
     385             :   
     386           0 :   IPosition start(4, 0);
     387           0 :   griddedData(blc, trc) = image->getSlice(start, image->shape());
     388             :   
     389             :   //if(arrayLattice) delete arrayLattice; arrayLattice=0;
     390           0 :   arrayLattice = new ArrayLattice<Complex>(griddedData);
     391           0 :   lattice=arrayLattice;
     392             : 
     393           0 :   logIO() << LogIO::DEBUGGING << "Starting FFT of image" << LogIO::POST;
     394             :   
     395             :   
     396           0 :   Vector<Float> sincConvX(nx);
     397           0 :   for (Int ix=0;ix<nx;ix++) {
     398           0 :     Float x=C::pi*Float(ix-nx/2)/(Float(nx)*Float(convSampling));
     399           0 :     if(ix==nx/2) {
     400           0 :       sincConvX(ix)=1.0;
     401             :     }
     402             :     else {
     403           0 :       sincConvX(ix)=sin(x)/x;
     404             :     }
     405             :   }
     406           0 :   Vector<Float> sincConvY(ny);
     407           0 :   for (Int ix=0;ix<ny;ix++) {
     408           0 :     Float x=C::pi*Float(ix-ny/2)/(Float(ny)*Float(convSampling));
     409           0 :     if(ix==ny/2) {
     410           0 :       sincConvY(ix)=1.0;
     411             :     }
     412             :     else {
     413           0 :       sincConvY(ix)=sin(x)/x;
     414             :     }
     415             :   }
     416             :     
     417             : 
     418           0 :   Vector<Complex> correction(nx);
     419           0 :   correction=Complex(1.0, 0.0);
     420             :   // Do the Grid-correction
     421           0 :   IPosition cursorShape(4, nx, 1, 1, 1);
     422           0 :   IPosition axisPath(4, 0, 1, 2, 3);
     423           0 :   LatticeStepper lsx(lattice->shape(), cursorShape, axisPath);
     424           0 :   LatticeIterator<Complex> lix(*lattice, lsx);
     425           0 :   for(lix.reset();!lix.atEnd();lix++) {
     426           0 :     Int iy=lix.position()(1);
     427           0 :     gridder->correctX1D(correction,iy);
     428           0 :     for (Int ix=0;ix<nx;ix++) {
     429           0 :       correction(ix)/=(sincConvX(ix)*sincConvY(iy));
     430             :     }
     431           0 :     lix.rwVectorCursor()/=correction;
     432             :   }
     433             :   
     434             :   // Now do the FFT2D in place
     435           0 :   LatticeFFT::cfft2d(*lattice);
     436             :   
     437           0 :   logIO() << LogIO::DEBUGGING << "Finished FFT" << LogIO::POST;
     438             : 
     439             : 
     440             : 
     441           0 : }
     442             : 
     443             : 
     444           0 : void WProjectFT::finalizeToVis()
     445             : {
     446             :   
     447             :   //cerr <<"Time to degrid " << timedegrid_p << endl;
     448           0 :   timedegrid_p=0.0;
     449           0 :   if(!arrayLattice.null()) arrayLattice=0;
     450           0 :   if(!lattice.null()) lattice=0;
     451           0 :   griddedData.resize();
     452           0 :   if(isTiled) {
     453             :     
     454           0 :     logIO() << LogOrigin("WProjectFT", "finalizeToVis")  << LogIO::NORMAL;
     455             :     
     456           0 :     AlwaysAssert(imageCache, AipsError);
     457           0 :     AlwaysAssert(image, AipsError);
     458           0 :     ostringstream o;
     459           0 :     imageCache->flush();
     460           0 :     imageCache->showCacheStatistics(o);
     461           0 :     logIO() << o.str() << LogIO::POST;
     462             :   }
     463           0 : }
     464             : 
     465             : 
     466             : // Initialize the FFT to the Sky. Here we have to setup and initialize the
     467             : // grid. 
     468           0 : void WProjectFT::initializeToSky(ImageInterface<Complex>& iimage,
     469             :                                Matrix<Float>& weight,
     470             :                                const VisBuffer& vb)
     471             : {
     472             :   // image always points to the image
     473           0 :   image=&iimage;
     474           0 :   toVis_p=false;
     475             :   
     476             :   //  if(convSize==0) {
     477           0 :   init();
     478             :   //  }
     479           0 :   findConvFunction(*image, vb);
     480             :   
     481             :   
     482             :   // Initialize the maps for polarization and channel. These maps
     483             :   // translate visibility indices into image indices
     484           0 :   initMaps(vb);
     485             :   
     486             :   //  nx    = image->shape()(0);
     487             :   //  ny    = image->shape()(1);
     488             :   //  npol  = image->shape()(2);
     489             :   //  nchan = image->shape()(3);
     490             : 
     491             :   //  if(image->shape().product()>cachesize) {
     492             :   //  isTiled=true;
     493             :   // }
     494             :   // else {
     495             :   //  isTiled=false;
     496             :   // }
     497           0 :   isTiled=false;
     498           0 :   sumWeight=0.0;
     499           0 :   weight.resize(sumWeight.shape());
     500           0 :   weight=0.0;
     501             :   
     502             :   // Initialize for in memory or to disk gridding. lattice will
     503             :   // point to the appropriate Lattice, either the ArrayLattice for
     504             :   // in memory gridding or to the image for to disk gridding.
     505           0 :   if(isTiled) {
     506           0 :     imageCache->flush();
     507           0 :     image->set(Complex(0.0));
     508           0 :     lattice=CountedPtr<Lattice<Complex> > (image, false);
     509             :   }
     510             :   else {
     511           0 :     IPosition gridShape(4, nx, ny, npol, nchan);
     512           0 :     if( !useDoubleGrid_p )
     513             :       {
     514           0 :         griddedData.resize(gridShape);
     515           0 :         griddedData=Complex(0.0);
     516           0 :         griddedData2.resize();
     517             :       }
     518             :     else
     519           0 :       {griddedData.resize();
     520           0 :         griddedData2.resize(gridShape);
     521           0 :         griddedData2=DComplex(0.0);
     522             :       }
     523             :     //if(arrayLattice) delete arrayLattice; arrayLattice=0;
     524             :    
     525             :   }
     526             :   //AlwaysAssert(lattice, AipsError);
     527             :   
     528           0 : }
     529             : 
     530           0 : void WProjectFT::finalizeToSky()
     531             : {
     532             :   
     533             : 
     534             :   //cerr <<"Time to massage data " << timemass_p << endl;
     535             :   //cerr <<"Time to grid data " << timegrid_p << endl;
     536           0 :   timemass_p=0.0;
     537           0 :   timegrid_p=0.0;
     538             :   // Now we flush the cache and report statistics
     539             :   // For memory based, we don't write anything out yet.
     540           0 :   if(isTiled) {
     541           0 :     logIO() << LogOrigin("WProjectFT", "finalizeToSky")  << LogIO::NORMAL;
     542             :     
     543           0 :     AlwaysAssert(image, AipsError);
     544           0 :     AlwaysAssert(imageCache, AipsError);
     545           0 :     imageCache->flush();
     546           0 :     ostringstream o;
     547           0 :     imageCache->showCacheStatistics(o);
     548           0 :     logIO() << o.str() << LogIO::POST;
     549             :   }
     550           0 : }
     551             : 
     552           0 : Array<Complex>* WProjectFT::getDataPointer(const IPosition& centerLoc2D,
     553             :                                          Bool readonly) {
     554             :   Array<Complex>* result;
     555             :   // Is tiled: get tiles and set up offsets
     556           0 :   centerLoc(0)=centerLoc2D(0);
     557           0 :   centerLoc(1)=centerLoc2D(1);
     558           0 :   result=&imageCache->tile(offsetLoc, centerLoc, readonly);
     559           0 :   gridder->setOffset(IPosition(2, offsetLoc(0), offsetLoc(1)));
     560           0 :   return result;
     561             : }
     562             : 
     563             : #define NEED_UNDERSCORES
     564             : #if defined(NEED_UNDERSCORES)
     565             : #define gwgrid gwgrid_
     566             : #define gwproj gwproj_
     567             : #define dwproj dwproj_
     568             : #define sectgwgridd sectgwgridd_
     569             : #define sectgwgrids sectgwgrids_
     570             : #define sectdwgrid sectdwgrid_
     571             : #define locuvw locuvw_
     572             : #endif
     573             : 
     574             : extern "C" { 
     575             :   void locuvw(const Double*, const Double*, const Double*, const Int*, const Double*, const Double*, const Int*, 
     576             :               Int*, Int*, Complex*, const Int*, const Int*, const Double*);
     577             :   //Double precision gridding
     578             :   void gwgrid(const Double*,
     579             :               Double*,
     580             :               const Complex*,
     581             :               Int*,
     582             :               Int*,
     583             :               Int*,
     584             :               const Int*,
     585             :               const Int*,
     586             :               const Float*,
     587             :               Int*,
     588             :               Int*,
     589             :               Double*,
     590             :               Double*,
     591             :               DComplex*,
     592             :               Int*,
     593             :               Int*,
     594             :               Int *,
     595             :               Int *,
     596             :               const Double*,
     597             :               const Double*,
     598             :               Int*,
     599             :               Int*,
     600             :               Int*,
     601             :               Int*,
     602             :               const Complex*,
     603             :               Int*,
     604             :               Int*,
     605             :               Double*);
     606             : 
     607             :   void sectgwgridd(const Double*,
     608             :                    const Complex*,
     609             :               const Int*,
     610             :               const Int*,
     611             :               const Int*,
     612             :               const Int*,
     613             :               const Int*,
     614             :               const Float*,
     615             :               const Int*,
     616             :               DComplex*,
     617             :               const Int*,
     618             :               const Int*,
     619             :               const Int *,
     620             :               const Int *,
     621             :                    //support
     622             :               const Int*,
     623             :               const Int*,
     624             :               const Int*,
     625             :               const Int*,
     626             :               const Complex*,
     627             :               const Int*,
     628             :               const Int*,
     629             :                    Double*,
     630             :                    //x0
     631             :                    const Int*,
     632             :                    const Int*,
     633             :                    const Int*, 
     634             :                    const Int*, 
     635             :                    const Int*, 
     636             :                    const Int*,
     637             :                    const Int*,
     638             :                    const Int*,
     639             :                    const Complex*
     640             :                    );
     641             : 
     642             :   //Single precision gridding
     643             :     void sectgwgrids(const Double*,
     644             :                    const Complex*,
     645             :               const Int*,
     646             :               const Int*,
     647             :               const Int*,
     648             :               const Int*,
     649             :               const Int*,
     650             :               const Float*,
     651             :               const Int*,
     652             :               Complex*,
     653             :               const Int*,
     654             :               const Int*,
     655             :               const Int *,
     656             :               const Int *,
     657             :                    //support
     658             :               const Int*,
     659             :               const Int*,
     660             :               const Int*,
     661             :               const Int*,
     662             :               const Complex*,
     663             :               const Int*,
     664             :               const Int*,
     665             :                    Double*,
     666             :                    //x0
     667             :                    const Int*,
     668             :                    const Int*,
     669             :                    const Int*, 
     670             :                    const Int*, 
     671             :                    const Int*, 
     672             :                    const Int*,
     673             :                    const Int*,
     674             :                    const Int*,
     675             :                    const Complex*
     676             :                    );
     677             : 
     678             : 
     679             :   void gwproj(const Double*,
     680             :               Double*,
     681             :               const Complex*,
     682             :               Int*,
     683             :               Int*,
     684             :               Int*,
     685             :               const Int*,
     686             :               const Int*,
     687             :               const Float*,
     688             :               Int*,
     689             :               Int*,
     690             :               Double*,
     691             :               Double*,
     692             :               Complex*,
     693             :               Int*,
     694             :               Int*,
     695             :               Int *,
     696             :               Int *,
     697             :               const Double*,
     698             :               const Double*,
     699             :               Int*,
     700             :               Int*,
     701             :               Int*,
     702             :               Int*,
     703             :               const Complex*,
     704             :               Int*,
     705             :               Int*,
     706             :               Double*);
     707             : 
     708             :   void sectdwgrid(const Double*,
     709             :                   Complex*,
     710             :                   const Int*,
     711             :                   const Int*,
     712             :                   const Int*,
     713             :                   const Int*,
     714             :                   const Int*,
     715             :                   const Complex*,
     716             :                   const Int*,
     717             :                   const Int*,
     718             :                   const Int *,
     719             :                   const Int *,
     720             :                   //support
     721             :                   const Int*,
     722             :                   const Int*,
     723             :                   const Int*,
     724             :                   const Int*,
     725             :                   const Complex*,
     726             :                   const Int*,
     727             :                   const Int*,
     728             :                   //rbeg, rend, loc, off, phasor
     729             :                   const Int*,
     730             :                   const Int*,
     731             :                   const Int*,
     732             :                   const Int*,
     733             :                   const Complex*);
     734             :   void dwproj(const Double*,
     735             :               Double*,
     736             :               Complex*,
     737             :               Int*,
     738             :               Int*,
     739             :               const Int*,
     740             :               const Int*,
     741             :               Int*,
     742             :               Int*,
     743             :               Double*,
     744             :               Double*,
     745             :               const Complex*,
     746             :               Int*,
     747             :               Int*,
     748             :               Int *,
     749             :               Int *,
     750             :               const Double*,
     751             :               const Double*,
     752             :               Int*,
     753             :               Int*,
     754             :               Int*,
     755             :               Int*,
     756             :               const Complex*,
     757             :               Int*,
     758             :               Int*);
     759             : }
     760           0 : void WProjectFT::put(const VisBuffer& vb, Int row, Bool dopsf,
     761             :                      FTMachine::Type type)
     762             : {
     763             :   
     764             : 
     765             :    //Check if ms has changed then cache new spw and chan selection
     766           0 :   if(vb.newMS())
     767           0 :     matchAllSpwChans(vb);
     768             :   
     769             :   //Here we redo the match or use previous match
     770             :   
     771             :   //Channel matching for the actual spectral window of buffer
     772           0 :   if(doConversion_p[vb.spectralWindow()]){
     773           0 :     matchChannel(vb.spectralWindow(), vb);
     774             :   }
     775             :   else{
     776           0 :     chanMap.resize();
     777           0 :     chanMap=multiChanMap_p[vb.spectralWindow()];
     778             :   }
     779             :   
     780             :   //No point in reading data if its not matching in frequency
     781           0 :   if(max(chanMap)==-1)
     782           0 :     return;
     783           0 :    Timer tim;
     784           0 :    tim.mark();
     785             : 
     786             :   const Matrix<Float> *imagingweight;
     787           0 :   imagingweight=&(vb.imagingWeight());
     788             : 
     789           0 :   if(dopsf) type=FTMachine::PSF;
     790             : 
     791           0 :   Cube<Complex> data;
     792             :   //Fortran gridder need the flag as ints 
     793           0 :   Cube<Int> flags;
     794           0 :   Matrix<Float> elWeight;
     795           0 :   interpolateFrequencyTogrid(vb, *imagingweight,data, flags, elWeight, type);
     796             :   
     797             :   
     798             :   Bool iswgtCopy;
     799             :   const Float *wgtStorage;
     800           0 :   wgtStorage=elWeight.getStorage(iswgtCopy);
     801             : 
     802             : 
     803             :   Bool isCopy;
     804           0 :   const Complex *datStorage=0;
     805             : 
     806           0 :   if(!dopsf)
     807           0 :     datStorage=data.getStorage(isCopy);
     808             : 
     809             : 
     810             :   // If row is -1 then we pass through all rows
     811             :   Int startRow, endRow, nRow;
     812           0 :   if (row==-1) {
     813           0 :     nRow=vb.nRow();
     814           0 :     startRow=0;
     815           0 :     endRow=nRow-1;
     816             :   } else {
     817           0 :     nRow=1;
     818           0 :     startRow=row;
     819           0 :     endRow=row;
     820             :   }
     821             :   
     822             :   // Get the uvws in a form that Fortran can use and do that
     823             :   // necessary phase rotation. On a Pentium Pro 200 MHz
     824             :   // when null, this step takes about 50us per uvw point. This
     825             :   // is just barely noticeable for Stokes I continuum and
     826             :   // irrelevant for other cases.
     827           0 :   Matrix<Double> uvw(3, vb.uvw().nelements());
     828           0 :   uvw=0.0;
     829           0 :   Vector<Double> dphase(vb.uvw().nelements());
     830           0 :   dphase=0.0;
     831             :   //NEGATING to correct for an image inversion problem
     832           0 :   for (Int i=startRow;i<=endRow;i++) {
     833           0 :     for (Int idim=0;idim<2;idim++) uvw(idim,i)=-vb.uvw()(i)(idim);
     834           0 :     uvw(2,i)=vb.uvw()(i)(2);
     835             :   }
     836             :   
     837           0 :   rotateUVW(uvw, dphase, vb);
     838           0 :   refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
     839             : 
     840             : 
     841             :   
     842             :   // Take care of translation of Bools to Integer
     843           0 :   Int idopsf=0;
     844           0 :   if(dopsf) idopsf=1;
     845             :   
     846           0 :   Vector<Int> rowFlags(vb.nRow());
     847           0 :   rowFlags=0;
     848           0 :   rowFlags(vb.flagRow())=true;
     849           0 :   if(!usezero_p) {
     850           0 :     for (Int rownr=startRow; rownr<=endRow; rownr++) {
     851           0 :       if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) rowFlags(rownr)=1;
     852             :     }
     853             :   }
     854             :   
     855             :   
     856             :   Bool del;
     857             :   //    IPosition s(flags.shape());
     858           0 :   Vector<Int> s(flags.shape().nelements());
     859           0 :   convertArray(s, flags.shape().asVector());
     860           0 :   Int nvp=s[0];
     861           0 :   Int nvc=s[1];
     862           0 :   Int nvisrow=s[2];
     863             : 
     864           0 :   Int csamp=convSampling;
     865             :   
     866             :   Bool uvwcopy; 
     867           0 :   const Double *uvwstor=uvw.getStorage(uvwcopy);
     868             :   Bool gridcopy;
     869             :   Bool convcopy;
     870           0 :   const Complex *convstor=convFunc.getStorage(convcopy);
     871           0 :   Cube<Int> loc(3, nvc, nRow);
     872           0 :   Cube<Int> off(3, nvc, nRow);
     873           0 :   Matrix<Complex> phasor(nvc, nRow);
     874             :   Bool delphase;
     875           0 :   Complex * phasorstor=phasor.getStorage(delphase);
     876           0 :   const Double * visfreqstor=interpVisFreq_p.getStorage(del);
     877           0 :   const Double * scalestor=uvScale.getStorage(del);
     878           0 :   const Double * offsetstor=uvOffset.getStorage(del);
     879             :   Bool delloc, deloff;
     880           0 :   Int * locstor=loc.getStorage(delloc);
     881           0 :   Int * offstor=off.getStorage(deloff);
     882           0 :   const Double *dpstor=dphase.getStorage(del);
     883           0 :   Double cinv=Double(1.0)/C::c;
     884             :   Int irow;
     885           0 :   Int dow=1;
     886           0 :   Int nth=1;
     887             : #ifdef _OPENMP
     888           0 :   if(numthreads_p >0){
     889           0 :     nth=min(numthreads_p, omp_get_max_threads());
     890             :   }
     891             :   else{   
     892           0 :     nth= omp_get_max_threads();
     893             :   }
     894             :   //nth=min(4,nth);
     895             : #endif
     896             : 
     897             : 
     898             : 
     899             : 
     900           0 :    #pragma omp parallel default(none) private(irow) firstprivate(visfreqstor, nvc, scalestor, offsetstor, csamp, phasorstor, uvwstor, locstor, offstor, dpstor, cinv, dow) shared(startRow, endRow) num_threads(nth)  
     901             : {
     902             : #pragma omp for schedule(dynamic)
     903             :   for (irow=startRow; irow<=endRow;irow++){
     904             :     //locateuvw(uvwstor,dpstor, visfreqstor, nvc, scalestor, offsetstor, csamp, 
     905             :     //        locstor, 
     906             :     //        offstor, phasorstor, irow, true);
     907             :     locuvw(uvwstor, dpstor, visfreqstor, &nvc, scalestor, offsetstor, &csamp, locstor, offstor, phasorstor, &irow, &dow, &cinv);
     908             :   }  
     909             : 
     910             :   
     911             : 
     912             : 
     913             :  }//end pragma parallel
     914             :   //Int maxx=0; 
     915           0 :   Int minx=1000000;
     916             :   //Int maxy=0;
     917           0 :   Int miny=1000000;
     918             :   //Int maxsupp=max(convSupport);
     919             :   /*loc.putStorage(locstor, delloc);
     920             :   maxx=max(loc.yzPlane(0))+convSize;
     921             :   maxx=min(nx-1,  maxx-1);
     922             :   minx=min(loc.yzPlane(0))-convSize;
     923             :   minx=max(0, minx-1);
     924             :   maxy=max(loc.yzPlane(1))+convSize;
     925             :   maxy=min(ny-1, maxy-1);
     926             :   miny=min(loc.yzPlane(1))-convSize;
     927             :   miny=max(0,miny-1);
     928             :   locstor=loc.getStorage(delloc);
     929             :   */
     930             :   //cerr << "dels " << delloc << "  " << deloff << endl;
     931             :   //cerr << "LOC " << min(loc.xzPlane(0)) << "  max " << loc.shape() << endl;
     932           0 :   timemass_p +=tim.real();
     933             :   Int ixsub, iysub, icounter;
     934           0 :   ixsub=1;
     935           0 :   iysub=1;
     936           0 :   if(nth > 4){
     937           0 :     ixsub=8;
     938           0 :     iysub=8;
     939             :   }
     940             :   else{
     941           0 :     ixsub=2;
     942           0 :     iysub=2; 
     943             :   }
     944             :   /* else if(nth >1){
     945             :      ixsub=2;
     946             :      iysub=1; 
     947             :   }
     948             :   */
     949             : 
     950             :   //nxsub=nx;
     951             :   //nysub=ny;
     952             :   //nxsub=maxx-minx+1;
     953             :   //nysub=maxy-miny+1;
     954           0 :   Int rbeg=startRow+1;
     955           0 :   Int rend=endRow+1;
     956           0 :   const Int* pmapstor=polMap.getStorage(del);
     957           0 :   const Int *cmapstor=chanMap.getStorage(del);
     958           0 :   Int nc=nchan;
     959           0 :   Int np=npol;
     960             :   ////For now no limitation
     961           0 :   minx=0;
     962           0 :   miny=0; 
     963           0 :   Int nxp=nx;
     964           0 :   Int nyp=ny;
     965             :  
     966             :   
     967           0 :   Int nxcopy=nx;
     968           0 :   Int nycopy=ny;
     969             :   
     970           0 :   Int csize=convSize;
     971           0 :    Int wcsize=wConvSize;
     972           0 :   const Int * flagstor=flags.getStorage(del);
     973           0 :   const Int * rowflagstor=rowFlags.getStorage(del);
     974           0 :   const Int * suppstor=convSupport.getStorage(del);
     975             :   //for (Int biba=4; biba < 60; biba+=2){
     976             :   // cerr << "biba 0 " << biba << endl;
     977             :   //  ixsub=biba;
     978             :   //  iysub=biba;
     979             :  
     980           0 :   tim.mark(); 
     981             :   //clock_t  tick;
     982             :   //tick = clock();
     983             :   //time_t now;
     984             :   //time(&now);
     985             :   
     986           0 :   Vector<Int> x0p, y0p, nxpsub, nypsub;
     987             : 
     988           0 :   Block<Matrix<Double> > sumwgt(ixsub*iysub);
     989             :   //  if(timegrid_p==0.0 && dopsf){
     990             :   {
     991           0 :     xsect_p.resize(ixsub*iysub);
     992           0 :     ysect_p.resize(ixsub*iysub);
     993           0 :     nxsect_p.resize(ixsub*iysub);
     994           0 :     nysect_p.resize(ixsub*iysub);
     995           0 :     for (icounter=0; icounter < ixsub*iysub; ++icounter){
     996             :       ///testoo
     997             :       //minx=0;
     998             :       //miny=0;
     999             :       //nxp=nx;
    1000             :       //nyp=ny;
    1001             :       ////////
    1002           0 :       findGridSector(nxp, nyp, ixsub, iysub, minx, miny, icounter, xsect_p(icounter), ysect_p(icounter), nxsect_p(icounter), nysect_p(icounter), true);
    1003             :     }
    1004             :   }
    1005             :   /*if((Int(timegrid_p)%10000)==0){
    1006             :     cerr << timegrid_p << endl;
    1007             :     cerr << "xsect " << xsect_p << "\n ysect " << ysect_p << "\n nxsect "<< nxsect_p << "\n nysect " << nysect_p << endl;  
    1008             : 
    1009             :   }
    1010             :   */
    1011           0 :   for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1012           0 :     sumwgt[icounter].resize(sumWeight.shape());
    1013           0 :     sumwgt[icounter].set(0.0);
    1014             :   }
    1015           0 :   Vector<Int> xsect, ysect, nxsect, nysect;
    1016           0 :   xsect=xsect_p; ysect=ysect_p; nxsect=nxsect_p; nysect=nysect_p;
    1017             :   //cerr << "useDoubleGrid " << useDoubleGrid_p << endl;
    1018           0 :   if(!useDoubleGrid_p){
    1019           0 :     Complex *gridstor=griddedData.getStorage(gridcopy);
    1020           0 : #pragma omp parallel default(none) private(icounter, del) firstprivate(idopsf, uvwstor, datStorage, wgtStorage, flagstor, rowflagstor, convstor, pmapstor, cmapstor, gridstor, suppstor, nxp, nyp, nxcopy, nycopy, np, nc,ixsub, iysub, rend, rbeg, csamp, csize, wcsize, nvp, nvc, nvisrow, phasorstor, locstor, offstor, minx, miny, xsect, ysect, nxsect, nysect) shared(sumwgt) num_threads(nth)
    1021             :     {
    1022             : #pragma omp for schedule(dynamic)      
    1023             :     for(icounter=0; icounter < ixsub*iysub; ++icounter){
    1024             :       //Int realicounter=icounter%2==0 ? ixsub*iysub/2+icounter/2 :  ixsub*iysub/2-icounter/2-1;
    1025             :       //findGridSector(nxp, nyp, ixsub, iysub, minx, miny, icounter, x0, y0, nxsub, nysub, true);
    1026             :       Int x0=xsect(icounter);
    1027             :       Int y0=ysect(icounter);
    1028             :       Int nxsub=nxsect(icounter);
    1029             :       Int nysub=nysect(icounter);
    1030             : 
    1031             :       sectgwgrids(uvwstor,
    1032             :            datStorage,
    1033             :            &nvp,
    1034             :            &nvc,
    1035             :            &idopsf,
    1036             :            flagstor,
    1037             :            rowflagstor,
    1038             :            wgtStorage,
    1039             :            &nvisrow,
    1040             :            gridstor,
    1041             :            &nxcopy,
    1042             :            &nycopy,
    1043             :            &np,
    1044             :            &nc,
    1045             :            suppstor,
    1046             :            &csize,
    1047             :            &csamp,
    1048             :            &wcsize,
    1049             :            convstor,
    1050             :            cmapstor,
    1051             :            pmapstor,
    1052             :                   (sumwgt[icounter]).getStorage(del), 
    1053             :                   &x0, &y0, &nxsub, &nysub, &rbeg, &rend, locstor, offstor,
    1054             :                  phasorstor);
    1055             :     }
    1056             :     }//end pragma parallel
    1057             : 
    1058           0 :     timegrid_p+=tim.real();
    1059             :     //if(dopsf)
    1060             :     //  tweakGridSector(nx, ny, ixsub, iysub, xsect_p, ysect_p, nxsect_p, nysect_p);
    1061           0 :     for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1062             :       //cerr << "ixsub, iysub " << icounter%ixsub << "  " << icounter/ixsub << " sumwgt " << sumwgt[icounter](0,0) << endl;
    1063           0 :       sumWeight=sumWeight+sumwgt[icounter];
    1064             :     }    
    1065           0 :     griddedData.putStorage(gridstor, gridcopy);
    1066             :     
    1067             :   }
    1068             :   else{
    1069           0 :     DComplex *gridstor=griddedData2.getStorage(gridcopy);
    1070           0 : #pragma omp parallel default(none) private(icounter, del) firstprivate(idopsf, uvwstor, datStorage, wgtStorage, flagstor, rowflagstor, convstor, pmapstor, cmapstor, gridstor, suppstor, nxp, nyp, nxcopy, nycopy, np, nc,ixsub, iysub, rend, rbeg, csamp, csize, wcsize, nvp, nvc, nvisrow, phasorstor, locstor, offstor,minx,miny, xsect, ysect, nxsect, nysect) shared(sumwgt) num_threads(nth)
    1071             :     {
    1072             : #pragma omp for schedule(dynamic)    
    1073             :     for(icounter=0; icounter < ixsub*iysub; ++icounter){
    1074             :       //Int realicounter=icounter%2==0 ? ixsub*iysub/2+icounter/2 :  ixsub*iysub/2-icounter/2-1;
    1075             :       // findGridSector(nxp, nyp, ixsub, iysub, minx, miny, icounter, x0, y0, nxsub, nysub, true);
    1076             :       //Double wt0=omp_get_wtime();
    1077             :       Int x0=xsect(icounter);
    1078             :       Int y0=ysect(icounter);
    1079             :       Int nxsub=nxsect(icounter);
    1080             :       Int nysub=nysect(icounter);
    1081             :       
    1082             :        sectgwgridd(uvwstor,
    1083             :            datStorage,
    1084             :            &nvp,
    1085             :            &nvc,
    1086             :            &idopsf,
    1087             :            flagstor,
    1088             :            rowflagstor,
    1089             :            wgtStorage,
    1090             :            &nvisrow,
    1091             :            gridstor,
    1092             :            &nxcopy,
    1093             :            &nycopy,
    1094             :            &np,
    1095             :            &nc,
    1096             :            suppstor,
    1097             :            &csize,
    1098             :            &csamp,
    1099             :            &wcsize,
    1100             :            convstor,
    1101             :            cmapstor,
    1102             :            pmapstor,
    1103             :                   (sumwgt[icounter]).getStorage(del), 
    1104             :                   &x0, &y0, &nxsub, &nysub, &rbeg, &rend, locstor, offstor,
    1105             :                  phasorstor);
    1106             :        //cerr << "icounter " << icounter << "  " << icounter%ixsub << "  " << icounter/ixsub << "    " << omp_get_wtime()-wt0 << endl;
    1107             :     }
    1108             :     }//end pragma parallel
    1109           0 :     timegrid_p+=1.0;
    1110             :      //timegrid_p+=tim.real();
    1111             :      //if(dopsf)
    1112             :      //  tweakGridSector(nx, ny, ixsub, iysub, xsect_p, ysect_p, nxsect_p, nysect_p);
    1113           0 :     for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1114             :       //cerr << "ixsub, iysub " << icounter%ixsub << "  " << icounter/ixsub << " sumwgt " << sumwgt[icounter](0,0) << endl;
    1115           0 :       sumWeight=sumWeight+sumwgt[icounter];
    1116             :     }
    1117           0 :     griddedData2.putStorage(gridstor, gridcopy);
    1118             :   }
    1119             :  
    1120             :   
    1121             :   
    1122             :   //   std::cerr << std::setprecision(10) << "biba " << biba << " time " << tim.real() << " timall " << tim.all_usec() << endl;
    1123             :   //  }
    1124           0 :   uvw.freeStorage(uvwstor, uvwcopy);
    1125           0 :   convFunc.freeStorage(convstor, convcopy);
    1126             :   
    1127           0 :   if(!dopsf)
    1128           0 :     data.freeStorage(datStorage, isCopy);
    1129           0 :   elWeight.freeStorage(wgtStorage,iswgtCopy);
    1130             :   //timegrid_p+=tim.real();
    1131             :   //timegrid_p+= Double(clock()-tick);
    1132             :   // time_t now1;
    1133             :   //time(&now1);
    1134             :   //timegrid_p+=difftime(now1, now);
    1135             :   }
    1136             : 
    1137           0 : void WProjectFT::findGridSector(const Int& nxp, const Int& nyp, const Int& ixsub, const Int& iysub, const Int& minx, const Int& miny, const Int& icounter, Int& x0, Int& y0, Int&  nxsub, Int& nysub, const Bool linear){
    1138             :   /* Vector<Int> ord(36);
    1139             :        ord(0)=14; 
    1140             :       ord(1)=15;
    1141             :       ord(2)=20;
    1142             :       ord(3)=21;ord(4)=13;
    1143             :       ord(5)=16;ord(6)=19;ord(7)=22;ord(8)=8;ord(9)=9;
    1144             :       ord(10)=26;ord(11)=27;ord(12)=25;ord(13)=28;ord(14)=7;
    1145             :       ord(15)=10;ord(16)=32;ord(17)=33;ord(18)=2;ord(19)=3;
    1146             :       ord(20)=18;ord(21)=23;ord(22)=12;ord(23)=17;ord(24)=1;
    1147             :       ord(25)=4;ord(26)=6;ord(27)=11;ord(28)=24;ord(29)=29;
    1148             :       ord(30)=31;ord(31)=34;ord(32)=0;ord(33)=5;ord(34)=30;
    1149             :       ord(35)=35;
    1150             :       */
    1151             :   /*
    1152             :       Int ix= (icounter+1)-((icounter)/ixsub)*ixsub;
    1153             :       Int iy=(icounter)/ixsub+1;
    1154             :       y0=(nyp/iysub)*(iy-1)+1+miny;
    1155             :       nysub=nyp/iysub;
    1156             :       if( iy == iysub) {
    1157             :         nysub=nyp-(nyp/iysub)*(iy-1);
    1158             :       }
    1159             :       x0=(nxp/ixsub)*(ix-1)+1+minx;
    1160             :       nxsub=nxp/ixsub;
    1161             :       if( ix == ixsub){
    1162             :         nxsub=nxp-(nxp/ixsub)*(ix-1);
    1163             :       }
    1164             :   */
    1165             :          
    1166             :          
    1167             :       {
    1168           0 :         Int elrow=icounter/ixsub;
    1169           0 :         Int elcol=(icounter-elrow*ixsub);
    1170             :         //cerr << "row "<< elrow << " col " << elcol; 
    1171             :         //nxsub=Int(floor(((ceil(fabs(float(2*elcol+1-ixsub)/2.0))-1.0)*5 +1)*nxp/36.0 + 0.5));
    1172           0 :         Float factor=0;
    1173           0 :         for (Int k=0; k < ixsub/2; ++k)
    1174           0 :           factor= linear ? factor+(k+1): factor+sqrt(Float(k+1));
    1175             :           //factor= linear ? factor+(k+1): factor+(k+1)*(k+1)*(k+1);
    1176           0 :         factor *= 2.0;
    1177           0 :         if(linear)
    1178           0 :           nxsub=Int(floor((ceil(fabs(float(2*elcol+1-ixsub)/2.0))/factor)*nxp + 0.5));
    1179             :         else
    1180             :           //nxsub=Int(floor((ceil(fabs(float(2*elcol+1-ixsub)/2.0))*ceil(fabs(float(2*elcol+1-ixsub)/2.0))*ceil(fabs(float(2*elcol+1-ixsub)/2.0))/factor)*nxp + 0.5));
    1181           0 :           nxsub=Int(floor((sqrt(ceil(fabs(float(2*elcol+1-ixsub)/2.0)))/factor)*nxp + 0.5));
    1182             :         //cerr << nxp << " col " << elcol << " nxsub " << nxsub << endl;
    1183           0 :         x0=minx;
    1184           0 :         elcol-=1;
    1185           0 :         while(elcol >= 0){
    1186             :           //x0+=Int(floor(((ceil(fabs(float(2*elcol+1-ixsub)/2.0))-1.0)*5 +1)*nxp/36.0+0.5));
    1187             : 
    1188           0 :           if(linear)
    1189           0 :             x0+=Int(floor((ceil(fabs(float(2*elcol+1-ixsub)/2.0))/factor)*nxp + 0.5));
    1190             :           else
    1191             :             //x0+=Int(floor((ceil(fabs(float(2*elcol+1-ixsub)/2.0))*ceil(fabs(float(2*elcol+1-ixsub)/2.0))*ceil(fabs(float(2*elcol+1-ixsub)/2.0))/factor)*nxp + 0.5));
    1192           0 :             x0+=Int(floor((sqrt(ceil(fabs(float(2*elcol+1-ixsub)/2.0)))/factor)*nxp + 0.5));
    1193           0 :           elcol-=1;
    1194             :         }
    1195           0 :         factor=0;
    1196           0 :         for (Int k=0; k < iysub/2; ++k)
    1197             :           //factor=linear ? factor+(k+1): factor+(k+1)*(k+1)*(k+1);
    1198           0 :           factor= linear ? factor+(k+1): factor+sqrt(Float(k+1));
    1199           0 :         factor *= 2.0;
    1200             :         //nysub=Int(floor(((ceil(fabs(float(2*elrow+1-iysub)/2.0))-1.0)*5 +1)*nyp/36.0+0.5));
    1201           0 :         if(linear)
    1202           0 :           nysub=Int(floor((ceil(fabs(float(2*elrow+1-iysub)/2.0))/factor)*nyp + 0.5));
    1203             :         else
    1204           0 :           nysub=Int(floor((sqrt(ceil(fabs(float(2*elrow+1-iysub)/2.0)))/factor)*nyp + 0.5));
    1205             :           //nysub=Int(floor((ceil(fabs(float(2*elrow+1-iysub)/2.0))*ceil(fabs(float(2*elrow+1-iysub)/2.0))*ceil(fabs(float(2*elrow+1-iysub)/2.0))/factor)*nyp + 0.5));
    1206           0 :         y0=miny;
    1207           0 :         elrow-=1;
    1208             :         
    1209           0 :         while(elrow >=0){
    1210             :           //y0+=Int(floor(((ceil(fabs(float(2*elrow+1-iysub)/2.0))-1.0)*5 +1)*nyp/36.0+0.5));
    1211           0 :           if(linear)
    1212           0 :             y0+=Int(floor((ceil(fabs(float(2*elrow+1-iysub)/2.0))/factor)*nyp + 0.5));
    1213             :           else
    1214           0 :             y0+=Int(floor((sqrt(ceil(fabs(float(2*elrow+1-iysub)/2.0)))/factor)*nyp + 0.5));
    1215             :             //y0+=Int(floor((ceil(fabs(float(2*elrow+1-iysub)/2.0))*ceil(fabs(float(2*elrow+1-iysub)/2.0))*ceil(fabs(float(2*elrow+1-iysub)/2.0))/factor)*nyp + 0.5));
    1216           0 :           elrow-=1;
    1217             :         }
    1218             :       }
    1219             : 
    1220             : 
    1221           0 :       y0+=1;
    1222           0 :       x0+=1;
    1223             :       
    1224             :    
    1225           0 : }
    1226             : 
    1227           0 : void WProjectFT::tweakGridSector(const Int& nx, const Int& ny, const Int& ixsub, const Int& iysub, Vector<Int>& xsect, Vector<Int>& ysect, Vector<Int>&  nxsect, Vector<Int>& nysect){
    1228           0 :   Vector<Int> x0, y0, nxsub, nysub;
    1229           0 :   Vector<Float> xcut(nx/2);
    1230           0 :   Vector<Float> ycut(ny/2);
    1231           0 :   if(griddedData2.nelements() >0 ){
    1232             :     //cerr << "shapes " << xcut.shape() << "   gd " << amplitude(griddedData2(IPosition(4, 0, ny/2-1, 0, 0), IPosition(4, nx/2-1, ny/2-1, 0,0))).shape() << endl;
    1233           0 :     convertArray(xcut, amplitude(griddedData2(IPosition(4, 0, ny/2-1, 0, 0), IPosition(4, nx/2-1, ny/2-1, 0,0))).reform(xcut.shape()));
    1234           0 :     convertArray(ycut, amplitude(griddedData2(IPosition(4, nx/2-1, 0, 0, 0), IPosition(4, nx/2-1, ny/2-1, 0,0))).reform(ycut.shape()));
    1235             :   }
    1236             :   else{
    1237           0 :     xcut=amplitude(griddedData(IPosition(4, 0, ny/2-1, 0, 0), IPosition(4, nx/2-1, ny/2-1, 0,0)));
    1238           0 :     ycut=amplitude(griddedData(IPosition(4, nx/2-1, 0, 0, 0), IPosition(4, nx/2-1, ny/2-1, 0,0)));
    1239             :   }
    1240             :   //cerr << griddedData2.shape() << "   " << griddedData.shape() << endl;
    1241           0 :   Vector<Float> cumSumX(nx/2, 0);
    1242             :   //Vector<Float> cumSumX2(nx/2,0);
    1243           0 :   cumSumX(0)=xcut(0);
    1244             :   //cumSumX2(0)=cumSumX(0)*cumSumX(0);
    1245           0 :   Float sumX=sum(xcut);
    1246           0 :   if(sumX==0.0)
    1247           0 :     return;
    1248             :   //cerr << "sumX " << sumX << endl;
    1249             :   //sumX *= sumX;
    1250           0 :   x0.resize(ixsub);
    1251           0 :   x0=nx/2-1;
    1252           0 :   nxsub.resize(ixsub);
    1253           0 :   nxsub=0;
    1254           0 :   x0(0)=0;
    1255           0 :   Int counter=1;
    1256           0 :   for (Int k=1; k < nx/2; ++k){
    1257           0 :     cumSumX(k)=cumSumX(k-1)+xcut(k);
    1258             :     //cumSumX2(k)=cumSumX(k)*cumSumX(k);
    1259           0 :     Float nextEdge=sumX/(Float(ixsub/2)*Float(ixsub/2))*Float(counter)*Float(counter);
    1260           0 :     if(cumSumX(k-1) < nextEdge && cumSumX(k) >= nextEdge){
    1261           0 :       x0(counter)=k;
    1262             :       //cerr << counter << "    "   << k << " diff " << x0(counter)-x0(counter-1) << endl;
    1263           0 :       nxsub(counter-1)=x0(counter)-x0(counter-1);
    1264           0 :       ++counter;
    1265             :     }
    1266             :   } 
    1267             :   
    1268           0 :   x0(ixsub/2)=nx/2-1;
    1269           0 :   nxsub(ixsub/2)=nxsub(ixsub/2-1)=nx/2-1-x0(ixsub/2-1);
    1270           0 :   for(Int k=ixsub/2+1; k < ixsub; ++k){
    1271           0 :     x0(k)=x0(k-1)+ nxsub(ixsub-k);
    1272           0 :     nxsub(k)=nxsub(ixsub-k-1);
    1273             :   }
    1274           0 :   nxsub(ixsub-1)+=1;
    1275             :   
    1276           0 :   Vector<Float> cumSumY(ny/2, 0);
    1277             :   //Vector<Float> cumSumY2(ny/2,0);
    1278           0 :   cumSumY(0)=ycut(0);
    1279             :   //cumSumY2(0)=cumSumY(0)*cumSumY(0);
    1280           0 :   Float sumY=sum(ycut);
    1281           0 :   if(sumY==0.0)
    1282           0 :     return;
    1283             :   //sumY *=sumY;
    1284           0 :   y0.resize(iysub);
    1285           0 :   y0=ny/2-1;
    1286           0 :   nysub.resize(iysub);
    1287           0 :   nysub=0;
    1288           0 :   y0(0)=0;
    1289           0 :   counter=1;
    1290           0 :   for (Int k=1; k < ny/2; ++k){
    1291           0 :     cumSumY(k)=cumSumY(k-1)+ycut(k);
    1292             :     //cumSumY2(k)=cumSumY(k)*cumSumY(k);
    1293           0 :     Float nextEdge=sumY/(Float(iysub/2)*Float(iysub/2))*Float(counter)*Float(counter);
    1294           0 :     if(cumSumY(k-1) < nextEdge && cumSumY(k) >= nextEdge){
    1295           0 :       y0(counter)=k;
    1296           0 :       nysub(counter-1)=y0(counter)-y0(counter-1);
    1297           0 :       ++counter;
    1298             :     }
    1299             :   } 
    1300             :  
    1301           0 :   y0(ixsub/2)=ny/2-1;
    1302           0 :   nysub(iysub/2)=nysub(iysub/2-1)=ny/2-1-y0(iysub/2-1);
    1303           0 :   for(Int k=iysub/2+1; k < iysub; ++k){
    1304           0 :     y0(k)=y0(k-1)+ nysub(iysub-k);
    1305           0 :     nysub(k)=nysub(iysub-k-1);
    1306             :   }
    1307           0 :   nysub(iysub-1)+=1;
    1308             : 
    1309             : 
    1310             :   //cerr << " x0 " << x0 << "  nxsub " << nxsub << endl;
    1311             :   //cerr << " y0 " << y0 << "  nysub " << nysub << endl;
    1312           0 :   x0+=1;
    1313           0 :   y0+=1;
    1314           0 :   xsect.resize(ixsub*iysub);
    1315           0 :   ysect.resize(ixsub*iysub);
    1316           0 :   nxsect.resize(ixsub*iysub);
    1317           0 :   nysect.resize(ixsub*iysub);
    1318           0 :   for (Int iy=0; iy < iysub; ++iy){
    1319           0 :     for (Int ix=0; ix< ixsub; ++ix){
    1320             :       
    1321           0 :       xsect(iy*ixsub+ix)=x0[ix];
    1322           0 :       ysect(iy*ixsub+ix)=y0[iy];
    1323           0 :       nxsect(iy*ixsub+ix)=nxsub[ix];
    1324           0 :       nysect(iy*ixsub+ix)=nysub[iy];
    1325             :     }
    1326             :   }
    1327             : 
    1328             : 
    1329             : 
    1330             : }
    1331             : 
    1332             : 
    1333           0 : void WProjectFT::get(VisBuffer& vb, Int row)
    1334             : {
    1335             :   
    1336             :   ///This is needed here as virtual model column may not call initializeToVis
    1337           0 :   findConvFunction(*image, vb);
    1338             :   // If row is -1 then we pass through all rows
    1339             :   Int startRow, endRow, nRow;
    1340           0 :   if (row==-1) {
    1341           0 :     nRow=vb.nRow();
    1342           0 :     startRow=0;
    1343           0 :     endRow=nRow-1;
    1344             :     //vb.modelVisCube()=Complex(0.0,0.0);
    1345             :   } else {
    1346           0 :     nRow=1;
    1347           0 :     startRow=row;
    1348           0 :     endRow=row;
    1349             :     //vb.modelVisCube().xyPlane(row)=Complex(0.0,0.0);
    1350             :   }
    1351             :   
    1352             :   // Get the uvws in a form that Fortran can use
    1353           0 :   Matrix<Double> uvw(3, vb.uvw().nelements());
    1354           0 :   uvw=0.0;
    1355           0 :   Vector<Double> dphase(vb.uvw().nelements());
    1356           0 :   dphase=0.0;
    1357             :   //NEGATING to correct for an image inversion problem
    1358           0 :   for (Int i=startRow;i<=endRow;i++) {
    1359           0 :     for (Int idim=0;idim<2;idim++) uvw(idim,i)=-vb.uvw()(i)(idim);
    1360           0 :     uvw(2,i)=vb.uvw()(i)(2);
    1361             :   }
    1362             :   
    1363           0 :   rotateUVW(uvw, dphase, vb);
    1364           0 :   refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
    1365             : 
    1366             :   // This is the convention for dphase
    1367             :   // dphase*=-1.0;
    1368             :  
    1369             :   
    1370             :   //Check if ms has changed then cache new spw and chan selection
    1371           0 :   if(vb.newMS())
    1372           0 :     matchAllSpwChans(vb);
    1373             :   //Here we redo the match or use previous match
    1374             :   
    1375             :   //Channel matching for the actual spectral window of buffer
    1376           0 :   if(doConversion_p[vb.spectralWindow()]){
    1377           0 :     matchChannel(vb.spectralWindow(), vb);
    1378             :   }
    1379             :   else{
    1380           0 :     chanMap.resize();
    1381           0 :     chanMap=multiChanMap_p[vb.spectralWindow()];
    1382             :   }
    1383             :   
    1384             :   //No point in reading data if its not matching in frequency
    1385           0 :   if(max(chanMap)==-1)
    1386           0 :     return;
    1387             : 
    1388           0 :   Cube<Complex> data;
    1389           0 :   Cube<Int> flags;
    1390           0 :   getInterpolateArrays(vb, data, flags);
    1391             : 
    1392             : 
    1393             :   
    1394             :   Complex *datStorage;
    1395             :   Bool isCopy;
    1396           0 :   datStorage=data.getStorage(isCopy);
    1397             : 
    1398           0 :   Vector<Int> rowFlags(vb.nRow());
    1399           0 :   rowFlags=0;
    1400           0 :   rowFlags(vb.flagRow())=true;
    1401           0 :   if(!usezero_p) {
    1402           0 :     for (Int rownr=startRow; rownr<=endRow; rownr++) {
    1403           0 :       if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) rowFlags(rownr)=1;
    1404             :     }
    1405             :   }
    1406             :   
    1407           0 :   Int nvp=data.shape()(0);
    1408           0 :   Int nvc=data.shape()(1);
    1409           0 :   Int nvisrow=data.shape()(2);
    1410           0 :   Int nc=nchan;
    1411           0 :   Int np=npol;
    1412           0 :   Int nxp=nx;
    1413           0 :   Int nyp=ny;
    1414           0 :   Cube<Int> loc(3, nvc, nvisrow);
    1415           0 :   Cube<Int> off(3, nvc, nRow);
    1416           0 :   Int csamp=convSampling;
    1417           0 :   Int csize=convSize;
    1418           0 :   Int wcsize=wConvSize;
    1419           0 :   Matrix<Complex> phasor(nvc, nRow);
    1420             :   Bool delphase;
    1421             :   Bool del;
    1422           0 :   Complex * phasorstor=phasor.getStorage(delphase);
    1423           0 :   const Double * visfreqstor=interpVisFreq_p.getStorage(del);
    1424           0 :   const Double * scalestor=uvScale.getStorage(del);
    1425           0 :   const Double * offsetstor=uvOffset.getStorage(del);
    1426           0 :   Int * locstor=loc.getStorage(del);
    1427           0 :   Int * offstor=off.getStorage(del);
    1428           0 :   const Int * flagstor=flags.getStorage(del);
    1429           0 :   const Int * rowflagstor=rowFlags.getStorage(del);
    1430           0 :   const Double *dpstor=dphase.getStorage(del);
    1431             :   Bool uvwcopy; 
    1432           0 :   const Double *uvwstor=uvw.getStorage(uvwcopy);
    1433             :   Bool gridcopy;
    1434           0 :   const Complex *gridstor=griddedData.getStorage(gridcopy);
    1435             :   Bool convcopy;
    1436           0 :   const Complex *convstor=convFunc.getStorage(convcopy);
    1437           0 :   const Int* pmapstor=polMap.getStorage(del);
    1438           0 :   const Int *cmapstor=chanMap.getStorage(del);
    1439           0 :   const Int * suppstor=convSupport.getStorage(del);
    1440             :   Int irow;
    1441           0 :   Int nth=1;
    1442             : #ifdef _OPENMP
    1443           0 :   if(numthreads_p >0){
    1444           0 :     nth=min(numthreads_p, omp_get_max_threads());
    1445             :   }
    1446             :   else{   
    1447           0 :     nth= omp_get_max_threads();
    1448             :   }
    1449             :   // nth=min(4,nth);
    1450             : #endif
    1451           0 :   Int dow=1;
    1452           0 :   Double cinv=Double(1.0)/C::c;
    1453             : 
    1454           0 :     #pragma omp parallel default(none) private(irow) firstprivate(visfreqstor, nvc, scalestor, offsetstor, csamp, phasorstor, uvwstor, locstor, offstor, dpstor, dow, cinv) shared(startRow, endRow) num_threads(nth) 
    1455             :   {
    1456             : #pragma omp for schedule(dynamic)
    1457             :     for (irow=startRow; irow<=endRow; ++irow){
    1458             :       /*locateuvw(uvwstor,dpstor, visfreqstor, nvc, scalestor, offsetstor, csamp, 
    1459             :                 locstor, 
    1460             :                 offstor, phasorstor, irow, true);*/
    1461             :       locuvw(uvwstor, dpstor, visfreqstor, &nvc, scalestor, offsetstor, &csamp, locstor, offstor, phasorstor, &irow, &dow, &cinv);
    1462             :   }  
    1463             : 
    1464             :   }//end pragma parallel
    1465           0 :   Int rbeg=startRow+1;
    1466           0 :   Int rend=endRow+1;
    1467           0 :   Int npart=nth*2;
    1468             :   
    1469           0 :  Timer tim;
    1470           0 :   tim.mark();
    1471             :   
    1472           0 :   Int ix=0;
    1473           0 :   #pragma omp parallel default(none) private(ix, rbeg, rend) firstprivate(uvwstor, datStorage, flagstor, rowflagstor, convstor, pmapstor, cmapstor, gridstor, nxp, nyp, np, nc, suppstor, csamp, csize, wcsize, nvp, nvc, nvisrow, phasorstor, locstor, offstor) shared(npart) num_threads(nth)
    1474             :   {
    1475             : #pragma omp for schedule(dynamic,1) 
    1476             :     for (ix=0; ix< npart; ++ix){
    1477             :       rbeg=ix*(nvisrow/npart)+1;
    1478             :       rend=(ix != (npart-1)) ? (rbeg+(nvisrow/npart)-1) : (rbeg+(nvisrow/npart)+nvisrow%npart-1) ;
    1479             :       // cerr << "rbeg " << rbeg << " rend " << rend << " nRow " << nvisrow << endl;
    1480             :       sectdwgrid(uvwstor,
    1481             :                  datStorage,
    1482             :                  &nvp,
    1483             :                  &nvc,
    1484             :                  flagstor,
    1485             :                  rowflagstor,
    1486             :                  &nvisrow,
    1487             :                  gridstor,
    1488             :                  &nxp,
    1489             :                  &nyp,
    1490             :                  &np,
    1491             :                  &nc,
    1492             :                  suppstor,
    1493             :                  &csize,
    1494             :                  &csamp,
    1495             :                  &wcsize,
    1496             :                  convstor,
    1497             :                  cmapstor,
    1498             :                  pmapstor,
    1499             :                  &rbeg, &rend, locstor, offstor, phasorstor);
    1500             :     }
    1501             : 
    1502             :   }//end pragma parallel
    1503           0 :   data.putStorage(datStorage, isCopy);
    1504           0 :   uvw.freeStorage(uvwstor, uvwcopy);
    1505           0 :   griddedData.freeStorage(gridstor, gridcopy);
    1506           0 :   convFunc.freeStorage(convstor, convcopy);
    1507           0 :    timedegrid_p+=tim.real();
    1508             : 
    1509           0 :   interpolateFrequencyFromgrid(vb, data, FTMachine::MODEL);
    1510             : }
    1511             : 
    1512             : 
    1513             : 
    1514             : // Finalize the FFT to the Sky. Here we actually do the FFT and
    1515             : // return the resulting image
    1516           0 : ImageInterface<Complex>& WProjectFT::getImage(Matrix<Float>& weights,
    1517             :                                               Bool normalize) 
    1518             : {
    1519             :   //AlwaysAssert(lattice, AipsError);
    1520           0 :   AlwaysAssert(image, AipsError);
    1521             :   
    1522           0 :   if((griddedData.nelements() ==0) && (griddedData2.nelements()==0)){
    1523           0 :      throw(AipsError("Programmer error ...request for image without right order of calls"));
    1524             :   }
    1525           0 :   logIO() << LogOrigin("WProjectFT", "getImage") << LogIO::NORMAL;
    1526             :   
    1527           0 :   weights.resize(sumWeight.shape());
    1528             :   
    1529           0 :   convertArray(weights, sumWeight);
    1530             :   
    1531             :   // If the weights are all zero then we cannot normalize
    1532             :   // otherwise we don't care.
    1533           0 :   if(max(weights)==0.0) {
    1534           0 :     if(normalize) {
    1535             :       logIO() << LogIO::SEVERE
    1536             :               << "No useful data in WProjectFT: weights all zero"
    1537           0 :               << LogIO::POST;
    1538             :     }
    1539             :     else {
    1540             :       logIO() << LogIO::WARN
    1541             :               << "No useful data in WProjectFT: weights all zero"
    1542           0 :               << LogIO::POST;
    1543             :     }
    1544             :   }
    1545             :   else {
    1546             :     logIO() << LogIO::DEBUGGING
    1547           0 :             << "Starting FFT and scaling of image" << LogIO::POST;
    1548             :     
    1549           0 :     if(useDoubleGrid_p){
    1550           0 :       ArrayLattice<DComplex> darrayLattice(griddedData2);
    1551           0 :       LatticeFFT::cfft2d(darrayLattice,false);
    1552           0 :       griddedData.resize(griddedData2.shape());
    1553           0 :       convertArray(griddedData, griddedData2);
    1554           0 :       SynthesisUtilMethods::getResource("mem peak in getImage");
    1555           0 :       griddedData2.resize();
    1556           0 :       arrayLattice = new ArrayLattice<Complex>(griddedData);
    1557           0 :       lattice=arrayLattice;
    1558             :     }else{
    1559           0 :       arrayLattice = new ArrayLattice<Complex>(griddedData);
    1560           0 :       lattice=arrayLattice;
    1561           0 :       LatticeFFT::cfft2d(*lattice,false);
    1562             : 
    1563             :     }
    1564             : 
    1565             : 
    1566           0 :     const IPosition latticeShape = lattice->shape();
    1567             :     
    1568             :     
    1569             :     {
    1570           0 :       Int inx = lattice->shape()(0);
    1571           0 :       Int iny = lattice->shape()(1);
    1572           0 :       Vector<Complex> correction(inx);
    1573           0 :       correction=Complex(1.0, 0.0);
    1574           0 :       Vector<Float> sincConvX(nx);
    1575           0 :       for (Int ix=0;ix<nx;ix++) {
    1576           0 :         Float x=C::pi*Float(ix-nx/2)/(Float(nx)*Float(convSampling));
    1577           0 :         if(ix==nx/2) {
    1578           0 :           sincConvX(ix)=1.0;
    1579             :         }
    1580             :         else {
    1581           0 :           sincConvX(ix)=sin(x)/x;
    1582             :         }
    1583             :       }
    1584           0 :       Vector<Float> sincConvY(ny);
    1585           0 :       for (Int ix=0;ix<ny;ix++) {
    1586           0 :         Float x=C::pi*Float(ix-ny/2)/(Float(ny)*Float(convSampling));
    1587           0 :         if(ix==ny/2) {
    1588           0 :           sincConvY(ix)=1.0;
    1589             :         }
    1590             :         else {
    1591           0 :           sincConvY(ix)=sin(x)/x;
    1592             :         }
    1593             :       }
    1594             :     
    1595             :       
    1596             :       
    1597           0 :       IPosition cursorShape(4, inx, 1, 1, 1);
    1598           0 :       IPosition axisPath(4, 0, 1, 2, 3);
    1599           0 :       LatticeStepper lsx(lattice->shape(), cursorShape, axisPath);
    1600           0 :       LatticeIterator<Complex> lix(*lattice, lsx);
    1601           0 :       for(lix.reset();!lix.atEnd();lix++) {
    1602           0 :         Int pol=lix.position()(2);
    1603           0 :         Int chan=lix.position()(3);
    1604           0 :         if(weights(pol, chan)!=0.0) {
    1605           0 :           Int iy=lix.position()(1);
    1606           0 :           gridder->correctX1D(correction,iy);
    1607           0 :           for (Int ix=0;ix<nx;ix++) {
    1608           0 :             correction(ix)*=sincConvX(ix)*sincConvY(iy);
    1609             :           }
    1610           0 :           lix.rwVectorCursor()/=correction;
    1611           0 :           if(normalize) {
    1612           0 :             Complex rnorm(Float(inx)*Float(iny)/weights(pol,chan));
    1613           0 :             lix.rwCursor()*=rnorm;
    1614             :           }
    1615             :           else {
    1616           0 :             Complex rnorm(Float(inx)*Float(iny));
    1617           0 :             lix.rwCursor()*=rnorm;
    1618             :           }
    1619             :         }
    1620             :         else {
    1621           0 :           lix.woCursor()=0.0;
    1622             :         }
    1623             :       }
    1624             :     }
    1625             : 
    1626           0 :     if(!isTiled) {
    1627             :       // Check the section from the image BEFORE converting to a lattice 
    1628           0 :       IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2,
    1629           0 :                     (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
    1630           0 :       IPosition stride(4, 1);
    1631           0 :       IPosition trc(blc+image->shape()-stride);
    1632             :       
    1633             :       // Do the copy
    1634           0 :       image->put(griddedData(blc, trc));
    1635             :       //if(arrayLattice) delete arrayLattice; arrayLattice=0;
    1636           0 :       griddedData.resize(IPosition(1,0));
    1637             :     }
    1638             :   }
    1639           0 :   if(!arrayLattice.null()) arrayLattice=0;
    1640           0 :   if(!lattice.null()) lattice=0;
    1641           0 :   griddedData.resize();
    1642           0 :   return *image;
    1643             : }
    1644             : 
    1645             : // Get weight image
    1646           0 : void WProjectFT::getWeightImage(ImageInterface<Float>& weightImage,
    1647             :                               Matrix<Float>& weights) 
    1648             : {
    1649             :   
    1650           0 :   logIO() << LogOrigin("WProjectFT", "getWeightImage") << LogIO::NORMAL;
    1651             :   
    1652           0 :   weights.resize(sumWeight.shape());
    1653           0 :   convertArray(weights,sumWeight);
    1654             :   
    1655           0 :   const IPosition latticeShape = weightImage.shape();
    1656             :   
    1657           0 :   Int inx=latticeShape(0);
    1658           0 :   Int iny=latticeShape(1);
    1659             :   
    1660           0 :   IPosition loc(2, 0);
    1661           0 :   IPosition cursorShape(4, inx, iny, 1, 1);
    1662           0 :   IPosition axisPath(4, 0, 1, 2, 3);
    1663           0 :   LatticeStepper lsx(latticeShape, cursorShape, axisPath);
    1664           0 :   LatticeIterator<Float> lix(weightImage, lsx);
    1665           0 :   for(lix.reset();!lix.atEnd();lix++) {
    1666           0 :     Int pol=lix.position()(2);
    1667           0 :     Int chan=lix.position()(3);
    1668           0 :     lix.rwCursor()=weights(pol,chan);
    1669             :   }
    1670           0 : }
    1671             : 
    1672           0 : Bool WProjectFT::toRecord(String& error,
    1673             :                           RecordInterface& outRec, Bool withImage, const String diskimage)
    1674             : {  
    1675             : 
    1676             :   /*
    1677             : 
    1678             :   CountedPtr<WPConvFunc> wpConvFunc_p;
    1679             :   */
    1680             : 
    1681             :   // Save the current WProjectFT object to an output state record
    1682           0 :   Bool retval = true;
    1683             :   //save the base class variables
    1684             :   //this is a memory hog and slow on saving and recovering...better to recompute convfunctions
    1685             :   /* Record wpconvrec;
    1686             :   if(wpConvFunc_p->toRecord(wpconvrec))
    1687             :     outRec.defineRecord("wpconvfunc", wpconvrec);
    1688             :   */
    1689           0 :   Float elpadd=padding_p;
    1690           0 :   if(toVis_p && withImage)
    1691           0 :     elpadd=1.0;
    1692           0 :   if(!FTMachine::toRecord(error, outRec, withImage, diskimage))
    1693           0 :     return false;
    1694             : 
    1695           0 :   outRec.define("uvscale", uvScale);
    1696           0 :   outRec.define("uvoffset", uvOffset);
    1697           0 :   outRec.define("istiled", isTiled);
    1698           0 :   outRec.define("cachesize", Int64(cachesize));
    1699           0 :   outRec.define("tilesize", tilesize);
    1700           0 :   outRec.define("maxabsdata", maxAbsData);
    1701           0 :   Vector<Int> center_loc(4), offset_loc(4);
    1702           0 :   for (Int k=0; k<4 ; k++){
    1703           0 :     center_loc(k)=centerLoc(k);
    1704           0 :     offset_loc(k)=offsetLoc(k);
    1705             :   }
    1706           0 :   outRec.define("centerloc", center_loc);
    1707           0 :   outRec.define("offsetloc", offset_loc);
    1708           0 :   outRec.define("padding", elpadd);
    1709           0 :   outRec.define("nwplanes", nWPlanes_p);
    1710           0 :   outRec.define("savedwscale", savedWScale_p);
    1711           0 :   outRec.define("usezero", usezero_p);
    1712             :   ///no need to save convfunc as it can be big and is recalculated anyways
    1713             :   ///outRec.define("convfunc", convFunc);
    1714           0 :   outRec.define("convsampling", convSampling);
    1715           0 :   outRec.define("convsize", convSize);
    1716           0 :   outRec.define("convsupport", convSupport);
    1717           0 :   outRec.define("convsizes", convSizes_p);
    1718           0 :   outRec.define("wconvsize", wConvSize);
    1719           0 :   outRec.define("lastindex", lastIndex_p);
    1720           0 :   outRec.define("minw", minW_p);
    1721           0 :   outRec.define("maxw", maxW_p);
    1722           0 :   outRec.define("rmsw", rmsW_p);
    1723             : 
    1724             : 
    1725           0 :   return retval;
    1726             : }
    1727             : 
    1728           0 : Bool WProjectFT::fromRecord(String& error,
    1729             :                             const RecordInterface& inRec)
    1730             : {
    1731           0 :   if(!FTMachine::fromRecord(error, inRec))
    1732           0 :     return false;
    1733           0 :   machineName_p="WProjectFT";
    1734           0 :   Bool retval = true;
    1735           0 :   imageCache=0; lattice=0; arrayLattice=0;
    1736           0 :   inRec.get("uvscale", uvScale);
    1737           0 :   inRec.get("uvoffset", uvOffset);
    1738           0 :   inRec.get("istiled", isTiled);
    1739           0 :   cachesize=inRec.asInt64("cachesize");
    1740           0 :   inRec.get("tilesize", tilesize);
    1741           0 :   inRec.get("maxabsdata", maxAbsData);
    1742           0 :   Vector<Int> center_loc(4), offset_loc(4);
    1743           0 :   inRec.get("centerloc", center_loc);
    1744           0 :   inRec.get("offsetloc", offset_loc);
    1745           0 :   uInt ndim4 = 4;
    1746           0 :   centerLoc=IPosition(ndim4, center_loc(0), center_loc(1), center_loc(2), 
    1747           0 :                       center_loc(3));
    1748           0 :   offsetLoc=IPosition(ndim4, offset_loc(0), offset_loc(1), offset_loc(2), 
    1749           0 :                       offset_loc(3));
    1750           0 :   inRec.get("minw", minW_p);
    1751           0 :   inRec.get("maxw", maxW_p);
    1752           0 :   inRec.get("rmsw", rmsW_p);
    1753           0 :   if(inRec.isDefined("wpconvfunc")){
    1754           0 :     wpConvFunc_p=new WPConvFunc(inRec.asRecord("wpconvfunc"));
    1755             :   }
    1756             :   else{
    1757           0 :     wpConvFunc_p=new WPConvFunc(minW_p, maxW_p, rmsW_p);
    1758             :   }
    1759           0 :   inRec.get("padding", padding_p);
    1760           0 :   inRec.get("nwplanes", nWPlanes_p);
    1761           0 :   inRec.get("savedwscale", savedWScale_p);
    1762           0 :   inRec.get("usezero", usezero_p);
    1763             :   ///have stopped saving this parameter
    1764             :   ////inRec.get("convfunc", convFunc);
    1765           0 :   convFunc.resize();
    1766           0 :   inRec.get("convsampling", convSampling);
    1767           0 :   inRec.get("convsize", convSize);
    1768           0 :   inRec.get("convsupport", convSupport);
    1769           0 :   inRec.get("convsizes", convSizes_p);
    1770           0 :   inRec.get("wconvsize", wConvSize);
    1771           0 :   inRec.get("lastindex", lastIndex_p);
    1772             :   
    1773           0 :   gridder=0;
    1774             :     ///setup some of the parameters
    1775           0 :   init();
    1776             :      
    1777             : 
    1778             :   
    1779           0 :   return retval;
    1780             : }
    1781             : 
    1782           0 : void WProjectFT::ok() {
    1783           0 :   AlwaysAssert(image, AipsError);
    1784           0 : }
    1785             : 
    1786             : // Make a plain straightforward honest-to-God image. This returns
    1787             : // a complex image, without conversion to Stokes. The representation
    1788             : // is that required for the visibilities.
    1789             : //----------------------------------------------------------------------
    1790           0 : void WProjectFT::makeImage(FTMachine::Type type, 
    1791             :                          VisSet& vs,
    1792             :                          ImageInterface<Complex>& theImage,
    1793             :                          Matrix<Float>& weight) {
    1794             :   
    1795             :   
    1796           0 :   logIO() << LogOrigin("WProjectFT", "makeImage") << LogIO::NORMAL;
    1797             :   
    1798           0 :   if(type==FTMachine::COVERAGE) {
    1799             :     logIO() << "Type COVERAGE not defined for Fourier transforms"
    1800           0 :             << LogIO::EXCEPTION;
    1801             :   }
    1802             :   
    1803             :   
    1804             :   // Initialize the gradients
    1805           0 :   ROVisIter& vi(vs.iter());
    1806             :   
    1807             :   // Loop over all visibilities and pixels
    1808           0 :   VisBuffer vb(vi);
    1809             :   
    1810             :   // Initialize put (i.e. transform to Sky) for this model
    1811           0 :   vi.origin();
    1812             :   
    1813           0 :   if(vb.polFrame()==MSIter::Linear) {
    1814           0 :     StokesImageUtil::changeCStokesRep(theImage, StokesImageUtil::LINEAR);
    1815             :   }
    1816             :   else {
    1817           0 :     StokesImageUtil::changeCStokesRep(theImage, StokesImageUtil::CIRCULAR);
    1818             :   }
    1819             :   
    1820           0 :   initializeToSky(theImage,weight,vb);
    1821             :   
    1822             :   // Loop over the visibilities, putting VisBuffers
    1823           0 :   for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
    1824           0 :     for (vi.origin(); vi.more(); vi++) {
    1825             :       
    1826           0 :       switch(type) {
    1827           0 :       case FTMachine::RESIDUAL:
    1828           0 :         vb.visCube()=vb.correctedVisCube();
    1829           0 :         vb.visCube()-=vb.modelVisCube();
    1830           0 :         put(vb, -1, false);
    1831           0 :         break;
    1832           0 :       case FTMachine::MODEL:
    1833           0 :         vb.visCube()=vb.modelVisCube();
    1834           0 :         put(vb, -1, false);
    1835           0 :         break;
    1836           0 :       case FTMachine::CORRECTED:
    1837           0 :         vb.visCube()=vb.correctedVisCube();
    1838           0 :         put(vb, -1, false);
    1839           0 :         break;
    1840           0 :       case FTMachine::PSF:
    1841           0 :         vb.visCube()=Complex(1.0,0.0);
    1842           0 :         put(vb, -1, true);
    1843           0 :         break;
    1844           0 :       case FTMachine::OBSERVED:
    1845             :       default:
    1846           0 :         put(vb, -1, false);
    1847           0 :         break;
    1848             :       }
    1849             :     }
    1850             :   }
    1851           0 :   finalizeToSky();
    1852             :   // Normalize by dividing out weights, etc.
    1853           0 :   getImage(weight, true);
    1854           0 : }
    1855             : 
    1856             : 
    1857           0 : String WProjectFT::name() const {
    1858             : 
    1859           0 :   return machineName_p;
    1860             : 
    1861             : }
    1862             : 
    1863           0 :   void WProjectFT::wStat(ROVisibilityIterator& vi, Double& minW, Double& maxW, Double& rmsW){
    1864           0 :      VisBuffer vb(vi);
    1865           0 :     maxW=0.0;
    1866           0 :     minW=1e99;
    1867           0 :     Double nval=0;
    1868           0 :     rmsW=0.0;
    1869           0 :     for (vi.originChunks(); vi.moreChunks(); vi.nextChunk()) {
    1870           0 :       for (vi.origin();vi.more();vi++) {
    1871           0 :         maxW=max(maxW, max(abs(vb.uvwMat().row(2)*max(vb.frequency())))/C::c);
    1872           0 :         minW=min(minW, min(abs(vb.uvwMat().row(2)*min(vb.frequency())))/C::c);
    1873             :         ///////////some shenanigans as some compilers is confusing * operator for vector
    1874           0 :         Vector<Double> elw;
    1875           0 :         elw=vb.uvwMat().row(2);
    1876           0 :         elw*=vb.uvwMat().row(2);
    1877             :         //////////////////////////////////////////////////
    1878           0 :         rmsW+=sum(elw);
    1879             : 
    1880           0 :         nval+=Double(vb.nRow());
    1881             :       }
    1882             :     }
    1883           0 :     rmsW=sqrt(rmsW/Double(nval))*max(vb.frequency())/C::c;
    1884             : 
    1885           0 :   }
    1886             : 
    1887             : 
    1888             : } //# NAMESPACE CASA - END
    1889             : 

Generated by: LCOV version 1.16