LCOV - code coverage report
Current view: top level - synthesis/TransformMachines2 - WProjectFT.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 491 695 70.6 %
Date: 2024-12-11 20:54:31 Functions: 22 29 75.9 %

          Line data    Source code
       1             : //# WProjectFT.cc: Implementation of WProjectFT class
       2             : //# Copyright (C) 2003-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 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: casa-feedback@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             : #include <msvis/MSVis/VisibilityIterator2.h>
      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/TransformMachines2/WProjectFT.h>
      43             : #include <synthesis/TransformMachines2/WPConvFunc.h>
      44             : #include <casacore/scimath/Mathematics/RigidVector.h>
      45             : #include <msvis/MSVis/StokesVector.h>
      46             : #include <synthesis/TransformMachines/StokesImageUtil.h>
      47             : #include <casacore/images/Images/ImageInterface.h>
      48             : #include <casacore/images/Images/PagedImage.h>
      49             : #include <casacore/casa/Containers/Block.h>
      50             : #include <casacore/casa/Containers/Record.h>
      51             : #include <casacore/casa/Arrays/ArrayLogical.h>
      52             : #include <casacore/casa/Arrays/ArrayMath.h>
      53             : #include <casacore/casa/Arrays/Array.h>
      54             : #include <casacore/casa/Arrays/MaskedArray.h>
      55             : #include <casacore/casa/Arrays/Vector.h>
      56             : #include <casacore/casa/Arrays/Slice.h>
      57             : #include <casacore/casa/Arrays/Matrix.h>
      58             : #include <casacore/casa/Arrays/Cube.h>
      59             : #include <casacore/casa/Arrays/MatrixIter.h>
      60             : #include <casacore/casa/BasicSL/String.h>
      61             : #include <casacore/casa/Utilities/Assert.h>
      62             : #include <casacore/casa/Exceptions/Error.h>
      63             : #include <iostream>
      64             : #include <iomanip>
      65             : #include <casacore/lattices/Lattices/ArrayLattice.h>
      66             : #include <casacore/lattices/Lattices/SubLattice.h>
      67             : #include <casacore/lattices/LRegions/LCBox.h>
      68             : #include <casacore/lattices/LEL/LatticeExpr.h>
      69             : #include <casacore/lattices/Lattices/LatticeCache.h>
      70             : #include <casacore/lattices/LatticeMath/LatticeFFT.h>
      71             : #include <casacore/lattices/Lattices/LatticeIterator.h>
      72             : #include <casacore/lattices/Lattices/LatticeStepper.h>
      73             : #include <casacore/casa/Utilities/CompositeNumber.h>
      74             : #include <casacore/casa/OS/Timer.h>
      75             : #include <casacore/casa/OS/HostInfo.h>
      76             : #include <sstream>
      77             : #ifdef _OPENMP
      78             : #include <omp.h>
      79             : #endif
      80             : using namespace casacore;
      81             : namespace casa { //# NAMESPACE CASA - BEGIN
      82             : namespace refim { //#namespace for imaging refactoring
      83             : 
      84             : using namespace casacore;
      85             : using namespace casa;
      86             : using namespace casacore;
      87             : using namespace casa::vi;
      88             : using namespace casacore;
      89             : using namespace casa::refim;
      90             : 
      91           0 : WProjectFT::WProjectFT( Int nWPlanes, Long icachesize, Int itilesize, 
      92           0 :                         Bool usezero, Bool useDoublePrec, const Double minW, const Double maxW, const Double rmsW)
      93           0 :   : FTMachine(), padding_p(1.0), nWPlanes_p(nWPlanes),
      94           0 :     imageCache(0), cachesize(icachesize), tilesize(itilesize),
      95           0 :     gridder(0), isTiled(false), 
      96           0 :     maxAbsData(0.0), centerLoc(IPosition(4,0)), offsetLoc(IPosition(4,0)), usezero_p(usezero), 
      97           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)
      98             : {
      99           0 :   convSize=0;
     100           0 :   tangentSpecified_p=false;
     101           0 :   lastIndex_p=0;
     102           0 :   useDoubleGrid_p=useDoublePrec;
     103           0 :   wpConvFunc_p=new WPConvFunc(minW, maxW, rmsW);
     104             : 
     105           0 : }
     106          89 : WProjectFT::WProjectFT(Int nWPlanes, 
     107             :                        MPosition mLocation, 
     108             :                        Long icachesize, Int itilesize, 
     109          89 :                        Bool usezero, Float padding, Bool useDoublePrec, const Double minW, const Double maxW, const Double rmsW)
     110          89 :   : FTMachine(), padding_p(padding), nWPlanes_p(nWPlanes),
     111          89 :     imageCache(0), cachesize(icachesize), tilesize(itilesize),
     112          89 :     gridder(0), isTiled(false),  
     113          89 :     maxAbsData(0.0), centerLoc(IPosition(4,0)), offsetLoc(IPosition(4,0)),
     114          89 :     usezero_p(usezero),  
     115         178 :     machineName_p("WProjectFT"), timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0), minW_p(minW), maxW_p(maxW), rmsW_p(rmsW)
     116             : 
     117             : {
     118          89 :   convSize=0;
     119          89 :   savedWScale_p=0.0;
     120          89 :   tangentSpecified_p=false;
     121          89 :   mLocation_p=mLocation;
     122          89 :   lastIndex_p=0;
     123          89 :   wpConvFunc_p=new WPConvFunc(minW, maxW, rmsW);
     124          89 :   useDoubleGrid_p=useDoublePrec;
     125          89 : }
     126           2 : WProjectFT::WProjectFT(
     127             :                        Int nWPlanes, MDirection mTangent, 
     128             :                        MPosition mLocation, 
     129             :                        Long icachesize, Int itilesize, 
     130           2 :                        Bool usezero, Float padding, Bool useDoublePrec, const Double minW, const Double maxW, const Double rmsW)
     131           2 :   : FTMachine(), padding_p(padding), nWPlanes_p(nWPlanes),
     132           2 :     imageCache(0), cachesize(icachesize), tilesize(itilesize),
     133           2 :     gridder(0), isTiled(false),  
     134           2 :     maxAbsData(0.0), centerLoc(IPosition(4,0)), offsetLoc(IPosition(4,0)),
     135           2 :     usezero_p(usezero), 
     136           4 :     machineName_p("WProjectFT"), timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0), minW_p(minW), maxW_p(maxW), rmsW_p(rmsW)
     137             : {
     138           2 :   convSize=0;
     139           2 :   savedWScale_p=0.0;
     140           2 :   mTangent_p=mTangent;
     141           2 :   tangentSpecified_p=true;
     142           2 :   mLocation_p=mLocation;
     143           2 :   lastIndex_p=0;
     144           2 :   wpConvFunc_p=new WPConvFunc(minW, maxW, rmsW);
     145           2 :   useDoubleGrid_p=useDoublePrec;
     146           2 : }
     147             : 
     148           0 : WProjectFT::WProjectFT(const RecordInterface& stateRec)
     149           0 :   : FTMachine(),machineName_p("WProjectFT"), timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0)
     150             : {
     151             :   // Construct from the input state record
     152           0 :   String error;
     153           0 :   if (!fromRecord(error, stateRec)) {
     154           0 :     throw (AipsError("Failed to create WProjectFT: " + error));
     155             :   };
     156           0 : }
     157             : //---------------------------------------------------------------------- 
     158          30 : WProjectFT& WProjectFT::operator=(const WProjectFT& other)
     159             : {
     160          30 :   if(this!=&other) {
     161             :     //Do the base parameters
     162          30 :     FTMachine::operator=(other);
     163             :     
     164             :     
     165          30 :     padding_p=other.padding_p;
     166          30 :     nWPlanes_p=other.nWPlanes_p;
     167          30 :     imageCache=other.imageCache;
     168          30 :     cachesize=other.cachesize;
     169          30 :     tilesize=other.tilesize;
     170          30 :     if(other.gridder==0)
     171          30 :       gridder=0;
     172             :     else{
     173           0 :       uvScale.resize();
     174           0 :       uvOffset.resize();
     175           0 :       uvScale=other.uvScale;
     176           0 :       uvOffset=other.uvOffset;
     177           0 :       gridder = new ConvolveGridder<Double, Complex>(IPosition(2, nx, ny),
     178           0 :                                                      uvScale, uvOffset,
     179           0 :                                                      "SF");
     180             :     }
     181             : 
     182          30 :     isTiled=other.isTiled;
     183             :     //lattice=other.lattice;
     184             :     //arrayLattice=other.arrayLattice;
     185          30 :     lattice=0;
     186          30 :     arrayLattice=0;
     187             : 
     188          30 :     maxAbsData=other.maxAbsData;
     189          30 :     centerLoc=other.centerLoc;
     190          30 :     offsetLoc=other.offsetLoc;
     191          30 :     usezero_p=other.usezero_p;
     192          30 :     machineName_p=other.machineName_p;
     193          30 :     wpConvFunc_p=other.wpConvFunc_p;
     194          30 :     timemass_p=0.0;
     195          30 :     timegrid_p=0.0;
     196          30 :     timedegrid_p=0.0;
     197          30 :     minW_p=other.minW_p;
     198          30 :     maxW_p=other.maxW_p;
     199          30 :     rmsW_p=other.rmsW_p;
     200             :   };
     201          30 :   return *this;
     202             : };
     203             : 
     204             : //----------------------------------------------------------------------
     205          30 :   WProjectFT::WProjectFT(const WProjectFT& other) :FTMachine(), machineName_p("WProjectFT"),timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0)
     206             : {
     207          30 :   operator=(other);
     208          30 : }
     209             : 
     210          30 : FTMachine* WProjectFT::cloneFTM(){
     211          30 :   return new WProjectFT(*this);
     212             : }
     213             : 
     214             : //----------------------------------------------------------------------
     215          94 : void WProjectFT::init() {
     216             :   /*  if((padding_p*padding_p*image->shape().product())>cachesize) {
     217             :     isTiled=true;
     218             :     nx    = image->shape()(0);
     219             :     ny    = image->shape()(1);
     220             :     npol  = image->shape()(2);
     221             :     nchan = image->shape()(3);
     222             :   }
     223             :   else {*/
     224             :     // We are padding.
     225          94 :     isTiled=false;
     226          94 :     CompositeNumber cn(uInt(image->shape()(0)*2));    
     227          94 :     nx    = cn.nextLargerEven(Int(padding_p*Float(image->shape()(0))-0.5));
     228          94 :     ny    = cn.nextLargerEven(Int(padding_p*Float(image->shape()(1))-0.5));   
     229          94 :     npol  = image->shape()(2);
     230          94 :     nchan = image->shape()(3);
     231             :     //}
     232             :   
     233             :   //  if(image->shape().product()>cachesize) {
     234             :   //   isTiled=true;
     235             :   // }
     236             :   // else {
     237             :   // isTiled=false;
     238             :   // }
     239             :   //The Tiled version need some fixing: sof or now
     240          94 :   isTiled=false;
     241             : 
     242             :  
     243          94 :   sumWeight.resize(npol, nchan);
     244             :   
     245          94 :   wConvSize=max(0, nWPlanes_p);
     246          94 :   convSupport.resize(wConvSize);
     247          94 :   convSupport=0;
     248             : 
     249          94 :   uvScale.resize(3);
     250          94 :   uvScale=0.0;
     251          94 :   uvScale(0)=Float(nx)*image->coordinates().increment()(0); 
     252          94 :   uvScale(1)=Float(ny)*image->coordinates().increment()(1); 
     253          94 :   if(savedWScale_p==0.0){
     254          50 :     uvScale(2)=Float(wConvSize)*abs(image->coordinates().increment()(0));
     255             :   }
     256             :   else{
     257          44 :     uvScale(2)=savedWScale_p;
     258             :   }
     259          94 :   uvOffset.resize(3);
     260          94 :   uvOffset(0)=nx/2;
     261          94 :   uvOffset(1)=ny/2;
     262          94 :   uvOffset(2)=0;
     263             :   
     264             :   
     265             : 
     266          94 :   if(gridder) delete gridder; gridder=0;
     267         188 :   gridder = new ConvolveGridder<Double, Complex>(IPosition(2, nx, ny),
     268          94 :                                                  uvScale, uvOffset,
     269          94 :                                                  "SF");
     270             : 
     271             :   // Set up image cache needed for gridding. 
     272          94 :   if(imageCache) delete imageCache; imageCache=0;
     273             :   
     274             :   // The tile size should be large enough that the
     275             :   // extended convolution function can fit easily
     276          94 :   if(isTiled) {
     277           0 :     Float tileOverlap=0.5;
     278           0 :     tilesize=min(256,tilesize);
     279           0 :     IPosition tileShape=IPosition(4,tilesize,tilesize,npol,nchan);
     280           0 :     Vector<Float> tileOverlapVec(4);
     281           0 :     tileOverlapVec=0.0;
     282           0 :     tileOverlapVec(0)=tileOverlap;
     283           0 :     tileOverlapVec(1)=tileOverlap;
     284           0 :     Int tmpCacheVal=static_cast<Int>(cachesize);
     285           0 :     imageCache=new LatticeCache <Complex> (*image, tmpCacheVal, tileShape, 
     286             :                                            tileOverlapVec,
     287           0 :                                            (tileOverlap>0.0));
     288             :     
     289           0 :   }
     290          94 : }
     291             : 
     292             : // This is nasty, we should use CountedPointers here.
     293         240 : WProjectFT::~WProjectFT() {
     294         120 :   if(imageCache) delete imageCache; imageCache=0;
     295         120 :   if(gridder) delete gridder; gridder=0;
     296             :   /*
     297             :   if(arrayLattice) delete arrayLattice; arrayLattice=0;
     298             :   
     299             :   Int numofmodels=convFunctions_p.nelements();
     300             :   for (Int k=0; k< numofmodels; ++k){
     301             :     delete convFunctions_p[k];
     302             :     delete convSupportBlock_p[k];
     303             : 
     304             :   }
     305             :   */
     306             :   // convFuctions_p.resize();
     307             :   //  convSupportBlock_p.resize();
     308             : 
     309         240 : }
     310             : 
     311             : 
     312          45 : void WProjectFT::setConvFunc(CountedPtr<WPConvFunc>& pbconvFunc){
     313             : 
     314          45 :   wpConvFunc_p=pbconvFunc;
     315          45 : }
     316          45 : CountedPtr<WPConvFunc>& WProjectFT::getConvFunc(){
     317             : 
     318          45 :   return wpConvFunc_p;
     319             : }
     320             : 
     321        1824 : void WProjectFT::findConvFunction(const ImageInterface<Complex>& image,
     322             :                                 const VisBuffer2& vb) {
     323             :   
     324             : 
     325             : 
     326             : 
     327             : 
     328        1824 :   wpConvFunc_p->findConvFunction(image, vb, wConvSize, uvScale, uvOffset,
     329        1824 :                                  padding_p,
     330        1824 :                                  convSampling, 
     331        1824 :                                  convFunc, convSize, convSupport, 
     332        1824 :                                  savedWScale_p); 
     333             : 
     334        1824 :   nWPlanes_p=convSupport.nelements();
     335        1824 :   wConvSize=max(1,nWPlanes_p);
     336        1824 :   uvScale(2)=savedWScale_p;
     337             : 
     338             :   
     339             :   
     340        1824 : }
     341             : 
     342          16 : void WProjectFT::initializeToVis(ImageInterface<Complex>& iimage,
     343             :                                const VisBuffer2& vb)
     344             : {
     345          16 :   image=&iimage;
     346          16 :   toVis_p=true;
     347          16 :   ok();
     348             :   
     349             :   //   if(convSize==0) {
     350          16 :   init();
     351             :   // }
     352          16 :   findConvFunction(*image, vb);
     353             : 
     354             :   
     355             :   // Initialize the maps for polarization and channel. These maps
     356             :   // translate visibility indices into image indices
     357          16 :   initMaps(vb);
     358             :   
     359             :   //  nx    = image->shape()(0);
     360             :   //  ny    = image->shape()(1);
     361             :   //  npol  = image->shape()(2);
     362             :   //  nchan = image->shape()(3);
     363             : 
     364             : 
     365          16 :   isTiled=false;
     366             :   // If we are memory-based then read the image in and create an
     367             :   // ArrayLattice otherwise just use the PagedImage
     368             :   /*if(isTiled) {
     369             :     lattice=CountedPtr<Lattice<Complex> > (image, false);
     370             :   }
     371             :   else {
     372             :    }
     373             :   */
     374             :   //AlwaysAssert(lattice, AipsError);
     375             :   
     376          16 :   prepGridForDegrid();
     377          16 : }
     378             : 
     379          16 : void WProjectFT::prepGridForDegrid(){
     380          16 :   IPosition gridShape(4, nx, ny, npol, nchan);
     381          16 :   griddedData.resize(gridShape);
     382          16 :   griddedData=Complex(0.0);
     383             :   
     384             : 
     385          16 :   IPosition stride(4, 1);
     386          32 :   IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2,
     387          32 :                 (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
     388          32 :   IPosition trc(blc+image->shape()-stride);
     389             :   
     390          16 :   IPosition start(4, 0);
     391          16 :   griddedData(blc, trc) = image->getSlice(start, image->shape());
     392             :   
     393             :   //if(arrayLattice) delete arrayLattice; arrayLattice=0;
     394          16 :   arrayLattice = new ArrayLattice<Complex>(griddedData);
     395          16 :   lattice=arrayLattice;
     396             : 
     397          16 :   logIO() << LogIO::DEBUGGING << "Starting FFT of image" << LogIO::POST;
     398             :   
     399             :   
     400          16 : Vector<Float> sincConvX(nx);
     401       17556 :   for (Int ix=0;ix<nx;ix++) {
     402       17540 :     Float x=C::pi*Float(ix-nx/2)/(Float(nx)*Float(convSampling));
     403       17540 :     if(ix==nx/2) {
     404          16 :       sincConvX(ix)=1.0;
     405             :     }
     406             :     else {
     407       17524 :       sincConvX(ix)=sin(x)/x;
     408             :     }
     409             :   }
     410          16 :   Vector<Float> sincConvY(ny);
     411       17556 :   for (Int ix=0;ix<ny;ix++) {
     412       17540 :     Float x=C::pi*Float(ix-ny/2)/(Float(ny)*Float(convSampling));
     413       17540 :     if(ix==ny/2) {
     414          16 :       sincConvY(ix)=1.0;
     415             :     }
     416             :     else {
     417       17524 :       sincConvY(ix)=sin(x)/x;
     418             :     }
     419             :   }
     420             : 
     421          16 :   Vector<Complex> correction(nx);
     422          16 :   correction=Complex(1.0, 0.0);
     423             :   // Do the Grid-correction
     424          16 :   IPosition cursorShape(4, nx, 1, 1, 1);
     425          16 :   IPosition axisPath(4, 0, 1, 2, 3);
     426          16 :   LatticeStepper lsx(lattice->shape(), cursorShape, axisPath);
     427          16 :   LatticeIterator<Complex> lix(*lattice, lsx);
     428       26396 :   for(lix.reset();!lix.atEnd();lix++) {
     429       26380 :     Int iy=lix.position()(1);
     430       26380 :     gridder->correctX1D(correction,iy);
     431    36722180 :     for (Int ix=0;ix<nx;ix++) {
     432    36695800 :       correction(ix)/=(sincConvX(ix)*sincConvY(iy));
     433             :     }
     434       26380 :     lix.rwVectorCursor()/=correction;
     435             :   }
     436             :   
     437             :   // Now do the FFT2D in place
     438          16 :   LatticeFFT::cfft2d(*lattice);
     439             :   
     440          16 :   logIO() << LogIO::DEBUGGING << "Finished FFT" << LogIO::POST;
     441             : 
     442             : 
     443             : 
     444          16 : }
     445             : 
     446             : 
     447          15 : void WProjectFT::finalizeToVis()
     448             : {
     449          15 :   logIO() << LogOrigin("WProjectFT", "finalizeToVis")  << LogIO::NORMAL;
     450          15 :   logIO() <<LogIO::NORMAL2<< "Time to degrid " << timedegrid_p << LogIO::POST ;
     451          15 :   timedegrid_p=0.0;
     452          15 :   if(!arrayLattice.null()) arrayLattice=0;
     453          15 :   if(!lattice.null()) lattice=0;
     454          15 :   griddedData.resize();
     455          15 :   if(isTiled) {
     456             :     
     457             :    
     458             :     
     459           0 :     AlwaysAssert(imageCache, AipsError);
     460           0 :     AlwaysAssert(image, AipsError);
     461           0 :     ostringstream o;
     462           0 :     imageCache->flush();
     463           0 :     imageCache->showCacheStatistics(o);
     464           0 :     logIO() << o.str() << LogIO::POST;
     465           0 :   }
     466          15 : }
     467             : 
     468             : 
     469             : // Initialize the FFT to the Sky. Here we have to setup and initialize the
     470             : // grid. 
     471          78 : void WProjectFT::initializeToSky(ImageInterface<Complex>& iimage,
     472             :                                Matrix<Float>& weight,
     473             :                                const VisBuffer2& vb)
     474             : {
     475             :   // image always points to the image
     476          78 :   image=&iimage;
     477          78 :   toVis_p=false;
     478             :   
     479             :   //  if(convSize==0) {
     480          78 :   init();
     481             :   //  }
     482          78 :   findConvFunction(*image, vb);
     483             :   
     484             :   
     485             :   // Initialize the maps for polarization and channel. These maps
     486             :   // translate visibility indices into image indices
     487          78 :   initMaps(vb);
     488             :   
     489             :   //  nx    = image->shape()(0);
     490             :   //  ny    = image->shape()(1);
     491             :   //  npol  = image->shape()(2);
     492             :   //  nchan = image->shape()(3);
     493             : 
     494             :   //  if(image->shape().product()>cachesize) {
     495             :   //  isTiled=true;
     496             :   // }
     497             :   // else {
     498             :   //  isTiled=false;
     499             :   // }
     500          78 :   isTiled=false;
     501          78 :   sumWeight=0.0;
     502          78 :   weight.resize(sumWeight.shape());
     503          78 :   weight=0.0;
     504             :   
     505             :   // Initialize for in memory or to disk gridding. lattice will
     506             :   // point to the appropriate Lattice, either the ArrayLattice for
     507             :   // in memory gridding or to the image for to disk gridding.
     508          78 :   if(isTiled) {
     509           0 :     imageCache->flush();
     510           0 :     image->set(Complex(0.0));
     511           0 :     lattice=CountedPtr<Lattice<Complex> > (image, false);
     512             :   }
     513             :   else {
     514          78 :     IPosition gridShape(4, nx, ny, npol, nchan);
     515          78 :     if(!useDoubleGrid_p){
     516           1 :       griddedData.resize(gridShape);
     517           1 :       griddedData=Complex(0.0);
     518             :     }
     519             :     else{
     520             :       //griddedData.resize();
     521          77 :       griddedData2.resize(gridShape);
     522          77 :       griddedData2=DComplex(0.0);
     523             :     }
     524             :     //if(arrayLattice) delete arrayLattice; arrayLattice=0;
     525             :    
     526          78 :   }
     527             :   //AlwaysAssert(lattice, AipsError);
     528             :   
     529          78 : }
     530             : 
     531          78 : void WProjectFT::finalizeToSky()
     532             : {
     533          78 :   logIO() << LogOrigin("WProjectFT", "finalizeToSky")  << LogIO::NORMAL;
     534          78 :   logIO() <<LogIO::NORMAL2<< "Time to massage data " << timemass_p << LogIO::POST;
     535          78 :   logIO() << LogIO::NORMAL2 <<"Time to grid data " << timegrid_p << LogIO::POST;
     536          78 :   timemass_p=0.0;
     537          78 :   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          78 :   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           0 :   }
     550          78 : }
     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        6036 : void WProjectFT::put(const VisBuffer2& 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             :   //if(vb.isNewMs())
     767             :   //  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             :   //if(doConversion_p[vb.spectralWindows()[0]]){
     773        6036 :     matchChannel(vb);
     774             :   //}
     775             :   //else{
     776             :   //  chanMap.resize();
     777             :   //  chanMap=multiChanMap_p[vb.spectralWindows()[0]];
     778             :   //}
     779             :   
     780             :   //No point in reading data if its not matching in frequency
     781        6036 :   if(max(chanMap)==-1)
     782           0 :     return;
     783        6036 :   Timer tim;
     784        6036 :    tim.mark();
     785             : 
     786             :    //const Matrix<Float> *imagingweight;
     787             :    //imagingweight=&(vb.imagingWeight());
     788        6036 :    Matrix<Float> imagingweight;
     789        6036 :    getImagingWeight(imagingweight, vb);
     790        6036 :   if(dopsf) type=FTMachine::PSF;
     791             : 
     792        6036 :   Cube<Complex> data;
     793             :   //Fortran gridder need the flag as ints 
     794        6036 :   Cube<Int> flags;
     795        6036 :   Matrix<Float> elWeight;
     796        6036 :   interpolateFrequencyTogrid(vb, imagingweight,data, flags, elWeight, type);
     797             :   
     798             :   
     799             :   Bool iswgtCopy;
     800             :   const Float *wgtStorage;
     801        6036 :   wgtStorage=elWeight.getStorage(iswgtCopy);
     802             : 
     803             : 
     804             :   Bool isCopy;
     805        6036 :   const Complex *datStorage=0;
     806             : 
     807        6036 :   if(!dopsf)
     808        3883 :     datStorage=data.getStorage(isCopy);
     809             : 
     810             : 
     811             :   // If row is -1 then we pass through all rows
     812             :   Int startRow, endRow, nRow;
     813        6036 :   if (row==-1) {
     814        6036 :     nRow=vb.nRows();
     815        6036 :     startRow=0;
     816        6036 :     endRow=nRow-1;
     817             :   } else {
     818           0 :     nRow=1;
     819           0 :     startRow=row;
     820           0 :     endRow=row;
     821             :   }
     822             :   
     823             :   // Get the uvws in a form that Fortran can use and do that
     824             :   // necessary phase rotation. On a Pentium Pro 200 MHz
     825             :   // when null, this step takes about 50us per uvw point. This
     826             :   // is just barely noticeable for Stokes I continuum and
     827             :   // irrelevant for other cases.
     828        6036 :   Matrix<Double> uvw(negateUV(vb));
     829        6036 :   Vector<Double> dphase(vb.nRows());
     830        6036 :   dphase=0.0;
     831             :  
     832        6036 :   rotateUVW(uvw, dphase, vb);
     833        6036 :   refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
     834             : 
     835             : 
     836             :   
     837             :   // Take care of translation of Bools to Integer
     838        6036 :   Int idopsf=0;
     839        6036 :   if(dopsf) idopsf=1;
     840             :   
     841        6036 :   Vector<Int> rowFlags(vb.nRows());
     842        6036 :   rowFlags=0;
     843        6036 :   rowFlags(vb.flagRow())=true;
     844        6036 :   if(!usezero_p) {
     845     2054272 :     for (Int rownr=startRow; rownr<=endRow; rownr++) {
     846     2048436 :       if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) rowFlags(rownr)=1;
     847             :     }
     848             :   }
     849             :   
     850             :   
     851             :   Bool del;
     852             :   //    IPosition s(flags.shape());
     853        6036 :   Vector<Int> s(flags.shape().nelements());
     854        6036 :   convertArray(s, flags.shape().asVector());
     855        6036 :   Int nvp=s[0];
     856        6036 :   Int nvc=s[1];
     857        6036 :   Int nvisrow=s[2];
     858             : 
     859        6036 :   Int csamp=convSampling;
     860             :   
     861             :   Bool uvwcopy; 
     862        6036 :   const Double *uvwstor=uvw.getStorage(uvwcopy);
     863             :   Bool gridcopy;
     864             :   Bool convcopy;
     865        6036 :   const Complex *convstor=convFunc.getStorage(convcopy);
     866        6036 :   Cube<Int> loc(3, nvc, nRow);
     867        6036 :   Cube<Int> off(3, nvc, nRow);
     868        6036 :   Matrix<Complex> phasor(nvc, nRow);
     869             :   Bool delphase;
     870        6036 :   Complex * phasorstor=phasor.getStorage(delphase);
     871        6036 :   const Double * visfreqstor=interpVisFreq_p.getStorage(del);
     872        6036 :   const Double * scalestor=uvScale.getStorage(del);
     873        6036 :   const Double * offsetstor=uvOffset.getStorage(del);
     874             :   Bool delloc, deloff;
     875        6036 :   Int * locstor=loc.getStorage(delloc);
     876        6036 :   Int * offstor=off.getStorage(deloff);
     877        6036 :   const Double *dpstor=dphase.getStorage(del);
     878        6036 :   Double cinv=Double(1.0)/C::c;
     879             :   Int irow;
     880        6036 :   Int dow=1;
     881        6036 :   Int nth=1;
     882             : #ifdef _OPENMP
     883        6036 :   if(numthreads_p >0){
     884           0 :     nth=min(numthreads_p, omp_get_max_threads());
     885             :   }
     886             :   else{   
     887        6036 :     nth= omp_get_max_threads();
     888             :   }
     889             :   //nth=min(4,nth);
     890             : #endif
     891             : 
     892             : 
     893        6036 : #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)
     894             : 
     895             : {
     896             : #pragma omp for schedule(dynamic)
     897             :   for (irow=startRow; irow<=endRow;irow++){
     898             :     //locateuvw(uvwstor,dpstor, visfreqstor, nvc, scalestor, offsetstor, csamp, 
     899             :     //        locstor, 
     900             :     //        offstor, phasorstor, irow, true);
     901             :     locuvw(uvwstor, dpstor, visfreqstor, &nvc, scalestor, offsetstor, &csamp, locstor, offstor, phasorstor, &irow, &dow, &cinv);
     902             :   }  
     903             : 
     904             :  }//end pragma parallel
     905        6036 :   Int maxx=0; 
     906        6036 :   Int minx=1000000;
     907        6036 :   Int maxy=0;
     908        6036 :   Int miny=1000000;
     909             :   //Int maxsupp=max(convSupport);
     910        6036 :   loc.putStorage(locstor, delloc);
     911        6036 :   maxx=max(loc.yzPlane(0));
     912        6036 :   maxx=min(nx-1,  maxx-1);
     913        6036 :   minx=min(loc.yzPlane(0));
     914        6036 :   minx=max(0, minx-1);
     915        6036 :   maxy=max(loc.yzPlane(1));
     916        6036 :   maxy=min(ny-1, maxy-1);
     917        6036 :   miny=min(loc.yzPlane(1));
     918        6036 :   miny=max(0,miny-1);
     919        6036 :   locstor=loc.getStorage(delloc);
     920             :   //cerr << "dels " << delloc << "  " << deloff << endl;
     921             :   //cerr << "LOC " << min(loc.xzPlane(0)) << "  max " << loc.shape() << endl;
     922        6036 :   timemass_p +=tim.real();
     923             :   Int ixsub, iysub, icounter;
     924        6036 :   ixsub=1;
     925        6036 :   iysub=1;
     926        6036 :   if (nth >4){
     927        3170 :     ixsub=8;
     928        3170 :     iysub=8; 
     929             :   }
     930             :   else {
     931        2866 :      ixsub=2;
     932        2866 :      iysub=2; 
     933             :   }
     934             :   //nxsub=nx;
     935             :   //nysub=ny;
     936        6036 :   Int rbeg=startRow+1;
     937        6036 :   Int rend=endRow+1;
     938             :  
     939        6036 :   const Int* pmapstor=polMap.getStorage(del);
     940        6036 :   const Int *cmapstor=chanMap.getStorage(del);
     941        6036 :   Int nc=nchan;
     942        6036 :   Int np=npol;
     943             :   // Int nxp=nx;
     944             :   // Int nyp=ny;
     945        6036 :   minx=0;
     946        6036 :   miny=0;
     947        6036 :   Int nxp=nx;
     948        6036 :   Int nyp=ny;
     949        6036 :   Int nxcopy=nx;
     950        6036 :   Int nycopy=ny;
     951             :  
     952        6036 :   Int csize=convSize;
     953        6036 :    Int wcsize=wConvSize;
     954        6036 :   const Int * flagstor=flags.getStorage(del);
     955        6036 :   const Int * rowflagstor=rowFlags.getStorage(del);
     956        6036 :   const Int * suppstor=convSupport.getStorage(del);
     957        6036 :   tim.mark(); 
     958        6036 :   Block<Matrix<Double> > sumwgt(ixsub*iysub);
     959      220380 :   for (icounter=0; icounter < ixsub*iysub; ++icounter){
     960      214344 :     sumwgt[icounter].resize(sumWeight.shape());
     961      214344 :     sumwgt[icounter].set(0.0);
     962             :   }
     963        6036 :   if(doneThreadPartition_p < 0){
     964          52 :     xsect_p.resize(ixsub*iysub);
     965          52 :     ysect_p.resize(ixsub*iysub);
     966          52 :     nxsect_p.resize(ixsub*iysub);
     967          52 :     nysect_p.resize(ixsub*iysub);
     968        1160 :     for (icounter=0; icounter < ixsub*iysub; ++icounter){
     969        1108 :       findGridSector(nxp, nyp, ixsub, iysub, minx, miny, icounter, xsect_p(icounter), ysect_p(icounter), nxsect_p(icounter), nysect_p(icounter), true);
     970             :     }
     971             :   }
     972        6036 :   Vector<Int> xsect, ysect, nxsect, nysect;
     973        6036 :   xsect=xsect_p; ysect=ysect_p; nxsect=nxsect_p; nysect=nysect_p;
     974             : 
     975        6036 :   if(!useDoubleGrid_p){
     976         200 :     Complex *gridstor=griddedData.getStorage(gridcopy);
     977         200 : #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)
     978             :     {
     979             : 
     980             : #pragma omp for schedule(dynamic) 
     981             :     for(icounter=0; icounter < ixsub*iysub; ++icounter){
     982             :      
     983             :      
     984             :        Int x0=xsect(icounter);
     985             :        Int y0=ysect(icounter);
     986             :        Int nxsub=nxsect(icounter);
     987             :        Int nysub=nysect(icounter);
     988             : 
     989             :       sectgwgrids(uvwstor,
     990             :            datStorage,
     991             :            &nvp,
     992             :            &nvc,
     993             :            &idopsf,
     994             :            flagstor,
     995             :            rowflagstor,
     996             :            wgtStorage,
     997             :            &nvisrow,
     998             :            gridstor,
     999             :            &nxcopy,
    1000             :            &nycopy,
    1001             :            &np,
    1002             :            &nc,
    1003             :            suppstor,
    1004             :            &csize,
    1005             :            &csamp,
    1006             :            &wcsize,
    1007             :            convstor,
    1008             :            cmapstor,
    1009             :            pmapstor,
    1010             :                   (sumwgt[icounter]).getStorage(del), 
    1011             :                   &x0, &y0, &nxsub, &nysub, &rbeg, &rend, locstor, offstor,
    1012             :                  phasorstor);
    1013             :     }
    1014             :     }//end pragma parallel
    1015         200 :     if(dopsf && (nth > 4))
    1016           0 :       tweakGridSector(nx, ny, ixsub, iysub);
    1017         200 :     timegrid_p+=tim.real();
    1018             : 
    1019       13000 :     for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1020       12800 :       sumWeight=sumWeight+sumwgt[icounter];
    1021             :     }    
    1022         200 :     griddedData.putStorage(gridstor, gridcopy);
    1023             :     
    1024             :   }
    1025             :   else{
    1026        5836 :     DComplex *gridstor=griddedData2.getStorage(gridcopy);
    1027        5836 : #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)
    1028             :     {
    1029             : #pragma omp for  schedule(dynamic)    
    1030             :     for(icounter=0; icounter < ixsub*iysub; ++icounter){
    1031             :       
    1032             :       Int x0=xsect(icounter);
    1033             :       Int y0=ysect(icounter);
    1034             :       Int nxsub=nxsect(icounter);
    1035             :       Int nysub=nysect(icounter);
    1036             : 
    1037             :       sectgwgridd(uvwstor,
    1038             :            datStorage,
    1039             :            &nvp,
    1040             :            &nvc,
    1041             :            &idopsf,
    1042             :            flagstor,
    1043             :            rowflagstor,
    1044             :            wgtStorage,
    1045             :            &nvisrow,
    1046             :            gridstor,
    1047             :            &nxcopy,
    1048             :            &nycopy,
    1049             :            &np,
    1050             :            &nc,
    1051             :            suppstor,
    1052             :            &csize,
    1053             :            &csamp,
    1054             :            &wcsize,
    1055             :            convstor,
    1056             :            cmapstor,
    1057             :            pmapstor,
    1058             :                   (sumwgt[icounter]).getStorage(del), 
    1059             :                   &x0, &y0, &nxsub, &nysub, &rbeg, &rend, locstor, offstor,
    1060             :                  phasorstor);
    1061             :     }
    1062             :     }//end pragma parallel
    1063        5836 :     if(dopsf && (nth > 4))
    1064         918 :       tweakGridSector(nx, ny, ixsub, iysub);
    1065        5836 :     timegrid_p+=tim.real();
    1066             : 
    1067      207380 :     for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1068      201544 :       sumWeight=sumWeight+sumwgt[icounter];
    1069             :     }
    1070        5836 :     griddedData2.putStorage(gridstor, gridcopy);
    1071             :   }
    1072        6036 :   uvw.freeStorage(uvwstor, uvwcopy);
    1073        6036 :   convFunc.freeStorage(convstor, convcopy);
    1074             :   
    1075        6036 :   if(!dopsf)
    1076        3883 :     data.freeStorage(datStorage, isCopy);
    1077        6036 :   elWeight.freeStorage(wgtStorage,iswgtCopy);
    1078        6036 : }
    1079             : 
    1080             : 
    1081             : 
    1082        1730 : void WProjectFT::get(VisBuffer2& vb, Int row)
    1083             : {
    1084             :   
    1085             : 
    1086        1730 :   findConvFunction(*image, vb);
    1087             :   // If row is -1 then we pass through all rows
    1088             :   Int startRow, endRow, nRow;
    1089        1730 :   if (row==-1) {
    1090        1730 :     nRow=vb.nRows();
    1091        1730 :     startRow=0;
    1092        1730 :     endRow=nRow-1;
    1093             :     //vb.modelVisCube()=Complex(0.0,0.0);
    1094             :   } else {
    1095           0 :     nRow=1;
    1096           0 :     startRow=row;
    1097           0 :     endRow=row;
    1098             :     //vb.modelVisCube().xyPlane(row)=Complex(0.0,0.0);
    1099             :   }
    1100             :   
    1101             :   
    1102             : //Channel matching for the actual spectral window of buffer
    1103        1730 :     matchChannel(vb);
    1104             :  
    1105             :   //No point in reading data if its not matching in frequency
    1106        1730 :   if(max(chanMap)==-1)
    1107           0 :     return;
    1108             : 
    1109             : 
    1110             :   // Get the uvws in a form that Fortran can use
    1111        1730 :   Matrix<Double> uvw(negateUV(vb));
    1112        1730 :   Vector<Double> dphase(vb.nRows());
    1113        1730 :   dphase=0.0;
    1114             :    
    1115        1730 :   rotateUVW(uvw, dphase, vb);
    1116        1730 :   refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
    1117             : 
    1118             :   // This is the convention for dphase
    1119             :   // dphase*=-1.0;
    1120             :  
    1121             :   
    1122             :   //Check if ms has changed then cache new spw and chan selection
    1123             :   //if(vb.isNewMs())
    1124             :   //  matchAllSpwChans(vb);
    1125             :   //Here we redo the match or use previous match
    1126             :   
    1127             :   
    1128        1730 :   Cube<Complex> data;
    1129        1730 :   Cube<Int> flags;
    1130        1730 :   getInterpolateArrays(vb, data, flags);
    1131             : 
    1132             : 
    1133             :   
    1134             :   Complex *datStorage;
    1135             :   Bool isCopy;
    1136        1730 :   datStorage=data.getStorage(isCopy);
    1137             : 
    1138        1730 :   Vector<Int> rowFlags(vb.nRows());
    1139        1730 :   rowFlags=0;
    1140        1730 :   rowFlags(vb.flagRow())=true;
    1141        1730 :   if(!usezero_p) {
    1142      538560 :     for (Int rownr=startRow; rownr<=endRow; rownr++) {
    1143      537030 :       if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) rowFlags(rownr)=1;
    1144             :     }
    1145             :   }
    1146             :   
    1147        1730 :   Int nvp=data.shape()(0);
    1148        1730 :   Int nvc=data.shape()(1);
    1149        1730 :   Int nvisrow=data.shape()(2);
    1150        1730 :   Int nc=nchan;
    1151        1730 :   Int np=npol;
    1152        1730 :   Int nxp=nx;
    1153        1730 :   Int nyp=ny;
    1154        1730 :   Cube<Int> loc(3, nvc, nvisrow);
    1155        1730 :   Cube<Int> off(3, nvc, nRow);
    1156        1730 :   Int csamp=convSampling;
    1157        1730 :   Int csize=convSize;
    1158        1730 :   Int wcsize=wConvSize;
    1159        1730 :   Matrix<Complex> phasor(nvc, nRow);
    1160             :   Bool delphase;
    1161             :   Bool del;
    1162        1730 :   Complex * phasorstor=phasor.getStorage(delphase);
    1163        1730 :   const Double * visfreqstor=interpVisFreq_p.getStorage(del);
    1164        1730 :   const Double * scalestor=uvScale.getStorage(del);
    1165        1730 :   const Double * offsetstor=uvOffset.getStorage(del);
    1166        1730 :   Int * locstor=loc.getStorage(del);
    1167        1730 :   Int * offstor=off.getStorage(del);
    1168        1730 :   const Int * flagstor=flags.getStorage(del);
    1169        1730 :   const Int * rowflagstor=rowFlags.getStorage(del);
    1170        1730 :   const Double *dpstor=dphase.getStorage(del);
    1171             :   Bool uvwcopy; 
    1172        1730 :   const Double *uvwstor=uvw.getStorage(uvwcopy);
    1173             :   Bool gridcopy;
    1174        1730 :   const Complex *gridstor=griddedData.getStorage(gridcopy);
    1175             :   Bool convcopy;
    1176        1730 :   const Complex *convstor=convFunc.getStorage(convcopy);
    1177        1730 :   const Int* pmapstor=polMap.getStorage(del);
    1178        1730 :   const Int *cmapstor=chanMap.getStorage(del);
    1179        1730 :   const Int * suppstor=convSupport.getStorage(del);
    1180             :   Int irow;
    1181        1730 :   Int nth=1;
    1182             : #ifdef _OPENMP
    1183        1730 :   if(numthreads_p >0){
    1184           0 :     nth=min(numthreads_p, omp_get_max_threads());
    1185             :   }
    1186             :   else{   
    1187        1730 :     nth= omp_get_max_threads();
    1188             :   }
    1189             :   // nth=min(4,nth);
    1190             : #endif
    1191        1730 :   Int dow=1;
    1192        1730 :   Double cinv=Double(1.0)/C::c;
    1193        1730 :   #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) 
    1194             :   {
    1195             : 
    1196             : #pragma omp for schedule(dynamic)
    1197             :     for (irow=startRow; irow<=endRow; ++irow){
    1198             :       /*locateuvw(uvwstor,dpstor, visfreqstor, nvc, scalestor, offsetstor, csamp, 
    1199             :                 locstor, 
    1200             :                 offstor, phasorstor, irow, true);*/
    1201             :       locuvw(uvwstor, dpstor, visfreqstor, &nvc, scalestor, offsetstor, &csamp, locstor, offstor, phasorstor, &irow, &dow, &cinv);
    1202             :   }  
    1203             : 
    1204             :   }//end pragma parallel
    1205        1730 :   Int rbeg=startRow+1;
    1206        1730 :   Int rend=endRow+1;
    1207        1730 :   Int npart=nth;
    1208        1730 :   Timer tim;
    1209        1730 :   tim.mark();
    1210             :  
    1211        1730 :   Int ix=0;
    1212        1730 : #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)
    1213             :   {
    1214             : 
    1215             : #pragma omp for schedule(dynamic)
    1216             :     for (ix=0; ix< npart; ++ix){
    1217             :       rbeg=ix*(nvisrow/npart)+1;
    1218             :       rend=(ix != (npart-1)) ? (rbeg+(nvisrow/npart)-1) : (rbeg+(nvisrow/npart)+nvisrow%npart-1) ;
    1219             :       // cerr << "rbeg " << rbeg << " rend " << rend << " nRow " << nvisrow << endl;
    1220             :       sectdwgrid(uvwstor,
    1221             :                  datStorage,
    1222             :                  &nvp,
    1223             :                  &nvc,
    1224             :                  flagstor,
    1225             :                  rowflagstor,
    1226             :                  &nvisrow,
    1227             :                  gridstor,
    1228             :                  &nxp,
    1229             :                  &nyp,
    1230             :                  &np,
    1231             :                  &nc,
    1232             :                  suppstor,
    1233             :                  &csize,
    1234             :                  &csamp,
    1235             :                  &wcsize,
    1236             :                  convstor,
    1237             :                  cmapstor,
    1238             :                  pmapstor,
    1239             :                  &rbeg, &rend, locstor, offstor, phasorstor);
    1240             :     }
    1241             : 
    1242             :   }//end pragma parallel
    1243        1730 :   data.putStorage(datStorage, isCopy);
    1244        1730 :   uvw.freeStorage(uvwstor, uvwcopy);
    1245        1730 :   griddedData.freeStorage(gridstor, gridcopy);
    1246        1730 :   convFunc.freeStorage(convstor, convcopy);
    1247        1730 :    timedegrid_p+=tim.real();
    1248             : 
    1249        1730 :   interpolateFrequencyFromgrid(vb, data, FTMachine::MODEL);
    1250        1730 : }
    1251             : 
    1252             : 
    1253             : 
    1254             : // Finalize the FFT to the Sky. Here we actually do the FFT and
    1255             : // return the resulting image
    1256          78 : ImageInterface<Complex>& WProjectFT::getImage(Matrix<Float>& weights,
    1257             :                                               Bool normalize) 
    1258             : {
    1259             :   //AlwaysAssert(lattice, AipsError);
    1260          78 :   AlwaysAssert(image, AipsError);
    1261             :   
    1262          78 :   if((griddedData.nelements() ==0) && (griddedData2.nelements()==0)){
    1263           0 :      throw(AipsError("Programmer error ...request for image without right order of calls"));
    1264             :   }
    1265          78 :   logIO() << LogOrigin("WProjectFT", "getImage") << LogIO::NORMAL;
    1266             :   
    1267          78 :   weights.resize(sumWeight.shape());
    1268             :   
    1269          78 :   convertArray(weights, sumWeight);
    1270             :   
    1271             :   // If the weights are all zero then we cannot normalize
    1272             :   // otherwise we don't care.
    1273          78 :   if(max(weights)==0.0) {
    1274           0 :     if(normalize) {
    1275             :       logIO() << LogIO::SEVERE
    1276             :               << "No useful data in WProjectFT: weights all zero"
    1277           0 :               << LogIO::POST;
    1278             :     }
    1279             :     else {
    1280             :       logIO() << LogIO::WARN
    1281             :               << "No useful data in WProjectFT: weights all zero"
    1282           0 :               << LogIO::POST;
    1283             :     }
    1284             :   }
    1285             :   else {
    1286             :     logIO() << LogIO::DEBUGGING
    1287          78 :             << "Starting FFT and scaling of image" << LogIO::POST;
    1288             :     
    1289          78 :     if(useDoubleGrid_p){
    1290          77 :       ArrayLattice<DComplex> darrayLattice(griddedData2);
    1291          77 :       LatticeFFT::cfft2d(darrayLattice,false);
    1292          77 :       griddedData.resize(griddedData2.shape());
    1293          77 :       convertArray(griddedData, griddedData2);
    1294          77 :       SynthesisUtilMethods::getResource("mem peak in getImage");
    1295          77 :       griddedData2.resize();
    1296          77 :       arrayLattice = new ArrayLattice<Complex>(griddedData);
    1297          77 :       lattice=arrayLattice;
    1298          77 :     }else{
    1299           1 :       arrayLattice = new ArrayLattice<Complex>(griddedData);
    1300           1 :       lattice=arrayLattice;
    1301           1 :       LatticeFFT::cfft2d(*lattice,false);
    1302             : 
    1303             :     }
    1304             : 
    1305             : 
    1306          78 :     const IPosition latticeShape = lattice->shape();
    1307             :     
    1308             :     
    1309             :     {
    1310          78 :       Int inx = lattice->shape()(0);
    1311          78 :       Int iny = lattice->shape()(1);
    1312          78 :       Vector<Complex> correction(inx);
    1313          78 :       correction=Complex(1.0, 0.0);
    1314             : 
    1315          78 :       Int npixCorr= max(nx,ny);
    1316          78 :       Vector<Float> sincConv(npixCorr);
    1317       80778 :       for (Int ix=0;ix<npixCorr;ix++) {
    1318       80700 :         Float x=C::pi*Float(ix-npixCorr/2)/(Float(npixCorr)*Float(convSampling));
    1319       80700 :         if(ix==npixCorr/2) {
    1320          78 :           sincConv(ix)=1.0;
    1321             :         }
    1322             :         else {
    1323       80622 :           sincConv(ix)=sin(x)/x;
    1324             :         }
    1325             :       }
    1326             : 
    1327          78 :       IPosition cursorShape(4, inx, 1, 1, 1);
    1328          78 :       IPosition axisPath(4, 0, 1, 2, 3);
    1329          78 :       LatticeStepper lsx(lattice->shape(), cursorShape, axisPath);
    1330          78 :       LatticeIterator<Complex> lix(*lattice, lsx);
    1331      117298 :       for(lix.reset();!lix.atEnd();lix++) {
    1332      117220 :         Int pol=lix.position()(2);
    1333      117220 :         Int chan=lix.position()(3);
    1334      117220 :         if(weights(pol, chan)!=0.0) {
    1335      117220 :           Int iy=lix.position()(1);
    1336      117220 :           gridder->correctX1D(correction,iy);
    1337   160561820 :           for (Int ix=0;ix<nx;ix++) {
    1338   160444600 :             correction(ix)*=sincConv(ix)*sincConv(iy);
    1339             :           }
    1340      117220 :           lix.rwVectorCursor()/=correction;
    1341      117220 :           if(normalize) {
    1342         100 :             Complex rnorm(Float(inx)*Float(iny)/weights(pol,chan));
    1343         100 :             lix.rwCursor()*=rnorm;
    1344             :           }
    1345             :           else {
    1346      117120 :             Complex rnorm(Float(inx)*Float(iny));
    1347      117120 :             lix.rwCursor()*=rnorm;
    1348             :           }
    1349             :         }
    1350             :         else {
    1351           0 :           lix.woCursor()=0.0;
    1352             :         }
    1353             :       }
    1354          78 :     }
    1355             : 
    1356          78 :     if(!isTiled) {
    1357          78 :       LatticeLocker lock1 (*(image), FileLocker::Write);
    1358             :       // Check the section from the image BEFORE converting to a lattice 
    1359         156 :       IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2,
    1360         156 :                     (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
    1361          78 :       IPosition stride(4, 1);
    1362         156 :       IPosition trc(blc+image->shape()-stride);
    1363             :       
    1364             :       // Do the copy
    1365          78 :       image->put(griddedData(blc, trc));
    1366             :       //if(arrayLattice) delete arrayLattice; arrayLattice=0;
    1367          78 :       griddedData.resize(IPosition(1,0));
    1368          78 :     }
    1369          78 :   }
    1370          78 :   if(!lattice.null()) lattice=nullptr;
    1371          78 :   if(!arrayLattice.null()) lattice=nullptr;
    1372          78 :   griddedData.resize();
    1373          78 :   return *image;
    1374             : }
    1375             : 
    1376             : // Get weight image
    1377           0 : void WProjectFT::getWeightImage(ImageInterface<Float>& weightImage,
    1378             :                               Matrix<Float>& weights) 
    1379             : {
    1380             :   
    1381           0 :   logIO() << LogOrigin("WProjectFT", "getWeightImage") << LogIO::NORMAL;
    1382             :   
    1383           0 :   weights.resize(sumWeight.shape());
    1384           0 :   convertArray(weights,sumWeight);
    1385             :   
    1386           0 :   const IPosition latticeShape = weightImage.shape();
    1387             :   
    1388           0 :   Int inx=latticeShape(0);
    1389           0 :   Int iny=latticeShape(1);
    1390             :   
    1391           0 :   IPosition loc(2, 0);
    1392           0 :   IPosition cursorShape(4, inx, iny, 1, 1);
    1393           0 :   IPosition axisPath(4, 0, 1, 2, 3);
    1394           0 :   LatticeStepper lsx(latticeShape, cursorShape, axisPath);
    1395           0 :   LatticeIterator<Float> lix(weightImage, lsx);
    1396           0 :   for(lix.reset();!lix.atEnd();lix++) {
    1397           0 :     Int pol=lix.position()(2);
    1398           0 :     Int chan=lix.position()(3);
    1399           0 :     lix.rwCursor()=weights(pol,chan);
    1400             :   }
    1401           0 : }
    1402             : 
    1403           0 : Bool WProjectFT::toRecord(String& error,
    1404             :                           RecordInterface& outRec, Bool withImage, const String diskimage)
    1405             : {  
    1406             : 
    1407             :   /*
    1408             : 
    1409             :   CountedPtr<WPConvFunc> wpConvFunc_p;
    1410             :   */
    1411             : 
    1412             :   // Save the current WProjectFT object to an output state record
    1413           0 :   Bool retval = true;
    1414             :   //save the base class variables
    1415             :   //this is a memory hog and slow on saving and recovering...better to recompute convfunctions
    1416             :   /* Record wpconvrec;
    1417             :   if(wpConvFunc_p->toRecord(wpconvrec))
    1418             :     outRec.defineRecord("wpconvfunc", wpconvrec);
    1419             :   */
    1420           0 :    Float elpadd=padding_p;
    1421           0 :   if(toVis_p && withImage)
    1422           0 :     elpadd=1.0;
    1423           0 :   if(!FTMachine::toRecord(error, outRec, withImage, diskimage))
    1424           0 :     return false;
    1425             : 
    1426           0 :   outRec.define("uvscale", uvScale);
    1427           0 :   outRec.define("uvoffset", uvOffset);
    1428           0 :   outRec.define("istiled", isTiled);
    1429           0 :   outRec.define("cachesize", Int64(cachesize));
    1430           0 :   outRec.define("tilesize", tilesize);
    1431           0 :   outRec.define("maxabsdata", maxAbsData);
    1432           0 :   Vector<Int> center_loc(4), offset_loc(4);
    1433           0 :   for (Int k=0; k<4 ; k++){
    1434           0 :     center_loc(k)=centerLoc(k);
    1435           0 :     offset_loc(k)=offsetLoc(k);
    1436             :   }
    1437           0 :   outRec.define("centerloc", center_loc);
    1438           0 :   outRec.define("offsetloc", offset_loc);
    1439           0 :   outRec.define("padding", elpadd);
    1440           0 :   outRec.define("nwplanes", nWPlanes_p);
    1441           0 :   outRec.define("savedwscale", savedWScale_p);
    1442           0 :   outRec.define("usezero", usezero_p);
    1443             :   ///no need to save convfunc as it can be big and is recalculated anyways
    1444             :   ///outRec.define("convfunc", convFunc);
    1445           0 :   outRec.define("convsampling", convSampling);
    1446           0 :   outRec.define("convsize", convSize);
    1447           0 :   outRec.define("convsupport", convSupport);
    1448           0 :   outRec.define("convsizes", convSizes_p);
    1449           0 :   outRec.define("wconvsize", wConvSize);
    1450           0 :   outRec.define("lastindex", lastIndex_p);
    1451           0 :   outRec.define("minw", minW_p);
    1452           0 :   outRec.define("maxw", maxW_p);
    1453           0 :   outRec.define("rmsw", rmsW_p);
    1454             : 
    1455             : 
    1456             : 
    1457           0 :   return retval;
    1458           0 : }
    1459             : 
    1460           0 : Bool WProjectFT::fromRecord(String& error,
    1461             :                             const RecordInterface& inRec)
    1462             : {
    1463           0 :   if(!FTMachine::fromRecord(error, inRec))
    1464           0 :     return false;
    1465           0 :   machineName_p="WProjectFT";
    1466           0 :   Bool retval = true;
    1467           0 :   imageCache=0; lattice=0; arrayLattice=0;
    1468           0 :   inRec.get("uvscale", uvScale);
    1469           0 :   inRec.get("uvoffset", uvOffset);
    1470           0 :   inRec.get("istiled", isTiled);
    1471           0 :   cachesize=inRec.asInt64("cachesize");
    1472           0 :   inRec.get("tilesize", tilesize);
    1473           0 :   inRec.get("maxabsdata", maxAbsData);
    1474           0 :   Vector<Int> center_loc(4), offset_loc(4);
    1475           0 :   inRec.get("centerloc", center_loc);
    1476           0 :   inRec.get("offsetloc", offset_loc);
    1477           0 :   uInt ndim4 = 4;
    1478           0 :   centerLoc=IPosition(ndim4, center_loc(0), center_loc(1), center_loc(2), 
    1479           0 :                       center_loc(3));
    1480           0 :   offsetLoc=IPosition(ndim4, offset_loc(0), offset_loc(1), offset_loc(2), 
    1481           0 :                       offset_loc(3));
    1482           0 :   inRec.get("minw", minW_p);
    1483           0 :   inRec.get("maxw", maxW_p);
    1484           0 :   inRec.get("rmsw", rmsW_p);
    1485           0 :   if(inRec.isDefined("wpconvfunc")){
    1486           0 :     wpConvFunc_p=new WPConvFunc(inRec.asRecord("wpconvfunc"));
    1487             :   }
    1488             :   else{
    1489           0 :     wpConvFunc_p=new WPConvFunc(minW_p, maxW_p, rmsW_p);
    1490             :   }
    1491           0 :   inRec.get("padding", padding_p);
    1492           0 :   inRec.get("nwplanes", nWPlanes_p);
    1493           0 :   inRec.get("savedwscale", savedWScale_p);
    1494           0 :   inRec.get("usezero", usezero_p);
    1495             :   //inRec.get("convfunc", convFunc);
    1496           0 :   convFunc.resize();
    1497           0 :   inRec.get("convsampling", convSampling);
    1498           0 :   inRec.get("convsize", convSize);
    1499           0 :   inRec.get("convsupport", convSupport);
    1500           0 :   inRec.get("convsizes", convSizes_p);
    1501           0 :   inRec.get("wconvsize", wConvSize);
    1502           0 :   inRec.get("lastindex", lastIndex_p);
    1503           0 :   gridder=0;
    1504             :     ///setup some of the parameters
    1505           0 :   init();
    1506             :      
    1507             : 
    1508             :   
    1509           0 :   return retval;
    1510           0 : }
    1511             : 
    1512       15548 : void WProjectFT::ok() {
    1513       15548 :   AlwaysAssert(image, AipsError);
    1514       15548 : }
    1515             : 
    1516             : // Make a plain straightforward honest-to-God image. This returns
    1517             : // a complex image, without conversion to Stokes. The representation
    1518             : // is that required for the visibilities.
    1519             : //----------------------------------------------------------------------
    1520           0 : void WProjectFT::makeImage(FTMachine::Type type, 
    1521             :                          VisibilityIterator2& vi,
    1522             :                          ImageInterface<Complex>& theImage,
    1523             :                          Matrix<Float>& weight) {
    1524             :   
    1525             :   
    1526           0 :   logIO() << LogOrigin("WProjectFT", "makeImage") << LogIO::NORMAL;
    1527             :   
    1528           0 :   if(type==FTMachine::COVERAGE) {
    1529             :     logIO() << "Type COVERAGE not defined for Fourier transforms"
    1530           0 :             << LogIO::EXCEPTION;
    1531             :   }
    1532             :   
    1533             :   
    1534             :   
    1535             :   // Loop over all visibilities and pixels
    1536           0 :   VisBuffer2 *vb=vi.getVisBuffer();
    1537             :   
    1538             :   // Initialize put (i.e. transform to Sky) for this model
    1539           0 :   vi.origin();
    1540             :   
    1541           0 :   if(vb->polarizationFrame()==MSIter::Linear) {
    1542           0 :     StokesImageUtil::changeCStokesRep(theImage, StokesImageUtil::LINEAR);
    1543             :   }
    1544             :   else {
    1545           0 :     StokesImageUtil::changeCStokesRep(theImage, StokesImageUtil::CIRCULAR);
    1546             :   }
    1547             :   
    1548           0 :   initializeToSky(theImage,weight,*vb);
    1549             :   
    1550             :   // Loop over the visibilities, putting VisBuffers
    1551           0 :   for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
    1552           0 :     for (vi.origin(); vi.more(); vi.next()) {
    1553             :       
    1554           0 :       switch(type) {
    1555           0 :       case FTMachine::RESIDUAL:
    1556             :           //vb.visCube()=vb.correctedVisCube();
    1557           0 :           vb->setVisCube(vb->visCubeCorrected()-vb->visCubeModel());
    1558           0 :           put(*vb, -1, false);
    1559           0 :           break;
    1560           0 :       case FTMachine::MODEL:
    1561           0 :           vb->setVisCube(vb->visCubeModel());
    1562           0 :           put(*vb, -1, false);
    1563           0 :           break;
    1564           0 :       case FTMachine::CORRECTED:
    1565           0 :           vb->setVisCube(vb->visCubeCorrected());
    1566           0 :           put(*vb, -1, false);
    1567           0 :           break;
    1568           0 :       case FTMachine::PSF:
    1569           0 :           vb->setVisCube(Complex(1.0,0.0));
    1570           0 :           put(*vb, -1, true);
    1571           0 :           break;
    1572           0 :       case FTMachine::OBSERVED:
    1573             :       default:
    1574           0 :           put(*vb, -1, false);
    1575           0 :           break;
    1576             :       }
    1577             :     }
    1578             :   }
    1579           0 :   finalizeToSky();
    1580             :   // Normalize by dividing out weights, etc.
    1581           0 :   getImage(weight, true);
    1582           0 : }
    1583             : 
    1584             : 
    1585         142 : String WProjectFT::name() const {
    1586             : 
    1587         142 :   return machineName_p;
    1588             : 
    1589             : }
    1590           7 : void WProjectFT::wStat(vi::VisibilityIterator2& vi, Double& minW, Double& maxW, Double& rmsW){
    1591           7 :   VisBuffer2* vb= vi.getVisBuffer();
    1592           7 :     maxW=0.0;
    1593           7 :     minW=1e99;
    1594           7 :     Double nval=0;
    1595           7 :     rmsW=0.0;
    1596          28 :     for (vi.originChunks(); vi.moreChunks(); vi.nextChunk()) {
    1597         273 :       for (vi.origin();vi.more();vi.next()) {
    1598         252 :         maxW=max(maxW, max(abs(vb->uvw().row(2)*max(vb->getFrequencies(0))))/C::c);
    1599         252 :         minW=min(minW, min(abs(vb->uvw().row(2)*min(vb->getFrequencies(0))))/C::c);
    1600             :         ///////////some shenanigans as some compilers is confusing * operator for vector
    1601         252 :         Vector<Double> elw;
    1602         252 :         elw=vb->uvw().row(2);
    1603         252 :         elw*=vb->uvw().row(2);
    1604             :         //////////////////////////////////////////////////
    1605         252 :         rmsW+=sum(elw);
    1606             : 
    1607         252 :         nval+=Double(vb->nRows());
    1608         252 :       }
    1609             :     }
    1610           7 :     rmsW=sqrt(rmsW/Double(nval))*max(vb->getFrequencies(0))/C::c;
    1611             : 
    1612           7 :   }
    1613             : 
    1614             : 
    1615             : } // end of namespace refim
    1616             : } //# NAMESPACE CASA - END
    1617             : 

Generated by: LCOV version 1.16