LCOV - code coverage report
Current view: top level - synthesis/TransformMachines2 - MosaicFT.cc (source / functions) Hit Total Coverage
Test: casa_coverage.info Lines: 489 918 53.3 %
Date: 2023-10-25 08:47:59 Functions: 18 33 54.5 %

          Line data    Source code
       1             : //# MosaicFT.cc: Implementation of MosaicFT class
       2             : //# Copyright (C) 2002-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: 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             : #include <casacore/casa/Quanta/UnitMap.h>
      29             : #include <casacore/casa/Quanta/MVTime.h>
      30             : #include <casacore/casa/Quanta/UnitVal.h>
      31             : #include <casacore/measures/Measures/Stokes.h>
      32             : #include <casacore/measures/Measures/UVWMachine.h>
      33             : #include <casacore/coordinates/Coordinates/CoordinateSystem.h>
      34             : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
      35             : #include <casacore/coordinates/Coordinates/SpectralCoordinate.h>
      36             : #include <casacore/coordinates/Coordinates/StokesCoordinate.h>
      37             : #include <casacore/coordinates/Coordinates/Projection.h>
      38             : #include <casacore/ms/MeasurementSets/MSColumns.h>
      39             : #include <casacore/casa/BasicSL/Constants.h>
      40             : #include <casacore/scimath/Mathematics/FFTServer.h>
      41             : #include <synthesis/TransformMachines2/MosaicFT.h>
      42             : #include <synthesis/TransformMachines2/SimplePBConvFunc.h>
      43             : #include <synthesis/TransformMachines2/HetArrayConvFunc.h>
      44             : #include <synthesis/TransformMachines/PBMath.h>
      45             : #include <synthesis/TransformMachines2/VPSkyJones.h>
      46             : #include <casacore/scimath/Mathematics/RigidVector.h>
      47             : #include <msvis/MSVis/StokesVector.h>
      48             : #include <synthesis/TransformMachines/StokesImageUtil.h>
      49             : #include <msvis/MSVis/VisBuffer2.h>
      50             : #include <msvis/MSVis/VisibilityIterator2.h>
      51             : #include <casacore/images/Images/ImageInterface.h>
      52             : #include <casacore/images/Images/PagedImage.h>
      53             : #include <casacore/images/Images/SubImage.h>
      54             : #include <casacore/images/Regions/ImageRegion.h>
      55             : #include <casacore/images/Regions/WCBox.h>
      56             : #include <casacore/casa/Containers/Block.h>
      57             : #include <casacore/casa/Containers/Record.h>
      58             : #include <casacore/casa/Arrays/ArrayLogical.h>
      59             : #include <casacore/casa/Arrays/ArrayMath.h>
      60             : #include <casacore/casa/Arrays/Array.h>
      61             : #include <casacore/casa/Arrays/MaskedArray.h>
      62             : #include <casacore/casa/Arrays/Vector.h>
      63             : #include <casacore/casa/Arrays/Slice.h>
      64             : #include <casacore/casa/Arrays/Matrix.h>
      65             : #include <casacore/casa/Arrays/Cube.h>
      66             : #include <casacore/casa/Arrays/MatrixIter.h>
      67             : #include <casacore/casa/BasicSL/String.h>
      68             : #include <casacore/casa/Utilities/Assert.h>
      69             : #include <casacore/casa/Exceptions/Error.h>
      70             : #include <casacore/lattices/Lattices/ArrayLattice.h>
      71             : #include <casacore/lattices/Lattices/SubLattice.h>
      72             : #include <casacore/lattices/LRegions/LCBox.h>
      73             : #include <casacore/lattices/LEL/LatticeExpr.h>
      74             : #include <casacore/lattices/Lattices/LatticeCache.h>
      75             : #include <casacore/lattices/LatticeMath/LatticeFFT.h>
      76             : #include <casacore/lattices/Lattices/LatticeIterator.h>
      77             : #include <casacore/lattices/Lattices/LatticeStepper.h>
      78             : #include <casacore/casa/Utilities/CompositeNumber.h>
      79             : #include <casacore/casa/OS/Timer.h>
      80             : #include <casacore/casa/OS/HostInfo.h>
      81             : #include <sstream>
      82             : #ifdef _OPENMP
      83             : #include <omp.h>
      84             : #endif
      85             : using namespace casacore;
      86             : namespace casa { //# NAMESPACE CASA - BEGIN
      87             : namespace refim {//# namespace for imaging refactor
      88             : using namespace casacore;
      89             : using namespace casa;
      90             : using namespace casacore;
      91             : using namespace casa::refim;
      92             : 
      93         197 :   MosaicFT::MosaicFT(SkyJones* sj, MPosition mloc, String stokes,
      94             :                    Long icachesize, Int itilesize, 
      95         197 :                      Bool usezero, Bool useDoublePrec, Bool useConjConvFunc, Bool usePointing)
      96             :   : FTMachine(), sj_p(sj),
      97             :     imageCache(0),  cachesize(icachesize), tilesize(itilesize), gridder(nullptr),
      98             :     isTiled(false),
      99             :     maxAbsData(0.0), centerLoc(IPosition(4,0)), offsetLoc(IPosition(4,0)),
     100             :     mspc(0), msac(0), pointingToImage(0), usezero_p(usezero), convSampling(1),
     101         197 :     skyCoverage_p( ), machineName_p("MosaicFT"), stokes_p(stokes), useConjConvFunc_p(useConjConvFunc), usePointingTable_p(usePointing),timemass_p(0.0), timegrid_p(0.0), timedegrid_p(0.0)
     102             : {
     103         197 :   convSize=0;
     104         197 :   lastIndex_p=0;
     105         197 :   doneWeightImage_p=false;
     106         197 :   convWeightImage_p=0;
     107         197 :   pbConvFunc_p=new SimplePBConvFunc();
     108             :     
     109         197 :   mLocation_p=mloc;
     110         197 :   useDoubleGrid_p=useDoublePrec;  
     111             :   // We should get rid of the ms dependence in the constructor
     112             :   // not used
     113         197 : }
     114             : 
     115           0 : MosaicFT::MosaicFT(const RecordInterface& stateRec)
     116           0 :   : FTMachine()
     117             : {
     118             :   // Construct from the input state record
     119           0 :   String error;
     120           0 :   if (!fromRecord(error, stateRec)) {
     121           0 :     throw (AipsError("Failed to create MosaicFT: " + error));
     122             :   };
     123           0 : }
     124             : 
     125             : //---------------------------------------------------------------------- 
     126         266 : MosaicFT& MosaicFT::operator=(const MosaicFT& other)
     127             : {
     128         266 :   if(this!=&other) {
     129             : 
     130             :     //Do the base parameters
     131         266 :     FTMachine::operator=(other);
     132             :      
     133         266 :     convSampling=other.convSampling;
     134         266 :     sj_p=other.sj_p;
     135         266 :     imageCache=other.imageCache;
     136         266 :     cachesize=other.cachesize;
     137         266 :     tilesize=other.tilesize;
     138         266 :     isTiled=other.isTiled;
     139             :     //lattice=other.lattice;
     140         266 :     lattice=0;
     141             :     // arrayLattice=other.arrayLattice;
     142             :     // weightLattice=other.weightLattice;
     143             :     //if(arrayLattice) delete arrayLattice;
     144         266 :     arrayLattice=0;
     145             :     //if(weightLattice) delete weightLattice;
     146         266 :     weightLattice=0;
     147         266 :     maxAbsData=other.maxAbsData;
     148         266 :     centerLoc=other.centerLoc;
     149         266 :     offsetLoc=other.offsetLoc;
     150         266 :     pointingToImage=other.pointingToImage;
     151         266 :     usezero_p=other.usezero_p;
     152         266 :     doneWeightImage_p=other.doneWeightImage_p;
     153         266 :     pbConvFunc_p=other.pbConvFunc_p;
     154         266 :     stokes_p=other.stokes_p;
     155         266 :     if(!other.skyCoverage_p.null())
     156           0 :       skyCoverage_p=other.skyCoverage_p;
     157             :     else
     158         266 :       skyCoverage_p=0;
     159         266 :     if(other.convWeightImage_p !=0)
     160           0 :       convWeightImage_p=(TempImage<Complex> *)other.convWeightImage_p->cloneII();
     161             :     else
     162         266 :       convWeightImage_p=0;
     163         266 :     if(other.gridder==0)
     164         266 :       gridder.reset(nullptr);
     165             :     else{
     166           0 :       uvScale=other.uvScale;
     167           0 :       uvOffset=other.uvOffset;
     168           0 :       gridder.reset(new ConvolveGridder<Double, Complex>(IPosition(2, nx, ny),
     169           0 :                                                          uvScale, uvOffset,
     170           0 :                                                          "SF"));
     171             :           
     172             :     }
     173         266 :     useConjConvFunc_p=other.useConjConvFunc_p;
     174         266 :     usePointingTable_p=other.usePointingTable_p;
     175         266 :     timemass_p=other.timemass_p;
     176         266 :     timegrid_p=other.timegrid_p;
     177         266 :     timedegrid_p=other.timedegrid_p;
     178             :   };
     179         266 :   return *this;
     180             : };
     181             : 
     182             : //----------------------------------------------------------------------
     183         266 :   MosaicFT::MosaicFT(const MosaicFT& other): FTMachine(),machineName_p("MosaicFT")
     184             : {
     185         266 :   operator=(other);
     186         266 : }
     187             : 
     188             : //----------------------------------------------------------------------
     189             : //void MosaicFT::setSharingFT(MosaicFT& otherFT){
     190             : //  otherFT_p=&otherFT;
     191             : //}
     192         357 : void MosaicFT::init() {
     193             :   
     194             :   /* if((image->shape().product())>cachesize) {
     195             :     isTiled=true;
     196             :   }
     197             :   else {
     198             :     isTiled=false;
     199             :   }
     200             :   */
     201             :   //For now only isTiled false works.
     202         357 :   isTiled=false;
     203         357 :   nx    = image->shape()(0);
     204         357 :   ny    = image->shape()(1);
     205         357 :   npol  = image->shape()(2);
     206         357 :   nchan = image->shape()(3);
     207             : 
     208             : 
     209             :   //  if(skyCoverage_p==0){
     210             :   //    Double memoryMB=HostInfo::memoryTotal()/1024.0/(20.0);
     211             :   //    skyCoverage_p=new TempImage<Float> (IPosition(4,nx,ny,1,1),
     212             :   //                                    image->coordinates(), memoryMB);
     213             :     //Setting it to zero
     214             : //   (*skyCoverage_p)-=(*skyCoverage_p);
     215             : //  }
     216         357 :   sumWeight.resize(npol, nchan);
     217             :   
     218         357 :   convSupport=0;
     219             : 
     220         357 :   uvScale.resize(2);
     221         357 :   uvScale=0.0;
     222         357 :   uvScale(0)=Float(nx)*image->coordinates().increment()(0); 
     223         357 :   uvScale(1)=Float(ny)*image->coordinates().increment()(1); 
     224             :     
     225         357 :   uvOffset.resize(2);
     226         357 :   uvOffset(0)=nx/2;
     227         357 :   uvOffset(1)=ny/2;
     228             :   
     229         714 :   gridder.reset(new ConvolveGridder<Double, Complex>(IPosition(2, nx, ny),
     230         357 :                                                      uvScale, uvOffset,
     231         357 :                                                      "SF"));
     232             : 
     233             :   // Set up image cache needed for gridding. 
     234         357 :   if(imageCache) delete imageCache; imageCache=0;
     235             :   /*
     236             :   if(isTiled) {
     237             :     Float tileOverlap=0.5;
     238             :     tilesize=min(256,tilesize);
     239             :     IPosition tileShape=IPosition(4,tilesize,tilesize,npol,nchan);
     240             :     Vector<Float> tileOverlapVec(4);
     241             :     tileOverlapVec=0.0;
     242             :     tileOverlapVec(0)=tileOverlap;
     243             :     tileOverlapVec(1)=tileOverlap;
     244             :     Int tmpCacheVal=static_cast<Int>(cachesize);
     245             :     imageCache=new LatticeCache <Complex> (*image, tmpCacheVal, tileShape, 
     246             :                                            tileOverlapVec,
     247             :                                            (tileOverlap>0.0));
     248             :     
     249             :   }
     250             :   */
     251         357 : }
     252             : 
     253             : // This is nasty, we should use CountedPointers here.
     254         463 : MosaicFT::~MosaicFT() {
     255         463 :   if(imageCache) delete imageCache; imageCache=0;
     256             :   //  if(arrayLattice) delete arrayLattice; arrayLattice=0;
     257         463 : }
     258             : 
     259             : 
     260         240 : void MosaicFT::setConvFunc(CountedPtr<SimplePBConvFunc>& pbconvFunc){
     261             : 
     262             : 
     263         240 :   pbConvFunc_p=pbconvFunc;
     264             :   
     265             : 
     266         240 : }
     267             : 
     268          69 : CountedPtr<SimplePBConvFunc>& MosaicFT::getConvFunc(){
     269          69 :   return pbConvFunc_p;
     270             : }
     271             : 
     272       82283 : void MosaicFT::findConvFunction(const ImageInterface<Complex>& iimage,
     273             :                                 const vi::VisBuffer2& vb) {
     274             :   
     275             :   
     276             :   //oversample if image is small
     277             :   //But not more than 5000 pixels
     278       82283 :   convSampling=(max(nx, ny) < 50) ? 100: Int(ceil(5000.0/max(nx, ny)));
     279       82283 :   if(convSampling <1) 
     280           0 :     convSampling=1;
     281       82283 :   if(pbConvFunc_p.null())
     282           0 :     pbConvFunc_p=new SimplePBConvFunc();
     283       82283 :   if(sj_p)
     284       82283 :     pbConvFunc_p->setSkyJones(sj_p.get());
     285             :   ////TEST for HetArray only for now
     286       82283 :   if(pbConvFunc_p->name()=="HetArrayConvFunc"){
     287       68835 :     if(convSampling <10) 
     288       30452 :       convSampling=10;
     289       68835 :     AipsrcValue<Int>::find (convSampling, "mosaic.oversampling", 10);
     290             :   }
     291       82283 :   if((pbConvFunc_p->getVBUtil()).null()){
     292           0 :     if(vbutil_p.null()){
     293           0 :         vbutil_p=new VisBufferUtil(vb);
     294             :     }
     295           0 :     pbConvFunc_p->setVBUtil(vbutil_p);
     296             :   }
     297             :   //cerr << "NELEMS " << interpVisFreq_p.nelements() << "  lsr " << lsrFreq_p.nelements() << endl;
     298       82283 :   pbConvFunc_p->findConvFunction(iimage, vb, convSampling, interpVisFreq_p, convFunc, weightConvFunc_p, convSizePlanes_p, convSupportPlanes_p,
     299       82283 :                                  convPolMap_p, convChanMap_p, convRowMap_p, (useConjConvFunc_p && !toVis_p), MVDirection(-(movingDirShift_p.getAngle())), fixMovingSource_p);
     300             : 
     301             :   // cerr << "MAX of convFunc " << max(abs(convFunc)) << endl;
     302             :   //For now only use one size and support
     303       82283 :   if(convSizePlanes_p.nelements() ==0)
     304           0 :     convSize=0;
     305             :   else
     306       82283 :     convSize=max(convSizePlanes_p);
     307       82283 :   if(convSupportPlanes_p.nelements() ==0)
     308           0 :     convSupport=0;
     309             :   else
     310       82283 :     convSupport=max(convSupportPlanes_p);
     311             :                                  
     312       82283 : }
     313             : 
     314          81 : void MosaicFT::initializeToVis(ImageInterface<Complex>& iimage,
     315             :                                const vi::VisBuffer2& vb)
     316             : {
     317          81 :   image=&iimage;
     318          81 :   toVis_p=true;
     319          81 :   ok();
     320             :   
     321             :   //  if(convSize==0) {
     322          81 :     init();
     323             :     
     324             :     //  }
     325             :   
     326             :   // Initialize the maps for polarization and channel. These maps
     327             :   // translate visibility indices into image indices
     328          81 :   initMaps(vb);
     329          81 :   pbConvFunc_p->setVBUtil(vbutil_p);
     330          81 :   pbConvFunc_p->setUsePointing(usePointingTable_p);
     331             :  //make sure we rotate the first field too
     332          81 :   lastFieldId_p=-1;
     333          81 :   phaseShifter_p=new UVWMachine(*uvwMachine_p);
     334             :   //This is needed here as we need to know the grid correction before FFTing 
     335          81 :   findConvFunction(*image, vb);
     336             :   
     337          81 :   prepGridForDegrid();
     338             : 
     339          81 : }
     340             : 
     341             : 
     342          81 : void MosaicFT::prepGridForDegrid(){
     343             : 
     344             :   //For now isTiled=false
     345          81 :   isTiled=false;
     346          81 :   nx    = image->shape()(0);
     347          81 :   ny    = image->shape()(1);
     348          81 :   npol  = image->shape()(2);
     349          81 :   nchan = image->shape()(3);
     350             : 
     351         162 :   IPosition gridShape(4, nx, ny, npol, nchan);
     352          81 :   griddedData.resize(gridShape);
     353          81 :   griddedData=Complex(0.0);
     354             :   
     355         162 :   IPosition stride(4, 1);
     356         162 :   IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2,
     357         243 :                 (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
     358         243 :   IPosition trc(blc+image->shape()-stride);
     359             :     
     360         162 :   IPosition start(4, 0);
     361          81 :   griddedData(blc, trc) = image->getSlice(start, image->shape());
     362             :   
     363          81 :   image->clearCache();
     364             :     //if(arrayLattice) delete arrayLattice; arrayLattice=0;
     365          81 :   arrayLattice = new ArrayLattice<Complex>(griddedData);
     366          81 :   lattice=arrayLattice;
     367             :    {///UnDo the grid correction
     368          81 :       Int inx = lattice->shape()(0);
     369             :       //Int iny = lattice->shape()(1);
     370         162 :       Vector<Complex> correction(inx);
     371          81 :       correction=Complex(1.0, 0.0);
     372             : 
     373             :       // Int npixCorr= max(nx,ny);
     374         162 :       Vector<Float> sincConvX(nx);
     375       66433 :       for (Int ix=0;ix<nx;ix++) {
     376       66352 :         Float x=C::pi*Float(ix-nx/2)/(Float(nx)*Float(convSampling));
     377       66352 :         if(ix==nx/2) {
     378          81 :           sincConvX(ix)=1.0;
     379             :         }
     380             :         else {
     381       66271 :           sincConvX(ix)=sin(x)/x;
     382             :         }
     383             :       }
     384         162 :       Vector<Float> sincConvY(ny);
     385       66433 :       for (Int ix=0;ix<ny;ix++) {
     386       66352 :         Float x=C::pi*Float(ix-ny/2)/(Float(ny)*Float(convSampling));
     387       66352 :         if(ix==ny/2) {
     388          81 :           sincConvY(ix)=1.0;
     389             :         }
     390             :         else {
     391       66271 :           sincConvY(ix)=sin(x)/x;
     392             :         }
     393             :       }
     394             :  
     395         162 :        IPosition cursorShape(4, inx, 1, 1, 1);
     396         162 :       IPosition axisPath(4, 0, 1, 2, 3);
     397         162 :       LatticeStepper lsx(lattice->shape(), cursorShape, axisPath);
     398         162 :       LatticeIterator<Complex> lix(*lattice, lsx);
     399      149865 :       for(lix.reset();!lix.atEnd();lix++) {
     400             :         //Int pol=lix.position()(2);
     401             :         //Int chan=lix.position()(3);
     402             :         
     403      149784 :         Int iy=lix.position()(1);
     404             :         //gridder->correctX1D(correction,iy);
     405   157548664 :         for (Int ix=0;ix<nx;ix++) {
     406   157398880 :           correction(ix)=(sincConvX(ix)*sincConvY(iy));
     407             :         }
     408      149784 :         lix.rwVectorCursor()*=correction;
     409             :         
     410             :       }
     411             :   }
     412             :     
     413             :   
     414          81 :   logIO() << LogIO::DEBUGGING << "Starting FFT of image" << LogIO::POST;
     415             :    // Now do the FFT2D in place
     416          81 :   ft_p.c2cFFT(*lattice);
     417             :   ///////////////////////
     418             :   /*{
     419             :     CoordinateSystem ftCoords(image->coordinates());
     420             :     Int directionIndex=ftCoords.findCoordinate(Coordinate::DIRECTION);
     421             :     DirectionCoordinate dc=ftCoords.directionCoordinate(directionIndex);
     422             :     Vector<Bool> axes(2); axes(0)=true;axes(1)=true;
     423             :     Vector<Int> shape(2); shape(0)=griddedData.shape()(0) ;shape(1)=griddedData.shape()(1);
     424             :     Coordinate* ftdc=dc.makeFourierCoordinate(axes,shape);
     425             :     ftCoords.replaceCoordinate(*ftdc, directionIndex);
     426             :     delete ftdc; ftdc=0;
     427             :     PagedImage<Float> thisScreen(griddedData.shape(), ftCoords, String("MODEL_GRID_VIS"));
     428             :     thisScreen.put(amplitude(griddedData));
     429             :     }*/
     430             :   ////////////////////////
     431          81 :   logIO() << LogIO::DEBUGGING << "Finished FFT" << LogIO::POST;
     432             : 
     433             : 
     434             : 
     435          81 : }
     436             : 
     437             : 
     438          81 : void MosaicFT::finalizeToVis()
     439             : {
     440          81 :   logIO() << LogOrigin("MosaicFT", "finalizeToVis")  << LogIO::NORMAL;
     441          81 :   logIO()<< LogIO::NORMAL2 << "Time degrid " << timedegrid_p << LogIO::POST;
     442          81 :   timedegrid_p=0.0;
     443             :   
     444          81 :   if(!arrayLattice.null()) arrayLattice=0;
     445          81 :   if(!lattice.null()) lattice=0;
     446          81 :   griddedData.resize();
     447             : 
     448             :   /*
     449             :   if(isTiled) {
     450             :     
     451             :     logIO() << LogOrigin("MosaicFT", "finalizeToVis")  << LogIO::NORMAL;
     452             :     
     453             :     AlwaysAssert(imageCache, AipsError);
     454             :     AlwaysAssert(image, AipsError);
     455             :     ostringstream o;
     456             :     imageCache->flush();
     457             :     imageCache->showCacheStatistics(o);
     458             :     logIO() << o.str() << LogIO::POST;
     459             :   }
     460             :   */
     461          81 :   if(pointingToImage) delete pointingToImage; pointingToImage=0;
     462          81 : }
     463             : 
     464             : 
     465             : // Initialize the FFT to the Sky. Here we have to setup and initialize the
     466             : // grid. 
     467             : 
     468             : 
     469             : 
     470             : 
     471             : 
     472         276 : void MosaicFT::initializeToSky(ImageInterface<Complex>& iimage,
     473             :                                Matrix<Float>& weight,
     474             :                                const vi::VisBuffer2& vb)
     475             : {
     476             :   // image always points to the image
     477         276 :   image=&iimage;
     478         276 :   toVis_p=False;
     479             :   //  if(convSize==0) {
     480         276 :     init();
     481             :     
     482             :     //  }
     483             :   
     484             :   // Initialize the maps for polarization and channel. These maps
     485             :   // translate visibility indices into image indices
     486         276 :   initMaps(vb);
     487         276 :   pbConvFunc_p->setVBUtil(vbutil_p);
     488         276 :   pbConvFunc_p->setUsePointing(usePointingTable_p);
     489             :   //make sure we rotate the first field too
     490         276 :   lastFieldId_p=-1;
     491         276 :   phaseShifter_p=new UVWMachine(*uvwMachine_p);
     492             :   //findConvFunction(*image, vb);
     493             :   /*if((image->shape().product())>cachesize) {
     494             :     isTiled=true;
     495             :   }
     496             :   else {
     497             :     isTiled=false;
     498             :   }
     499             :   */
     500             :   //For now isTiled has to be false
     501         276 :   isTiled=false;
     502         276 :   nx    = image->shape()(0);
     503         276 :   ny    = image->shape()(1);
     504         276 :   npol  = image->shape()(2);
     505         276 :   nchan = image->shape()(3);
     506             : 
     507         276 :   sumWeight=0.0;
     508         276 :   weight.resize(sumWeight.shape());
     509         276 :   weight=0.0;
     510             :   
     511         276 :   image->clearCache();
     512             :   // Initialize for in memory or to disk gridding. lattice will
     513             :   // point to the appropriate Lattice, either the ArrayLattice for
     514             :   // in memory gridding or to the image for to disk gridding.
     515             :   /*if(isTiled) {
     516             :     imageCache->flush();
     517             :     image->set(Complex(0.0));
     518             :     lattice=CountedPtr<Lattice<Complex> >(image, false);
     519             :     if( !doneWeightImage_p && (convWeightImage_p==0)){
     520             :       
     521             :       convWeightImage_p=new  TempImage<Complex> (iimage.shape(), 
     522             :                                                  iimage.coordinates());
     523             : 
     524             : 
     525             : 
     526             : 
     527             :       convWeightImage_p->set(Complex(0.0));
     528             :       weightLattice=convWeightImage_p;
     529             : 
     530             :     }
     531             :     }
     532             :     else*/ 
     533             :   {
     534         552 :     IPosition gridShape(4, nx, ny, npol, nchan);
     535         276 :     if(!useDoubleGrid_p) {
     536           0 :         griddedData.resize(gridShape);
     537           0 :         griddedData=Complex(0.0);
     538             :       }
     539             :     else {
     540         276 :       griddedData2.resize(gridShape);
     541         276 :       griddedData2=DComplex(0.0);
     542             :     }
     543             :     //if(arrayLattice) delete arrayLattice; arrayLattice=0;
     544             :     //arrayLattice = new ArrayLattice<Complex>(griddedData);
     545             :     //lattice=arrayLattice;
     546             :       
     547         276 :     if( !doneWeightImage_p && (convWeightImage_p==0)){
     548             :      
     549             :       
     550             :  
     551         392 :       convWeightImage_p=new  TempImage<Complex> (iimage.shape(), 
     552         196 :                                                  iimage.coordinates());
     553         196 :       griddedWeight.resize(gridShape);
     554             :       /*IPosition stride(4, 1);
     555             :       IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2,
     556             :                     (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
     557             :       IPosition trc(blc+image->shape()-stride);
     558             :       
     559             :       griddedWeight(blc, trc).set(Complex(0.0));
     560             :       */
     561         196 :       if(useDoubleGrid_p){
     562         196 :         griddedWeight2.resize(gridShape);
     563         196 :         griddedWeight2=DComplex(0.0);
     564             :       }
     565             :       else{
     566           0 :         griddedWeight=Complex(0.0);
     567             :       }
     568             :       //if(weightLattice) delete weightLattice; weightLattice=0;
     569         196 :       weightLattice = new ArrayLattice<Complex>(griddedWeight);
     570             : 
     571             :     }
     572             : 
     573             :   }
     574             : 
     575             :   //cerr << "initializetosky lastfield " << lastFieldId_p << endl;
     576             :   // AlwaysAssert(lattice, AipsError);
     577             :   
     578         276 : }
     579             : 
     580           0 : void MosaicFT::reset(){
     581             :   //call the base class reset
     582           0 :   FTMachine::reset();
     583           0 :   doneWeightImage_p=false;
     584           0 :   convWeightImage_p=nullptr;
     585           0 :   pbConvFunc_p->reset();
     586           0 : }
     587             : 
     588         276 : void MosaicFT::finalizeToSky()
     589             : {
     590         276 :   logIO() << LogOrigin("MosaicFT", "finalizeToSky")  << LogIO::NORMAL;
     591         276 :   logIO() << LogIO::NORMAL2 << "time to massage data " << timemass_p << LogIO::POST;
     592         276 :   logIO() << LogIO::NORMAL2<< "time gridding " << timegrid_p << LogIO::POST;
     593         276 :    timemass_p=0.0;
     594         276 :    timegrid_p=0.0;
     595             :   // Now we flush the cache and report statistics
     596             :   // For memory based, we don't write anything out yet.
     597             :   /*if(isTiled) {
     598             :     logIO() << LogOrigin("MosaicFT", "finalizeToSky")  << LogIO::NORMAL;
     599             :     
     600             :     AlwaysAssert(image, AipsError);
     601             :     AlwaysAssert(imageCache, AipsError);
     602             :     imageCache->flush();
     603             :     ostringstream o;
     604             :     imageCache->showCacheStatistics(o);
     605             :     logIO() << o.str() << LogIO::POST;
     606             :   }
     607             :   */
     608             :   
     609             :   
     610         276 :   if(!doneWeightImage_p){
     611         196 :     if(useDoubleGrid_p){
     612         196 :       convertArray(griddedWeight, griddedWeight2);
     613             :       //Don't need the double-prec grid anymore...
     614         196 :       griddedWeight2.resize();
     615             :     }
     616         196 :     ft_p.c2cFFT(*weightLattice, false);
     617             :     //Get the stokes right
     618         392 :     CoordinateSystem coords=convWeightImage_p->coordinates();
     619         196 :     Int stokesIndex=coords.findCoordinate(Coordinate::STOKES);
     620         196 :     Int npol=1;
     621         392 :     Vector<Int> whichStokes(npol);
     622         196 :     if(stokes_p=="I" || stokes_p=="RR" || stokes_p=="LL" ||stokes_p=="XX" 
     623         196 :        || stokes_p=="YY" || stokes_p=="Q" || stokes_p=="U" || stokes_p=="V"){
     624         196 :       npol=1;
     625         196 :       whichStokes(0)=Stokes::type(stokes_p);
     626             :        // if single plane Q U or V are used...the weight should be the I weight
     627             :       //if(stokes_p=="Q" || stokes_p=="U" || stokes_p=="V")
     628             :       //whichStokes(0)=Stokes::type("I");
     629             :     }
     630           0 :     else if(stokes_p=="IV"){
     631           0 :       npol=2;
     632           0 :       whichStokes.resize(2);
     633           0 :       whichStokes(0)=Stokes::I;
     634           0 :       whichStokes(1)=Stokes::V;
     635             :     }
     636           0 :     else if(stokes_p=="QU"){
     637           0 :       npol=2;
     638           0 :       whichStokes.resize(2);
     639           0 :       whichStokes(0)=Stokes::Q;
     640           0 :       whichStokes(1)=Stokes::U;
     641             :     }
     642           0 :     else if(stokes_p=="RRLL"){
     643           0 :       npol=2;
     644           0 :       whichStokes.resize(2);
     645           0 :       whichStokes(0)=Stokes::RR;
     646           0 :       whichStokes(1)=Stokes::LL;
     647             :     }   
     648           0 :     else if(stokes_p=="XXYY"){
     649           0 :       npol=2;
     650           0 :       whichStokes.resize(2);
     651           0 :       whichStokes(0)=Stokes::XX;
     652           0 :       whichStokes(1)=Stokes::YY;
     653             :     }  
     654           0 :     else if(stokes_p=="IQU"){
     655           0 :       npol=3;
     656           0 :       whichStokes.resize(3);
     657           0 :       whichStokes(0)=Stokes::I;
     658           0 :       whichStokes(1)=Stokes::Q;
     659           0 :       whichStokes(2)=Stokes::U;
     660             :     }
     661           0 :     else if(stokes_p=="IQUV"){
     662           0 :       npol=4;
     663           0 :       whichStokes.resize(4);
     664           0 :       whichStokes(0)=Stokes::I;
     665           0 :       whichStokes(1)=Stokes::Q;
     666           0 :       whichStokes(2)=Stokes::U;
     667           0 :       whichStokes(3)=Stokes::V;
     668             :     } 
     669             :     
     670         392 :     StokesCoordinate newStokesCoord(whichStokes);
     671         196 :     coords.replaceCoordinate(newStokesCoord, stokesIndex);
     672         392 :     IPosition imshp=convWeightImage_p->shape();
     673         196 :     imshp(2)=npol;
     674             : 
     675             : 
     676         196 :     skyCoverage_p=new TempImage<Float> (imshp, coords,1.0);
     677         392 :     IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2,
     678         588 :                     (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
     679         392 :     IPosition stride(4, 1);
     680         588 :     IPosition trc(blc+image->shape()-stride);
     681             :     
     682             :     // Do the copy
     683         196 :     IPosition start(4, 0);
     684         196 :     convWeightImage_p->put(griddedWeight(blc, trc));
     685         196 :     StokesImageUtil::ToStokesPSF(*skyCoverage_p, *convWeightImage_p);
     686         196 :     if(npol>1){
     687             :       // only the I get it right Q and U or V may end up with zero depending 
     688             :       // if RR or XX
     689           0 :       blc(0)=0; blc(1)=0; blc(3)=0;blc(2)=0;
     690           0 :       trc=skyCoverage_p->shape()-stride;
     691           0 :       trc(2)=0;
     692           0 :       SubImage<Float> isubim(*skyCoverage_p, Slicer(blc, trc, Slicer::endIsLast));
     693           0 :       for (Int k=1; k < npol; ++k){
     694           0 :         blc(2)=k; trc(2)=k;
     695           0 :         SubImage<Float> quvsubim(*skyCoverage_p, Slicer(blc, trc, Slicer::endIsLast), true);
     696           0 :         quvsubim.copyData(isubim);
     697             :       }
     698             : 
     699             :     }
     700             :     //Store this image in the pbconvfunc object as
     701             :     //it can be used for rescaling or shared by other ftmachines that use
     702             :     //this pbconvfunc
     703         196 :     pbConvFunc_p->setWeightImage(skyCoverage_p);
     704         196 :     if(convWeightImage_p) delete convWeightImage_p;
     705         196 :     convWeightImage_p=0;
     706         196 :     doneWeightImage_p=true;
     707             : 
     708             :     /*
     709             :     if(0){
     710             :       PagedImage<Float> thisScreen(skyCoverage_p->shape(), 
     711             :                                    skyCoverage_p->coordinates(), "Screen");
     712             :       thisScreen.copyData(*skyCoverage_p);
     713             :     }
     714             :     */
     715             : 
     716             :   }
     717             : 
     718         276 :   if(!weightLattice.null()) weightLattice=0;
     719         276 :   griddedWeight.resize();
     720         276 :   if(pointingToImage) delete pointingToImage; pointingToImage=0;
     721         276 : }
     722             : 
     723           0 : void MosaicFT::setWeightImage(CountedPtr<ImageInterface<Float> >& wgtimage){
     724           0 :   IPosition shp=wgtimage->shape();
     725           0 :   CoordinateSystem cs=wgtimage->coordinates();
     726           0 :   CountedPtr<TempImage<Float> > wgtim=new TempImage<Float>(shp, cs);
     727           0 :   wgtim->copyData(*(wgtimage));
     728           0 :   skyCoverage_p=wgtim;
     729           0 :   Record rec=skyCoverage_p->miscInfo();
     730             :   //For mosaicFTNew it has the nx*ny factor already in
     731           0 :   rec.define("isscaled", True);
     732           0 :   skyCoverage_p->setMiscInfo(rec);
     733             :   //cerr << "IN SET " << max(wgtimage->get()) << endl;
     734           0 :   pbConvFunc_p->setWeightImage(skyCoverage_p);
     735           0 :   doneWeightImage_p=true;
     736           0 : }
     737             : 
     738           0 : Array<Complex>* MosaicFT::getDataPointer(const IPosition& centerLoc2D,
     739             :                                          Bool readonly) {
     740             :   Array<Complex>* result;
     741             :   // Is tiled: get tiles and set up offsets
     742           0 :   centerLoc(0)=centerLoc2D(0);
     743           0 :   centerLoc(1)=centerLoc2D(1);
     744           0 :   result=&imageCache->tile(offsetLoc,centerLoc, readonly);
     745           0 :   gridder->setOffset(IPosition(2, offsetLoc(0), offsetLoc(1)));
     746           0 :   return result;
     747             : }
     748             : 
     749             : #define NEED_UNDERSCORES
     750             : #if defined(NEED_UNDERSCORES)
     751             : #define sectgmoss2 sectgmoss2_
     752             : #define gmoss2 gmoss2_
     753             : #define sectgmosd2 sectgmosd2_
     754             : #define gmosd2 gmosd2_
     755             : #define sectdmos2 sectdmos2_
     756             : #define dmos2 dmos2_
     757             : #define gmoswgtd gmoswgtd_
     758             : #define gmoswgts gmoswgts_
     759             : #define locuvw locuvw_
     760             : #endif
     761             : 
     762             : extern "C" { 
     763             :   void locuvw(const Double*, const Double*, const Double*, const Int*, const Double*, const Double*, const Int*, 
     764             :               Int*, Int*, Complex*, const Int*, const Int*, const Double*);
     765             :   void gmoswgtd(const Int*/*nvispol*/, const Int*/*nvischan*/,
     766             :                 const Int*/*flag*/, const Int*/*rflag*/, const Float*/*weight*/, const Int*/*nrow*/, 
     767             :                 const Int*/*nx*/, const Int*/*ny*/, const Int*/*npol*/, const Int*/*nchan*/, 
     768             :                 const Int*/*support*/, const Int*/*convsize*/, const Int*/*sampling*/, 
     769             :                 const Int*/*chanmap*/, const Int*/*polmap*/,
     770             :                 DComplex* /*weightgrid*/, Double* /*sumwt*/, const Complex*/*convweight*/, const Int*/*convplanemap*/, 
     771             :                 const Int*/*convchanmap*/,  const Int*/*convpolmap*/, 
     772             :                 const Int*/*nconvplane*/, const Int*/*nconvchan*/, const Int*/*nconvpol*/, const Int*/*rbeg*/, 
     773             :                 const Int*/*rend*/, const Int*/*loc*/, const Int*/*off*/, const Complex*/*phasor*/);
     774             :  void gmoswgts(const Int*/*nvispol*/, const Int*/*nvischan*/,
     775             :                 const Int*/*flag*/, const Int*/*rflag*/, const Float*/*weight*/, const Int*/*nrow*/, 
     776             :                 const Int*/*nx*/, const Int*/*ny*/, const Int*/*npol*/, const Int*/*nchan*/, 
     777             :                 const Int*/*support*/, const Int*/*convsize*/, const Int*/*sampling*/, 
     778             :                 const Int*/*chanmap*/, const Int*/*polmap*/,
     779             :                Complex* /*weightgrid*/, Double*/*sumwt*/, const Complex*/*convweight*/, const Int*/*convplanemap*/, 
     780             :                 const Int*/*convchanmap*/,  const Int*/*convpolmap*/, 
     781             :                 const Int*/*nconvplane*/, const Int*/*nconvchan*/, const Int*/*nconvpol*/, const Int*/*rbeg*/, 
     782             :                 const Int*/*rend*/, const Int*/*loc*/, const Int*/*off*/, const Complex*/*phasor*/);
     783             :   void sectgmosd2(const Complex* /*values*/,
     784             :                   Int* /*nvispol*/, Int* /*nvischan*/,
     785             :                   Int* /*dopsf*/, const Int* /*flag*/, const Int* /*rflag*/, const Float* /*weight*/,
     786             :                   Int* /* nrow*/, DComplex* /*grid*/, Int* /*nx*/, Int* /*ny*/, Int * /*npol*/, Int * /*nchan  */,
     787             :                   Int*/*support*/, Int*/*convsize*/, Int*/*sampling*/, const Complex*/*convfunc*/,
     788             :                   const Int*/*chanmap*/, const Int*/*polmap*/,
     789             :                   Double*/*sumwgt*/, const Int*/*convplanemap*/,
     790             :                   const Int*/*convchanmap*/, const Int*/*convpolmap*/, 
     791             :                   Int*/*nconvplane*/, Int*/*nconvchan*/, Int* /*nconvpol*/,
     792             :                   const Int*/*x0*/,const Int*/*y0*/, const Int*/*nxsub*/, const Int*/*nysub*/, const Int*/*rbeg*/, 
     793             :                   const Int* /*rend*/, const Int*/*loc*/, const Int* /*off*/, const Complex*/*phasor*/);     
     794             : 
     795             :  void sectgmoss2(const Complex* /*values*/,
     796             :                   Int* /*nvispol*/, Int* /*nvischan*/,
     797             :                   Int* /*dopsf*/, const Int* /*flag*/, const Int* /*rflag*/, const Float* /*weight*/,
     798             :                   Int* /* nrow*/, Complex* /*grid*/, Int* /*nx*/, Int* /*ny*/, Int * /*npol*/, Int * /*nchan  */,
     799             :                   Int*/*support*/, Int*/*convsize*/, Int*/*sampling*/, const Complex*/*convfunc*/,
     800             :                   const Int*/*chanmap*/, const Int*/*polmap*/,
     801             :                   Double*/*sumwgt*/, const Int*/*convplanemap*/,
     802             :                   const Int*/*convchanmap*/, const Int*/*convpolmap*/, 
     803             :                   Int*/*nconvplane*/, Int*/*nconvchan*/, Int* /*nconvpol*/,
     804             :                   const Int*/*x0*/,const Int*/*y0*/, const Int*/*nxsub*/, const Int*/*nysub*/, const Int*/*rbeg*/, 
     805             :                   const Int* /*rend*/, const Int*/*loc*/, const Int* /*off*/, const Complex*/*phasor*/);     
     806             : 
     807             : 
     808             :   void gmosd2(const Double*,
     809             :               Double*,
     810             :               const Complex*,
     811             :               Int*,
     812             :               Int*,
     813             :               Int*,
     814             :               const Int*,
     815             :               const Int*,
     816             :               const Float*,
     817             :               Int*,
     818             :               Int*,
     819             :               Double*,
     820             :               Double*,
     821             :               DComplex*,
     822             :               Int*,
     823             :               Int*,
     824             :               Int *,
     825             :               Int *,
     826             :               const Double*,
     827             :               const Double*,
     828             :               Int*,
     829             :               Int*,
     830             :               Int*,
     831             :               const Complex*,
     832             :               Int*,
     833             :               Int*,
     834             :               Double*,
     835             :               DComplex*,
     836             :               Complex*,
     837             :               Int*,
     838             :               Int*,
     839             :               Int*,Int*, Int*, Int*, Int*);
     840             :   /*  void gmoss(const Double*,
     841             :               Double*,
     842             :               const Complex*,
     843             :               Int*,
     844             :               Int*,
     845             :               Int*,
     846             :               const Int*,
     847             :               const Int*,
     848             :               const Float*,
     849             :               Int*,
     850             :               Int*,
     851             :               Double*,
     852             :               Double*,
     853             :               Complex*,
     854             :               Int*,
     855             :               Int*,
     856             :               Int *,
     857             :               Int *,
     858             :               const Double*,
     859             :               const Double*,
     860             :               Int*,
     861             :               Int*,
     862             :               Int*,
     863             :               const Complex*,
     864             :               Int*,
     865             :               Int*,
     866             :               Double*,
     867             :               Complex*,
     868             :               Complex*,
     869             :               Int*,
     870             :               Int*,
     871             :               Int*);
     872             :   */
     873             :     void gmoss2(const Double*,
     874             :               Double*,
     875             :               const Complex*,
     876             :               Int*,
     877             :               Int*,
     878             :               Int*,
     879             :               const Int*,
     880             :               const Int*,
     881             :               const Float*,
     882             :               Int*, //10
     883             :               Int*,
     884             :               Double*,
     885             :               Double*,
     886             :               Complex*,
     887             :               Int*,
     888             :               Int*,
     889             :               Int *,
     890             :               Int *,
     891             :               const Double*,
     892             :               const Double*, //20
     893             :               Int*,
     894             :               Int*,
     895             :               Int*,
     896             :               const Complex*,
     897             :               Int*,
     898             :               Int*,
     899             :               Double*,
     900             :               Complex*,
     901             :               Complex*,
     902             :               Int*, //30
     903             :               Int*,
     904             :               Int*, Int*, Int*, Int*, Int*);
     905             : 
     906             :   /* void dmos(const Double*,
     907             :               Double*,
     908             :               Complex*,
     909             :               Int*,
     910             :               Int*,
     911             :               const Int*,
     912             :               const Int*,
     913             :               Int*,
     914             :               Int*,
     915             :             Double*, //10
     916             :               Double*,
     917             :               const Complex*,
     918             :               Int*,
     919             :               Int*,
     920             :               Int *,
     921             :               Int *,
     922             :               const Double*,
     923             :               const Double*,
     924             :               Int*,
     925             :             Int*,//20
     926             :               Int*,
     927             :               const Complex*,
     928             :               Int*,
     929             :               Int*,
     930             :               Int*,
     931             :               Int*);
     932             :   */
     933             : 
     934             :   void dmos2(const Double*,
     935             :               Double*,
     936             :               Complex*,
     937             :               Int*,
     938             :               Int*,
     939             :               const Int*,
     940             :               const Int*,
     941             :               Int*,
     942             :               Int*,
     943             :               Double*,
     944             :               Double*,
     945             :               const Complex*,
     946             :               Int*,
     947             :               Int*,
     948             :               Int *,
     949             :               Int *,
     950             :               const Double*,
     951             :               const Double*,
     952             :               Int*,
     953             :               Int*,
     954             :               Int*,
     955             :               const Complex*,
     956             :               Int*,
     957             :               Int*,
     958             :               Int*,
     959             :               Int*, Int*, Int*, Int*, Int*);
     960             :   void sectdmos2(Complex*,
     961             :               Int*,
     962             :               Int*,
     963             :               const Int*,
     964             :               const Int*,
     965             :                  Int*,
     966             :               const Complex*,
     967             :               Int*,
     968             :               Int*,
     969             :               Int *,
     970             :                  Int *,
     971             :               Int*,
     972             :               Int*,
     973             :               Int*,
     974             :               const Complex*,
     975             :               const Int*,
     976             :               const Int*,
     977             :               const Int*,
     978             :               const  Int*, 
     979             :               const Int*, 
     980             :               Int*, Int*, Int*,
     981             :                  //rbeg
     982             :                  const Int*,
     983             :                  const Int*,
     984             :                  const Int*,
     985             :                  const Int*,
     986             :                  const Complex*);
     987             : 
     988             :              
     989             : 
     990             : }
     991       62621 : void MosaicFT::put(const vi::VisBuffer2& vb, Int row, Bool dopsf,
     992             :                    FTMachine::Type type)
     993             : {
     994             : 
     995             : 
     996             :   
     997             :   
     998       62621 :   Timer tim;
     999       62621 :   tim.mark();
    1000             :  
    1001       62621 :   matchChannel(vb);
    1002             :  
    1003             : 
    1004             :   //cerr << "CHANMAP " << chanMap << endl;
    1005             :   //No point in reading data if its not matching in frequency
    1006       62621 :   if(max(chanMap)==-1)
    1007           0 :     return;
    1008             : 
    1009             :   //const Matrix<Float> *imagingweight;
    1010             :   //imagingweight=&(vb.imagingWeight());
    1011       62621 :   Matrix<Float> imagingweight;
    1012       62621 :   getImagingWeight(imagingweight, vb);
    1013             : 
    1014       62621 :   if(dopsf) type=FTMachine::PSF;
    1015             : 
    1016       62621 :   Cube<Complex> data;
    1017             :   //Fortran gridder need the flag as ints 
    1018       62621 :   Cube<Int> flags;
    1019       62621 :   Matrix<Float> elWeight;
    1020       62621 :   interpolateFrequencyTogrid(vb, imagingweight,data, flags, elWeight, type);
    1021             :   
    1022             :  
    1023             : 
    1024             :   Bool iswgtCopy;
    1025             :   const Float *wgtStorage;
    1026       62621 :   wgtStorage=elWeight.getStorage(iswgtCopy);
    1027             : 
    1028             : 
    1029             :   
    1030             : 
    1031             :   Bool isCopy;
    1032       62621 :   const Complex *datStorage=0;
    1033             : 
    1034             :   // cerr << "dopsf " << dopsf << " isWeightCopy " << iswgtCopy << "  " << wgtStorage<< endl;
    1035       62621 :   if(!dopsf)
    1036       38608 :     datStorage=data.getStorage(isCopy);
    1037             :     
    1038             :   
    1039             :   // If row is -1 then we pass through all rows
    1040             :   Int startRow, endRow, nRow;
    1041       62621 :   if (row==-1) {
    1042       62621 :     nRow=vb.nRows();
    1043       62621 :     startRow=0;
    1044       62621 :     endRow=nRow-1;
    1045             :   } else {
    1046           0 :     nRow=1;
    1047           0 :     startRow=row;
    1048           0 :     endRow=row;
    1049             :   }
    1050             :   
    1051             :   // Get the uvws in a form that Fortran can use and do that
    1052             :   // necessary phase rotation. 
    1053       62621 :   Matrix<Double> uvw(negateUV(vb));
    1054       62621 :   Vector<Double> dphase(vb.nRows());
    1055       62621 :   dphase=0.0;
    1056             :  
    1057       62621 :   doUVWRotation_p=true;
    1058       62621 :   girarUVW(uvw, dphase, vb);
    1059       62621 :   refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
    1060             :   // This needs to be after the interp to get the interpolated channels
    1061             :   //Also has to be after rotateuvw in case tracking is on
    1062       62621 :   findConvFunction(*image, vb);
    1063             :   //nothing to grid here as the pointing resulted in a zero support convfunc
    1064       62621 :   if(convSupport <= 0)
    1065           0 :     return;
    1066             :   
    1067             :   // Get the pointing positions. This can easily consume a lot 
    1068             :   // of time thus we are for now assuming a field per 
    1069             :   // vb chunk...need to change that accordingly if we start using
    1070             :   // multiple pointings per vb.
    1071             :   //Warning 
    1072             : 
    1073             :   // Take care of translation of Bools to Integer
    1074       62621 :   Int idopsf=0;
    1075       62621 :   if(dopsf) idopsf=1;
    1076             :   
    1077             :   
    1078      125242 :   Vector<Int> rowFlags(vb.nRows());
    1079       62621 :   rowFlags=0;
    1080       62621 :   rowFlags(vb.flagRow())=true;
    1081       62621 :   if(!usezero_p) {
    1082    13725185 :     for (Int rownr=startRow; rownr<=endRow; rownr++) {
    1083    13662564 :       if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) rowFlags(rownr)=1;
    1084             :     }
    1085             :   }
    1086             :   
    1087             :   
    1088             : 
    1089             : 
    1090             :   //Tell the gridder to grid the weights too ...need to do that once only
    1091             :   //Int doWeightGridding=1;
    1092             :   //if(doneWeightImage_p)
    1093             :   //  doWeightGridding=-1;
    1094             :   Bool del;
    1095             :   //    IPosition s(flags.shape());
    1096       62621 :   const IPosition& fs=flags.shape();
    1097             :   //cerr << "flags shape " << fs << endl;
    1098      125242 :   std::vector<Int>s(fs.begin(), fs.end());
    1099       62621 :   Int nvp=s[0];
    1100       62621 :   Int nvc=s[1];
    1101       62621 :   Int nvisrow=s[2];
    1102       62621 :   Int csamp=convSampling;
    1103             :   Bool uvwcopy; 
    1104       62621 :   const Double *uvwstor=uvw.getStorage(uvwcopy);
    1105             :   Bool gridcopy;
    1106             :   Bool convcopy;
    1107             :   Bool wconvcopy;
    1108       62621 :   const Complex *convstor=convFunc.getStorage(convcopy);
    1109       62621 :   const Complex *wconvstor=weightConvFunc_p.getStorage(wconvcopy);
    1110       62621 :   Int nPolConv=convFunc.shape()[2];
    1111       62621 :   Int nChanConv=convFunc.shape()[3];
    1112       62621 :   Int nConvFunc=convFunc.shape()(4);
    1113             :   Bool weightcopy;
    1114             :   ////////**************************
    1115      125242 :   Cube<Int> loc(2, nvc, nRow);
    1116      125242 :   Cube<Int> off(2, nvc, nRow);
    1117      125242 :   Matrix<Complex> phasor(nvc, nRow);
    1118             :   Bool delphase;
    1119       62621 :   Complex * phasorstor=phasor.getStorage(delphase);
    1120       62621 :   const Double * visfreqstor=interpVisFreq_p.getStorage(del);
    1121       62621 :   const Double * scalestor=uvScale.getStorage(del);
    1122       62621 :   const Double * offsetstor=uvOffset.getStorage(del);
    1123       62621 :   Int * locstor=loc.getStorage(del);
    1124       62621 :   Int * offstor=off.getStorage(del);
    1125       62621 :   const Double *dpstor=dphase.getStorage(del);
    1126             :   Int irow;
    1127       62621 :   Int nth=1;
    1128             : #ifdef _OPENMP
    1129       62621 :   if(numthreads_p >0){
    1130           0 :     nth=min(numthreads_p, omp_get_max_threads());
    1131             :   }
    1132             :   else{   
    1133       62621 :     nth= omp_get_max_threads();
    1134             :   }
    1135             :   //nth=min(4,nth);
    1136             : #endif
    1137       62621 :   Double cinv=Double(1.0)/C::c;
    1138             :  
    1139       62621 :   Int dow=0;
    1140       62621 : #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)  
    1141             : {
    1142             : #pragma omp for
    1143             :   for (irow=startRow; irow<=endRow;irow++){
    1144             :     /*locateuvw(uvwstor,dpstor, visfreqstor, nvc, scalestor, offsetstor, csamp, 
    1145             :               locstor, 
    1146             :               offstor, phasorstor, irow, false);*/
    1147             :     locuvw(uvwstor, dpstor, visfreqstor, &nvc, scalestor, offsetstor, &csamp, locstor, offstor, phasorstor, &irow, &dow, &cinv);
    1148             :   }  
    1149             : 
    1150             :  }//end pragma parallel
    1151             : 
    1152             : 
    1153             :  
    1154       62621 :  timemass_p +=tim.real();
    1155             :  Int  ixsub, iysub, icounter;
    1156       62621 :  ixsub=1;
    1157       62621 :  iysub=1;
    1158             :   //////***********************DEBUGGING
    1159             :   //nth=1;
    1160             :   ////////***************
    1161       62621 :   if (nth >3){
    1162           0 :     ixsub=8;
    1163           0 :     iysub=8; 
    1164             :   }
    1165       62621 :   else if(nth >1){
    1166           0 :      ixsub=2;
    1167           0 :      iysub=2; 
    1168             :   }
    1169       62621 :   Int rbeg=startRow+1;
    1170       62621 :   Int rend=endRow+1;
    1171      125242 :   Block<Matrix<Double> > sumwgt(ixsub*iysub);
    1172      125242 :   Vector<Double *> swgtptr(ixsub*iysub);
    1173      125242 :   Vector<Bool> swgtdel(ixsub*iysub);
    1174      125242 :   for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1175       62621 :     sumwgt[icounter].resize(sumWeight.shape());
    1176       62621 :     sumwgt[icounter].set(0.0);
    1177       62621 :     swgtptr[icounter]=sumwgt[icounter].getStorage(swgtdel(icounter));
    1178             :   }
    1179             :   //cerr << "done thread " << doneThreadPartition_p << "  " << ixsub*iysub << endl;
    1180       62621 :    if(doneThreadPartition_p < 0){
    1181         196 :     xsect_p.resize(ixsub*iysub);
    1182         196 :     ysect_p.resize(ixsub*iysub);
    1183         196 :     nxsect_p.resize(ixsub*iysub);
    1184         196 :     nysect_p.resize(ixsub*iysub);
    1185         392 :     for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1186         196 :       findGridSector(nx, ny, ixsub, iysub, 0, 0, icounter, xsect_p(icounter), ysect_p(icounter), nxsect_p(icounter), nysect_p(icounter), true);
    1187             :     }
    1188             :   }
    1189      125242 :    Vector<Int> xsect, ysect, nxsect, nysect;
    1190       62621 :    xsect=xsect_p; ysect=ysect_p; nxsect=nxsect_p; nysect=nysect_p;
    1191             :    //cerr << xsect.shape() << "  " << xsect << endl;
    1192       62621 :   const Int* pmapstor=polMap.getStorage(del);
    1193       62621 :   const Int* cmapstor=chanMap.getStorage(del);
    1194             : // Dummy sumwt for gridweight part
    1195      125242 :   Matrix<Double> dumSumWeight(npol, nchan);
    1196       62621 :   dumSumWeight=sumWeight;
    1197             :   Bool isDSWC;
    1198       62621 :   Double *dsumwtstor=dumSumWeight.getStorage(isDSWC);
    1199       62621 :   Int nc=nchan;
    1200       62621 :   Int np=npol;
    1201       62621 :   Int nxp=nx;
    1202       62621 :   Int nyp=ny;
    1203       62621 :   Int csize=convSize;
    1204       62621 :   const Int * flagstor=flags.getStorage(del);
    1205       62621 :   const Int * rowflagstor=rowFlags.getStorage(del);
    1206       62621 :   Int csupp=convSupport;
    1207       62621 :   const Int *convrowmapstor=convRowMap_p.getStorage(del);
    1208       62621 :   const Int *convchanmapstor=convChanMap_p.getStorage(del);
    1209       62621 :   const Int *convpolmapstor=convPolMap_p.getStorage(del);
    1210             :   ///
    1211             : 
    1212             :   
    1213             :   ////////***************************
    1214       62621 :   tim.mark(); 
    1215             : 
    1216       62621 :   if(useDoubleGrid_p) {
    1217       62621 :     DComplex *gridstor=griddedData2.getStorage(gridcopy);
    1218             :     
    1219       62621 : #pragma omp parallel default(none) private(icounter, del) firstprivate(idopsf, /*doWeightGridding,*/ datStorage, wgtStorage, flagstor, rowflagstor, convstor, wconvstor, pmapstor, cmapstor, gridstor,  csupp, nxp, nyp, np, nc,ixsub, iysub, rend, rbeg, csamp, csize, nvp, nvc, nvisrow, phasorstor, locstor, offstor, convrowmapstor, convchanmapstor, convpolmapstor, nPolConv, nChanConv, nConvFunc,xsect, ysect, nxsect, nysect) shared(swgtptr) 
    1220             :     {   
    1221             : #pragma omp for schedule(dynamic)      
    1222             :     for(icounter=0; icounter < ixsub*iysub; ++icounter){
    1223             :       Int x0=xsect(icounter);
    1224             :       Int y0=ysect(icounter);
    1225             :       Int nxsub=nxsect(icounter);
    1226             :       Int nysub=nysect(icounter);
    1227             :       
    1228             :       /*
    1229             :       ix= (icounter+1)-((icounter)/ixsub)*ixsub;
    1230             :       iy=(icounter)/ixsub+1;
    1231             :       y0=(nyp/iysub)*(iy-1)+1;
    1232             :       nysub=nyp/iysub;
    1233             :       if( iy == iysub) {
    1234             :         nysub=nyp-(nyp/iysub)*(iy-1);
    1235             :       }
    1236             :       x0=(nxp/ixsub)*(ix-1)+1;
    1237             :       nxsub=nxp/ixsub;
    1238             :       if( ix == ixsub){
    1239             :         nxsub=nxp-(nxp/ixsub)*(ix-1);
    1240             :       } 
    1241             :       */
    1242             : 
    1243             :     sectgmosd2(datStorage,
    1244             :            &nvp,
    1245             :            &nvc,
    1246             :            &idopsf,
    1247             :            flagstor,
    1248             :            rowflagstor,
    1249             :            wgtStorage,
    1250             :            &nvisrow,
    1251             :            gridstor,
    1252             :            &nxp,
    1253             :            &nyp,
    1254             :            &np,
    1255             :            &nc,
    1256             :            &csupp, 
    1257             :            &csize,
    1258             :            &csamp,
    1259             :            convstor,
    1260             :            cmapstor,
    1261             :            pmapstor,
    1262             :            swgtptr[icounter],
    1263             :            convrowmapstor,
    1264             :            convchanmapstor,
    1265             :            convpolmapstor,
    1266             :                &nConvFunc, &nChanConv, &nPolConv,
    1267             :                &x0, &y0, &nxsub, &nysub, &rbeg, &rend, locstor, offstor,
    1268             :                  phasorstor
    1269             :                );
    1270             :     }
    1271             :     }//end pragma parallel
    1272      125242 :     for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1273       62621 :       sumwgt[icounter].putStorage(swgtptr[icounter],swgtdel[icounter]);
    1274       62621 :       sumWeight=sumWeight+sumwgt[icounter];
    1275             :     }    
    1276             :     
    1277       62621 :     griddedData2.putStorage(gridstor, gridcopy);
    1278       62621 :     if(dopsf && (nth >4))
    1279           0 :       tweakGridSector(nx, ny, ixsub, iysub);
    1280       62621 :     timegrid_p+=tim.real();
    1281       62621 :     tim.mark();
    1282       62621 :     if(!doneWeightImage_p){
    1283             :       //This can be parallelized by making copy of the central part of the griddedWeight
    1284             :       //and adding it after dooing the gridding
    1285       42195 :       DComplex *gridwgtstor=griddedWeight2.getStorage(weightcopy);
    1286       42195 :       gmoswgtd(&nvp, &nvc,flagstor, rowflagstor, wgtStorage, &nvisrow, 
    1287             :                &nxp, &nyp, &np, &nc, &csupp, &csize, &csamp, 
    1288             :                cmapstor, pmapstor,
    1289             :                gridwgtstor, dsumwtstor, wconvstor, convrowmapstor, 
    1290             :                convchanmapstor,  convpolmapstor, 
    1291             :                &nConvFunc, &nChanConv, &nPolConv, &rbeg, 
    1292             :                &rend, locstor, offstor, phasorstor);
    1293       42195 :       griddedWeight2.putStorage(gridwgtstor, weightcopy);
    1294             :     
    1295             :     }
    1296       62621 :     timemass_p+=tim.real();
    1297             :   }
    1298             :   else {
    1299             :     //cerr << "maps "  << convChanMap_p << "   " << chanMap  << endl;
    1300             :     //cerr << "nchan " << nchan << "  nchanconv " << nChanConv << endl;
    1301           0 :     Complex *gridstor=griddedData.getStorage(gridcopy);
    1302           0 : #pragma omp parallel default(none) private(icounter, del) firstprivate(idopsf, /*doWeightGridding,*/ datStorage, wgtStorage, flagstor, rowflagstor, convstor, wconvstor, pmapstor, cmapstor, gridstor, csupp, nxp, nyp, np, nc,ixsub, iysub, rend, rbeg, csamp, csize, nvp, nvc, nvisrow, phasorstor, locstor, offstor, convrowmapstor, convchanmapstor, convpolmapstor, nPolConv, nChanConv, nConvFunc, xsect, ysect, nxsect, nysect)  shared(swgtptr) 
    1303             :     {   
    1304             : #pragma omp for schedule(dynamic)      
    1305             :       for(icounter=0; icounter < ixsub*iysub; ++icounter){
    1306             :         /*ix= (icounter+1)-((icounter)/ixsub)*ixsub;
    1307             :         iy=(icounter)/ixsub+1;
    1308             :         y0=(nyp/iysub)*(iy-1)+1;
    1309             :         nysub=nyp/iysub;
    1310             :         if( iy == iysub) {
    1311             :           nysub=nyp-(nyp/iysub)*(iy-1);
    1312             :         }
    1313             :         x0=(nxp/ixsub)*(ix-1)+1;
    1314             :         nxsub=nxp/ixsub;
    1315             :         if( ix == ixsub){
    1316             :           nxsub=nxp-(nxp/ixsub)*(ix-1);
    1317             :         } 
    1318             :         */
    1319             :         Int x0=xsect(icounter);
    1320             :         Int y0=ysect(icounter);
    1321             :         Int nxsub=nxsect(icounter);
    1322             :         Int nysub=nysect(icounter);
    1323             : 
    1324             :            sectgmoss2(datStorage,
    1325             :            &nvp,
    1326             :            &nvc,
    1327             :            &idopsf,
    1328             :            flagstor,
    1329             :            rowflagstor,
    1330             :            wgtStorage,
    1331             :            &nvisrow,
    1332             :            gridstor,
    1333             :            &nxp,
    1334             :            &nyp,
    1335             :            &np,
    1336             :            &nc,
    1337             :            &csupp, 
    1338             :            &csize,
    1339             :            &csamp,
    1340             :            convstor,
    1341             :            cmapstor,
    1342             :            pmapstor,
    1343             :            swgtptr[icounter],
    1344             :            convrowmapstor,
    1345             :            convchanmapstor,
    1346             :            convpolmapstor,
    1347             :                &nConvFunc, &nChanConv, &nPolConv,
    1348             :                &x0, &y0, &nxsub, &nysub, &rbeg, &rend, locstor, offstor,
    1349             :                  phasorstor
    1350             :                );
    1351             : 
    1352             : 
    1353             :     }
    1354             :     } //end pragma   
    1355           0 :      for (icounter=0; icounter < ixsub*iysub; ++icounter){
    1356           0 :        sumwgt[icounter].putStorage(swgtptr[icounter],swgtdel[icounter]);
    1357           0 :        sumWeight=sumWeight+sumwgt[icounter];
    1358             :     }
    1359           0 :     griddedData.putStorage(gridstor, gridcopy);
    1360           0 :     if(dopsf && (nth > 4))
    1361           0 :       tweakGridSector(nx, ny, ixsub, iysub);
    1362           0 :     timegrid_p+=tim.real();
    1363           0 :     tim.mark();
    1364           0 :     if(!doneWeightImage_p){
    1365           0 :       Complex *gridwgtstor=griddedWeight.getStorage(weightcopy);
    1366           0 :       gmoswgts(&nvp, &nvc,flagstor, rowflagstor, wgtStorage, &nvisrow, 
    1367             :                &nxp, &nyp, &np, &nc, &csupp, &csize, &csamp, 
    1368             :                cmapstor, pmapstor,
    1369             :                gridwgtstor, dsumwtstor, wconvstor, convrowmapstor, 
    1370             :                convchanmapstor,  convpolmapstor, 
    1371             :                &nConvFunc, &nChanConv, &nPolConv, &rbeg, 
    1372             :                &rend, locstor, offstor, phasorstor);
    1373           0 :       griddedWeight.putStorage(gridwgtstor, weightcopy);
    1374             :     
    1375             :     }
    1376           0 :     timemass_p+=tim.real();
    1377             :   }
    1378       62621 :   convFunc.freeStorage(convstor, convcopy);
    1379       62621 :   weightConvFunc_p.freeStorage(wconvstor, wconvcopy);
    1380       62621 :   dumSumWeight.putStorage(dsumwtstor, isDSWC);
    1381       62621 :   uvw.freeStorage(uvwstor, uvwcopy);
    1382       62621 :   if(!dopsf)
    1383       38608 :     data.freeStorage(datStorage, isCopy);
    1384             : 
    1385       62621 :   elWeight.freeStorage(wgtStorage,iswgtCopy);
    1386             :   
    1387             : 
    1388             : 
    1389             : 
    1390             : }
    1391             : 
    1392           0 : void MosaicFT::gridImgWeights(const vi::VisBuffer2& vb){
    1393             : 
    1394           0 :   if(doneWeightImage_p)
    1395           0 :     return;
    1396           0 :   matchChannel(vb);
    1397             :  
    1398             :   
    1399             :   //cerr << "CHANMAP " << chanMap << endl;
    1400             :   //No point in reading data if its not matching in frequency
    1401           0 :   if(max(chanMap)==-1)
    1402           0 :     return;
    1403             : 
    1404             :   Int startRow, endRow, nRow;
    1405           0 :   nRow=vb.nRows();
    1406           0 :   startRow=0;
    1407           0 :   endRow=nRow-1;
    1408             :   
    1409             :   
    1410             :   //const Matrix<Float> *imagingweight;
    1411             :   //imagingweight=&(vb.imagingWeight());
    1412           0 :   Matrix<Float> imagingweight;
    1413           0 :   getImagingWeight(imagingweight, vb);
    1414             : 
    1415             : 
    1416           0 :   Cube<Complex> data;
    1417             :   //Fortran gridder need the flag as ints 
    1418           0 :   Cube<Int> flags;
    1419           0 :   Matrix<Float> elWeight;
    1420           0 :   interpolateFrequencyTogrid(vb, imagingweight,data, flags, elWeight, FTMachine::PSF);
    1421             :   
    1422             :  
    1423             : 
    1424             :   Bool iswgtCopy;
    1425             :   const Float *wgtStorage;
    1426           0 :   wgtStorage=elWeight.getStorage(iswgtCopy);
    1427             :   Bool issumWgtCopy;
    1428           0 :   Double* sumwgtstor=sumWeight.getStorage(issumWgtCopy);
    1429             : 
    1430             :   
    1431             :  
    1432             :   // Get the uvws in a form that Fortran can use and do that
    1433             :   // necessary phase rotation. 
    1434           0 :   Matrix<Double> uvw(negateUV(vb));
    1435           0 :   Vector<Double> dphase(vb.nRows());
    1436           0 :   dphase=0.0;
    1437             :  
    1438           0 :   doUVWRotation_p=true;
    1439           0 :   girarUVW(uvw, dphase, vb);
    1440           0 :   refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
    1441             :   // This needs to be after the interp to get the interpolated channels
    1442             :   //Also has to be after rotateuvw in case tracking is on
    1443           0 :   findConvFunction(*image, vb);
    1444             :   //nothing to grid here as the pointing resulted in a zero support convfunc
    1445           0 :   if(convSupport <= 0)
    1446           0 :     return;
    1447             :   
    1448             :   Bool del;
    1449             :   
    1450           0 :   const Int* pmapstor=polMap.getStorage(del);
    1451           0 :   const Int* cmapstor=chanMap.getStorage(del);
    1452             :   
    1453           0 :   Vector<Int> rowFlags(vb.nRows());
    1454           0 :   rowFlags=0;
    1455           0 :   rowFlags(vb.flagRow())=true;
    1456           0 :   if(!usezero_p) {
    1457           0 :     for (uInt rownr=0; rownr< vb.nRows(); rownr++) {
    1458           0 :       if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) rowFlags(rownr)=1;
    1459             :     }
    1460             :   }
    1461             : 
    1462             :   //Fortran indexing
    1463             :   
    1464           0 :   Int rbeg=1;
    1465           0 :   Int rend=vb.nRows();
    1466             : 
    1467           0 :   const Int * flagstor=flags.getStorage(del);
    1468           0 :   const Int * rowflagstor=rowFlags.getStorage(del);
    1469             : 
    1470           0 :   const Int *convrowmapstor=convRowMap_p.getStorage(del);
    1471           0 :   const Int *convchanmapstor=convChanMap_p.getStorage(del);
    1472           0 :   const Int *convpolmapstor=convPolMap_p.getStorage(del);
    1473             :   
    1474             :   //Tell the gridder to grid the weights too ...need to do that once only
    1475             :   //Int doWeightGridding=1;
    1476             :   //if(doneWeightImage_p)
    1477             :   //  doWeightGridding=-1;
    1478             :   //    IPosition s(flags.shape());
    1479           0 :   const IPosition& fs=flags.shape();
    1480             :   //cerr << "flags shape " << fs << endl;
    1481           0 :   std::vector<Int>s(fs.begin(), fs.end());
    1482           0 :   Int nvp=s[0];
    1483           0 :   Int nvc=s[1];
    1484           0 :   Int nvisrow=s[2];
    1485           0 :   Int csamp=convSampling;
    1486             :   Bool uvwcopy; 
    1487           0 :   const Double *uvwstor=uvw.getStorage(uvwcopy);
    1488             :   Bool gridcopy;
    1489             :   Bool convcopy;
    1490             :   Bool wconvcopy;
    1491           0 :   const Complex *wconvstor=weightConvFunc_p.getStorage(wconvcopy);
    1492           0 :   Int nPolConv=convFunc.shape()[2];
    1493           0 :   Int nChanConv=convFunc.shape()[3];
    1494           0 :   Int nConvFunc=convFunc.shape()(4);
    1495             :   Bool weightcopy;
    1496             :   ////////**************************
    1497           0 :   Cube<Int> loc(2, nvc, vb.nRows());
    1498           0 :   Cube<Int> off(2, nvc, vb.nRows());
    1499           0 :   Matrix<Complex> phasor(nvc, vb.nRows());
    1500             :   Bool delphase;
    1501           0 :   Complex * phasorstor=phasor.getStorage(delphase);
    1502           0 :   const Double * visfreqstor=interpVisFreq_p.getStorage(del);
    1503           0 :   const Double * scalestor=uvScale.getStorage(del);
    1504           0 :   const Double * offsetstor=uvOffset.getStorage(del);
    1505           0 :   Int * locstor=loc.getStorage(del);
    1506           0 :   Int * offstor=off.getStorage(del);
    1507           0 :   const Double *dpstor=dphase.getStorage(del);
    1508             : 
    1509             :   Int irow;
    1510           0 :   Int nth=1;
    1511             : #ifdef _OPENMP
    1512           0 :   if(numthreads_p >0){
    1513           0 :     nth=min(numthreads_p, omp_get_max_threads());
    1514             :   }
    1515             :   else{   
    1516           0 :     nth= omp_get_max_threads();
    1517             :   }
    1518             :   //nth=min(4,nth);
    1519             : #endif
    1520           0 :   Double cinv=Double(1.0)/C::c;
    1521             :  
    1522           0 :   Int dow=0;
    1523             : 
    1524           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)  
    1525             : {
    1526             : #pragma omp for
    1527             :   for (irow=startRow; irow<=endRow;irow++){
    1528             :     /*locateuvw(uvwstor,dpstor, visfreqstor, nvc, scalestor, offsetstor, csamp, 
    1529             :               locstor, 
    1530             :               offstor, phasorstor, irow, false);*/
    1531             :     locuvw(uvwstor, dpstor, visfreqstor, &nvc, scalestor, offsetstor, &csamp, locstor, offstor, phasorstor, &irow, &dow, &cinv);
    1532             :   }  
    1533             : 
    1534             :  }//end pragma parallel
    1535             : 
    1536             : 
    1537             : 
    1538             : 
    1539           0 :   if(useDoubleGrid_p) {
    1540             :       //This can be parallelized by making copy of the central part of the griddedWeight
    1541             :       //and adding it after dooing the gridding
    1542           0 :       DComplex *gridwgtstor=griddedWeight2.getStorage(weightcopy);
    1543           0 :       gmoswgtd(&nvp, &nvc,flagstor, rowflagstor, wgtStorage, &nvisrow, 
    1544           0 :                &nx, &ny, &npol, &nchan, &convSupport, &convSize, &convSampling, 
    1545             :                cmapstor, pmapstor,
    1546             :                gridwgtstor, sumwgtstor, wconvstor, convrowmapstor, 
    1547             :                convchanmapstor,  convpolmapstor, 
    1548             :                &nConvFunc, &nChanConv, &nPolConv, &rbeg, 
    1549             :                &rend, locstor, offstor, phasorstor);
    1550           0 :       griddedWeight2.putStorage(gridwgtstor, weightcopy);
    1551             :     
    1552             :     
    1553             : 
    1554             : 
    1555             : 
    1556             :   }
    1557             :   else{
    1558           0 :     Complex *gridwgtstor=griddedWeight.getStorage(weightcopy);
    1559           0 :     gmoswgts(&nvp, &nvc,flagstor, rowflagstor, wgtStorage, &nvisrow, 
    1560           0 :              &nx, &ny, &npol, &nchan, &convSupport, &convSize, &convSampling, 
    1561             :              cmapstor, pmapstor,
    1562             :              gridwgtstor, sumwgtstor, wconvstor, convrowmapstor, 
    1563             :              convchanmapstor,  convpolmapstor, 
    1564             :              &nConvFunc, &nChanConv, &nPolConv, &rbeg, 
    1565             :              &rend, locstor, offstor, phasorstor);
    1566           0 :     griddedWeight.putStorage(gridwgtstor, weightcopy);
    1567             : 
    1568             : 
    1569             :   }
    1570           0 :   sumWeight.putStorage(sumwgtstor, issumWgtCopy); 
    1571           0 :   elWeight.freeStorage(wgtStorage,iswgtCopy);
    1572             :     
    1573             : }
    1574             : 
    1575       19581 : void MosaicFT::get(vi::VisBuffer2& vb, Int row)
    1576             : {
    1577             :   
    1578             : 
    1579             :   
    1580             :   // If row is -1 then we pass through all rows
    1581             :   Int startRow, endRow, nRow;
    1582       19581 :   if (row==-1) {
    1583       19581 :     nRow=vb.nRows();
    1584       19581 :     startRow=0;
    1585       19581 :     endRow=nRow-1;
    1586             :     //  vb.modelVisCube()=Complex(0.0,0.0);
    1587             :   } else {
    1588           0 :     nRow=1;
    1589           0 :     startRow=row;
    1590           0 :     endRow=row;
    1591             :     //  vb.modelVisCube().xyPlane(row)=Complex(0.0,0.0);
    1592             :   }
    1593             :   
    1594             : 
    1595             :  
    1596             : 
    1597       19581 :   matchChannel(vb);
    1598             :  
    1599             :   //No point in reading data if its not matching in frequency
    1600       19581 :   if(max(chanMap)==-1)
    1601           0 :     return;
    1602             : 
    1603             :   // Get the uvws in a form that Fortran can use
    1604       19581 :   Matrix<Double> uvw(negateUV(vb));
    1605       19581 :   Vector<Double> dphase(vb.nRows());
    1606       19581 :   dphase=0.0;
    1607             :  
    1608       19581 :   doUVWRotation_p=true;
    1609       19581 :   girarUVW(uvw, dphase, vb);
    1610       19581 :   refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
    1611             :   
    1612             :   
    1613             :   
    1614             :  
    1615       19581 :   Cube<Complex> data;
    1616       19581 :   Cube<Int> flags;
    1617       19581 :   getInterpolateArrays(vb, data, flags);
    1618             :   
    1619             :   //Need to get interpolated freqs
    1620       19581 :   findConvFunction(*image, vb);
    1621             : 
    1622             :   // no valid pointing in this buffer
    1623       19581 :   if(convSupport <= 0)
    1624           0 :     return;
    1625             :   Complex *datStorage;
    1626             :   Bool isCopy;
    1627       19581 :   datStorage=data.getStorage(isCopy);
    1628             :   
    1629             : 
    1630       39162 :   Vector<Int> rowFlags(vb.nRows());
    1631       19581 :   rowFlags=0;
    1632       19581 :   rowFlags(vb.flagRow())=true;
    1633       19581 :   if(!usezero_p) {
    1634     2964291 :     for (Int rownr=startRow; rownr<=endRow; rownr++) {
    1635     2944710 :       if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) rowFlags(rownr)=1;
    1636             :     }
    1637             :   }
    1638       19581 :   Int nvp=data.shape()[0];
    1639       19581 :   Int nvc=data.shape()[1];
    1640       19581 :   Int nvisrow=data.shape()[2];
    1641       19581 :   Int csamp=convSampling;
    1642       19581 :   Int csize=convSize;
    1643       19581 :   Int csupp=convSupport;
    1644       19581 :   Int nc=nchan;
    1645       19581 :   Int np=npol;
    1646       19581 :   Int nxp=nx;
    1647       19581 :   Int nyp=ny;
    1648             :   Bool uvwcopy; 
    1649       19581 :   const Double *uvwstor=uvw.getStorage(uvwcopy);
    1650       19581 :   Int nPolConv=convFunc.shape()[2];
    1651       19581 :   Int nChanConv=convFunc.shape()[3];
    1652       19581 :   Int nConvFunc=convFunc.shape()(4);
    1653             :   ////////**************************
    1654       39162 :   Cube<Int> loc(2, nvc, nRow);
    1655       39162 :   Cube<Int> off(2, nvc, nRow);
    1656       39162 :   Matrix<Complex> phasor(nvc, nRow);
    1657             :   Bool delphase;
    1658             :   Bool del;
    1659       19581 :   const Int* pmapstor=polMap.getStorage(del);
    1660       19581 :   const Int* cmapstor=chanMap.getStorage(del);
    1661       19581 :   Complex * phasorstor=phasor.getStorage(delphase);
    1662       19581 :   const Double * visfreqstor=interpVisFreq_p.getStorage(del);
    1663       19581 :   const Double * scalestor=uvScale.getStorage(del);
    1664       19581 :   const Double * offsetstor=uvOffset.getStorage(del);
    1665       19581 :   const Int * flagstor=flags.getStorage(del);
    1666       19581 :   const Int * rowflagstor=rowFlags.getStorage(del);
    1667       19581 :   Int * locstor=loc.getStorage(del);
    1668       19581 :   Int * offstor=off.getStorage(del);
    1669       19581 :   const Double *dpstor=dphase.getStorage(del);
    1670       19581 :   const Int *convrowmapstor=convRowMap_p.getStorage(del);
    1671       19581 :   const Int *convchanmapstor=convChanMap_p.getStorage(del);
    1672       19581 :   const Int *convpolmapstor=convPolMap_p.getStorage(del);
    1673             :   ////////***************************
    1674             : 
    1675             :   Int irow;
    1676       19581 :   Int nth=1;
    1677             :  #ifdef _OPENMP
    1678       19581 :   if(numthreads_p >0){
    1679           0 :     nth=min(numthreads_p, omp_get_max_threads());
    1680             :   }
    1681             :   else{   
    1682       19581 :     nth= omp_get_max_threads();
    1683             :   }
    1684             :   //nth=min(4,nth);
    1685             : #endif
    1686             : 
    1687       19581 :   Timer tim;
    1688       19581 :   tim.mark();
    1689             : 
    1690       19581 :    Int dow=0;
    1691       19581 :    Double cinv=Double(1.0)/C::c;
    1692       19581 : #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)  
    1693             : {
    1694             : #pragma omp for
    1695             :   for (irow=startRow; irow<=endRow;irow++){
    1696             :     /////////////////*locateuvw(uvwstor,dpstor, visfreqstor, nvc, scalestor, offsetstor, csamp, 
    1697             :     //    locstor, 
    1698             :                 ///////////           offstor, phasorstor, irow, false);
    1699             :     //using the fortran version which is significantly faster ...this can account for 10% less overall degridding time
    1700             :     locuvw(uvwstor, dpstor, visfreqstor, &nvc, scalestor, offsetstor, &csamp, locstor, 
    1701             :            offstor, phasorstor, &irow, &dow, &cinv);
    1702             :   }  
    1703             : 
    1704             :  }//end pragma parallel
    1705       19581 :  Int rbeg=startRow+1;
    1706       19581 :  Int rend=endRow+1;
    1707       19581 :  Int npart=nth;
    1708             :  
    1709             :  Bool gridcopy;
    1710       19581 :  const Complex *gridstor=griddedData.getStorage(gridcopy);
    1711             :  Bool convcopy;
    1712             :  ////Degridding needs the conjugate ...doing it here
    1713       39162 :  Array<Complex> conjConvFunc=conj(convFunc);
    1714       19581 :  const Complex *convstor=conjConvFunc.getStorage(convcopy);
    1715       19581 :   Int ix=0;
    1716       19581 : #pragma omp parallel default(none) private(ix, rbeg, rend) firstprivate(uvwstor, datStorage, flagstor, rowflagstor, convstor, pmapstor, cmapstor, gridstor, nxp, nyp, np, nc, csamp, csize, csupp, nvp, nvc, nvisrow, phasorstor, locstor, offstor, nPolConv, nChanConv, nConvFunc, convrowmapstor, convpolmapstor, convchanmapstor, npart)  num_threads(npart)
    1717             :   {
    1718             :     #pragma omp for schedule(dynamic) 
    1719             :     for (ix=0; ix< npart; ++ix){
    1720             :       rbeg=ix*(nvisrow/npart)+1;
    1721             :       rend=(ix != (npart-1)) ? (rbeg+(nvisrow/npart)-1) : (rbeg+(nvisrow/npart)-1+nvisrow%npart) ;
    1722             :       //cerr << "maps "  << convChanMap_p << "   " << chanMap  << endl;
    1723             :       //cerr << "nchan " << nchan << "  nchanconv " << nChanConv << " npolconv " << nPolConv << " nRowConv " << nConvFunc << endl;
    1724             :      sectdmos2(
    1725             :                datStorage,
    1726             :                &nvp,
    1727             :                &nvc,
    1728             :                flagstor,
    1729             :                rowflagstor,
    1730             :                &nvisrow,
    1731             :                gridstor,
    1732             :                &nxp,
    1733             :                &nyp,
    1734             :                &np,
    1735             :                &nc,
    1736             :                &csupp,
    1737             :                &csize,   
    1738             :                &csamp,
    1739             :                convstor,
    1740             :                cmapstor,
    1741             :                pmapstor,
    1742             :                convrowmapstor, convchanmapstor,
    1743             :                convpolmapstor,
    1744             :                &nConvFunc, &nChanConv, &nPolConv,
    1745             :                &rbeg, &rend, locstor, offstor, phasorstor
    1746             :                );
    1747             : 
    1748             : 
    1749             :     }
    1750             :   }//end pragma omp
    1751             : 
    1752             : 
    1753       19581 :   data.putStorage(datStorage, isCopy);
    1754       19581 :   griddedData.freeStorage(gridstor, gridcopy);
    1755       19581 :   convFunc.freeStorage(convstor, convcopy);
    1756             :   
    1757       19581 :    timedegrid_p+=tim.real();
    1758             : 
    1759       19581 :   interpolateFrequencyFromgrid(vb, data, FTMachine::MODEL);
    1760             : }
    1761             : 
    1762             : 
    1763             : /*
    1764             : void MosaicFT::get(VisBuffer& vb, Int row)
    1765             : {
    1766             :   
    1767             : 
    1768             :   
    1769             :   // If row is -1 then we pass through all rows
    1770             :   Int startRow, endRow, nRow;
    1771             :   if (row==-1) {
    1772             :     nRow=vb.nRow();
    1773             :     startRow=0;
    1774             :     endRow=nRow-1;
    1775             :     //  vb.modelVisCube()=Complex(0.0,0.0);
    1776             :   } else {
    1777             :     nRow=1;
    1778             :     startRow=row;
    1779             :     endRow=row;
    1780             :     //  vb.modelVisCube().xyPlane(row)=Complex(0.0,0.0);
    1781             :   }
    1782             :   
    1783             : 
    1784             :  
    1785             : 
    1786             : 
    1787             :   // Get the uvws in a form that Fortran can use
    1788             :   Matrix<Double> uvw(3, vb.uvw().nelements());
    1789             :   uvw=0.0;
    1790             :   Vector<Double> dphase(vb.uvw().nelements());
    1791             :   dphase=0.0;
    1792             :   //NEGATING to correct for an image inversion problem
    1793             :   for (Int i=startRow;i<=endRow;i++) {
    1794             :     for (Int idim=0;idim<2;idim++) uvw(idim,i)=-vb.uvw()(i)(idim);
    1795             :     uvw(2,i)=vb.uvw()(i)(2);
    1796             :   }
    1797             :   
    1798             :   doUVWRotation_p=true;
    1799             :   girarUVW(uvw, dphase, vb);
    1800             :   refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
    1801             :   
    1802             :   
    1803             :   //Check if ms has changed then cache new spw and chan selection
    1804             :   if(vb.newMS())
    1805             :     matchAllSpwChans(vb);
    1806             :   
    1807             :   //Here we redo the match or use previous match
    1808             :   
    1809             :   //Channel matching for the actual spectral window of buffer
    1810             :   if(doConversion_p[vb.spectralWindow()]){
    1811             :     matchChannel(vb.spectralWindow(), vb);
    1812             :   }
    1813             :   else{
    1814             :     chanMap.resize();
    1815             :     chanMap=multiChanMap_p[vb.spectralWindow()];
    1816             :   }
    1817             :   //No point in reading data if its not matching in frequency
    1818             :   if(max(chanMap)==-1)
    1819             :     return;
    1820             : 
    1821             :   Cube<Complex> data;
    1822             :   Cube<Int> flags;
    1823             :   getInterpolateArrays(vb, data, flags);
    1824             :   //Need to get interpolated freqs
    1825             :   findConvFunction(*image, vb);
    1826             :   // no valid pointing in this buffer
    1827             :   if(convSupport <= 0)
    1828             :     return;
    1829             :   Complex *datStorage;
    1830             :   Bool isCopy;
    1831             :   datStorage=data.getStorage(isCopy);
    1832             : 
    1833             : 
    1834             :   Vector<Int> rowFlags(vb.nRow());
    1835             :   rowFlags=0;
    1836             :   rowFlags(vb.flagRow())=true;
    1837             :   if(!usezero_p) {
    1838             :     for (Int rownr=startRow; rownr<=endRow; rownr++) {
    1839             :       if(vb.antenna1()(rownr)==vb.antenna2()(rownr)) rowFlags(rownr)=1;
    1840             :     }
    1841             :   }
    1842             :   Int nPolConv=convFunc.shape()[2];
    1843             :   Int nChanConv=convFunc.shape()[3];
    1844             :   Int nConvFunc=convFunc.shape()(4);
    1845             :  
    1846             :   {
    1847             :     Bool del;
    1848             :      Bool uvwcopy; 
    1849             :      const Double *uvwstor=uvw.getStorage(uvwcopy);
    1850             :      Bool gridcopy;
    1851             :      const Complex *gridstor=griddedData.getStorage(gridcopy);
    1852             :      Bool convcopy;
    1853             :      ////Degridding needs the conjugate ...doing it here
    1854             :      Array<Complex> conjConvFunc=conj(convFunc);
    1855             :      const Complex *convstor=conjConvFunc.getStorage(convcopy);
    1856             :      //     IPosition s(data.shape());
    1857             :      const IPosition& fs=data.shape();
    1858             :      std::vector<Int> s(fs.begin(), fs.end());
    1859             :      //cerr << "maps "  << convChanMap_p << "   " << chanMap  << endl;
    1860             :      //cerr << "nchan " << nchan << "  nchanconv " << nChanConv << " npolconv " << nPolConv << " nRowConv " << nConvFunc << endl;
    1861             :      dmos2(uvwstor,
    1862             :             dphase.getStorage(del),
    1863             :             datStorage,
    1864             :             &s[0],
    1865             :             &s[1],
    1866             :             flags.getStorage(del),
    1867             :             rowFlags.getStorage(del),
    1868             :             &s[2],
    1869             :             &row,
    1870             :            uvScale.getStorage(del), //10
    1871             :             uvOffset.getStorage(del),
    1872             :             gridstor,
    1873             :             &nx,
    1874             :             &ny,
    1875             :             &npol,
    1876             :             &nchan,
    1877             :             interpVisFreq_p.getStorage(del),
    1878             :             &C::c,
    1879             :             &convSupport,
    1880             :            &convSize,   //20
    1881             :             &convSampling,
    1882             :             convstor,
    1883             :             chanMap.getStorage(del),
    1884             :             polMap.getStorage(del),
    1885             :             convRowMap_p.getStorage(del), convChanMap_p.getStorage(del),
    1886             :             convPolMap_p.getStorage(del),
    1887             :             &nConvFunc, &nChanConv, &nPolConv);
    1888             :       data.putStorage(datStorage, isCopy);
    1889             :      uvw.freeStorage(uvwstor, uvwcopy);
    1890             :      griddedData.freeStorage(gridstor, gridcopy);
    1891             :      convFunc.freeStorage(convstor, convcopy);
    1892             :   }
    1893             :   interpolateFrequencyFromgrid(vb, data, FTMachine::MODEL);
    1894             : }
    1895             : 
    1896             : */
    1897             : 
    1898             : 
    1899             : // Finalize the FFT to the Sky. Here we actually do the FFT and
    1900             : // return the resulting image
    1901           0 : ImageInterface<Complex>& MosaicFT::getImage(Matrix<Float>& weights,
    1902             :                                             Bool normalize) 
    1903             : {
    1904             :   //AlwaysAssert(lattice, AipsError);
    1905           0 :   AlwaysAssert(image, AipsError);
    1906             : 
    1907           0 :    if((griddedData.nelements() ==0) && (griddedData2.nelements()==0)){
    1908           0 :     throw(AipsError("Programmer error ...request for image without right order of calls"));
    1909             :   }
    1910             : 
    1911           0 :   logIO() << LogOrigin("MosaicFT", "getImage") << LogIO::NORMAL;
    1912             :   
    1913           0 :   weights.resize(sumWeight.shape());
    1914           0 :   convertArray(weights, sumWeight);
    1915           0 :   SynthesisUtilMethods::getResource("mem peak in getImage");
    1916             :   
    1917             :   // If the weights are all zero then we cannot normalize
    1918             :   // otherwise we don't care.
    1919           0 :   if(max(weights)==0.0) {
    1920           0 :     if(normalize) {
    1921             :       logIO() << LogIO::SEVERE << "No useful data in MosaicFT: weights all zero"
    1922           0 :               << LogIO::POST;
    1923             :     }
    1924             :     else {
    1925             :       logIO() << LogIO::WARN << "No useful data in MosaicFT: weights all zero"
    1926           0 :               << LogIO::POST;
    1927             :     }
    1928             :   }
    1929             :   else {
    1930             :     
    1931             :     //const IPosition latticeShape = lattice->shape();
    1932             :     
    1933             :     logIO() << LogIO::DEBUGGING
    1934           0 :             << "Starting FFT and scaling of image" << LogIO::POST;
    1935           0 :     if(useDoubleGrid_p){
    1936           0 :       ArrayLattice<DComplex> darrayLattice(griddedData2);
    1937           0 :       ft_p.c2cFFT(darrayLattice,false);
    1938           0 :       griddedData.resize(griddedData2.shape());
    1939           0 :       convertArray(griddedData, griddedData2);
    1940             :       
    1941             :       //Don't need the double-prec grid anymore...
    1942           0 :       griddedData2.resize();
    1943           0 :       arrayLattice = new ArrayLattice<Complex>(griddedData);
    1944           0 :       lattice=arrayLattice;
    1945             : 
    1946             :     }
    1947             :     else{
    1948           0 :       arrayLattice = new ArrayLattice<Complex>(griddedData);
    1949           0 :       lattice=arrayLattice;
    1950           0 :       ft_p.c2cFFT(*lattice,false);
    1951             :     }
    1952             :    {////Do the grid correction
    1953           0 :       Int inx = lattice->shape()(0);
    1954             :       //Int iny = lattice->shape()(1);
    1955           0 :       Vector<Complex> correction(inx);
    1956           0 :       correction=Complex(1.0, 0.0);
    1957             : 
    1958             :       // Int npixCorr= max(nx,ny);
    1959           0 :       Vector<Float> sincConvX(nx);
    1960           0 :       for (Int ix=0;ix<nx;ix++) {
    1961           0 :         Float x=C::pi*Float(ix-nx/2)/(Float(nx)*Float(convSampling));
    1962           0 :         if(ix==nx/2) {
    1963           0 :           sincConvX(ix)=1.0;
    1964             :         }
    1965             :         else {
    1966           0 :           sincConvX(ix)=sin(x)/x;
    1967             :         }
    1968             :       }
    1969           0 :       Vector<Float> sincConvY(ny);
    1970           0 :       for (Int ix=0;ix<ny;ix++) {
    1971           0 :         Float x=C::pi*Float(ix-ny/2)/(Float(ny)*Float(convSampling));
    1972           0 :         if(ix==ny/2) {
    1973           0 :           sincConvY(ix)=1.0;
    1974             :         }
    1975             :         else {
    1976           0 :           sincConvY(ix)=sin(x)/x;
    1977             :         }
    1978             :       }
    1979             :     
    1980             : 
    1981           0 :       IPosition cursorShape(4, inx, 1, 1, 1);
    1982           0 :       IPosition axisPath(4, 0, 1, 2, 3);
    1983           0 :       LatticeStepper lsx(lattice->shape(), cursorShape, axisPath);
    1984           0 :       LatticeIterator<Complex> lix(*lattice, lsx);
    1985           0 :       for(lix.reset();!lix.atEnd();lix++) {
    1986           0 :         Int pol=lix.position()(2);
    1987           0 :         Int chan=lix.position()(3);
    1988           0 :         if(weights(pol, chan)!=0.0) {
    1989           0 :           Int iy=lix.position()(1);
    1990             :           //gridder->correctX1D(correction,iy);
    1991           0 :           for (Int ix=0;ix<nx;ix++) {
    1992           0 :             correction(ix)=1.0/(sincConvX(ix)*sincConvY(iy));
    1993             :           }
    1994           0 :           lix.rwVectorCursor()*=correction;
    1995           0 :           if(normalize) {
    1996           0 :             Complex rnorm(1.0/weights(pol,chan));
    1997           0 :             lix.rwCursor()*=rnorm;
    1998             :           }
    1999             :         }
    2000             :         else {
    2001           0 :           lix.woCursor()=0.0;
    2002             :         }
    2003             :       }
    2004             :     }
    2005             :      
    2006             :     
    2007             : 
    2008             :     //if(!isTiled) 
    2009             :     {
    2010           0 :       LatticeLocker lock1 (*(image), FileLocker::Write);
    2011             :       // Check the section from the image BEFORE converting to a lattice 
    2012           0 :       IPosition blc(4, (nx-image->shape()(0)+(nx%2==0))/2,
    2013           0 :                     (ny-image->shape()(1)+(ny%2==0))/2, 0, 0);
    2014           0 :       IPosition stride(4, 1);
    2015           0 :       IPosition trc(blc+image->shape()-stride);
    2016             :       
    2017             :       // Do the copy
    2018           0 :       IPosition start(4, 0);
    2019           0 :       image->put(griddedData(blc, trc));
    2020             :     }
    2021             :   }
    2022           0 :   if(!arrayLattice.null()) arrayLattice=0;
    2023           0 :   if(!lattice.null()) lattice=0;
    2024           0 :    griddedData.resize();
    2025           0 :   image->clearCache();
    2026           0 :   return *image;
    2027             : }
    2028             : 
    2029             : // Get weight image
    2030           0 : void MosaicFT::getWeightImage(ImageInterface<Float>& weightImage,
    2031             :                               Matrix<Float>& weights) 
    2032             : {
    2033             :   
    2034           0 :   logIO() << LogOrigin("MosaicFT", "getWeightImage") << LogIO::NORMAL;
    2035             :   
    2036           0 :   weights.resize(sumWeight.shape());
    2037           0 :   convertArray(weights,sumWeight);
    2038             :   /*
    2039             :   weightImage.copyData((LatticeExpr<Float>) 
    2040             :                        (iif((pbConvFunc_p->getFluxScaleImage()) > (0.0), 
    2041             :                             (*skyCoverage_p),0.0)));
    2042             :   */
    2043           0 :   weightImage.copyData(*skyCoverage_p);
    2044             :   //cerr << "getWeightIm " << max(sumWeight) << "    " << max(skyCoverage_p->get()) << endl;
    2045             :   
    2046           0 :    skyCoverage_p->tempClose();
    2047             : 
    2048           0 : }
    2049             : 
    2050           0 : void MosaicFT::getFluxImage(ImageInterface<Float>& fluxImage) {
    2051             : 
    2052           0 :   if (stokes_p=="QU" || stokes_p=="IV"){
    2053           0 :     pbConvFunc_p->sliceFluxScale(2);
    2054             :   }
    2055           0 :   else if(stokes_p=="Q" || stokes_p=="U" ||  stokes_p=="V" || stokes_p=="I" ){
    2056           0 :      pbConvFunc_p->sliceFluxScale(1);
    2057             :   }
    2058           0 :    else if(stokes_p=="IQU"){
    2059           0 :        pbConvFunc_p->sliceFluxScale(3);
    2060             :    }
    2061           0 :   IPosition inShape=(pbConvFunc_p->getFluxScaleImage()).shape();
    2062           0 :   IPosition outShape=fluxImage.shape();
    2063           0 :   if(outShape==inShape){
    2064           0 :     fluxImage.copyData(pbConvFunc_p->getFluxScaleImage());
    2065             :   }
    2066           0 :   else if((outShape(0)==inShape(0)) && (outShape(1)==inShape(1)) 
    2067           0 :           && (outShape(2)==inShape(2))){
    2068             :     //case where CubeSkyEquation is chunking...copy the first pol-cube
    2069           0 :     IPosition cursorShape(4, inShape(0), inShape(1), inShape(2), 1);
    2070           0 :     IPosition axisPath(4, 0, 1, 2, 3);
    2071           0 :     LatticeStepper lsout(outShape, cursorShape, axisPath);
    2072           0 :     LatticeStepper lsin(inShape, cursorShape, axisPath);
    2073           0 :     LatticeIterator<Float> liout(fluxImage, lsout);
    2074           0 :     RO_LatticeIterator<Float> liin(pbConvFunc_p->getFluxScaleImage(), lsin);
    2075           0 :     liin.reset();
    2076           0 :     for(liout.reset();!liout.atEnd();liout++) {
    2077           0 :       if(inShape(2)==1)
    2078           0 :         liout.woMatrixCursor()=liin.matrixCursor();
    2079             :       else
    2080           0 :         liout.woCubeCursor()=liin.cubeCursor();
    2081             :     }
    2082             : 
    2083             : 
    2084             :   }
    2085             :   else{
    2086             :     //Should not reach here but the we're getting old
    2087           0 :     cout << "Bad case of shape mismatch in flux image shape" << endl;
    2088             :   }
    2089           0 : }
    2090             : 
    2091           0 : CountedPtr<TempImage<Float> >& MosaicFT::getConvWeightImage(){
    2092           0 :   if(!doneWeightImage_p)
    2093           0 :     finalizeToSky();
    2094           0 :   return skyCoverage_p;
    2095             : }
    2096             : 
    2097           4 : Bool MosaicFT::toRecord(String&  error,
    2098             :                         RecordInterface& outRec, Bool withImage, const String diskimage)
    2099             : {  
    2100             :   // Save the current MosaicFT object to an output state record
    2101           4 :   Bool retval = true;
    2102           4 :   if(!FTMachine::toRecord(error, outRec, withImage, diskimage))
    2103           0 :     return false;
    2104             :   
    2105           4 :   if(sj_p){
    2106           4 :     outRec.define("telescope", sj_p->telescope());
    2107             :     //cerr <<" Telescope " << sj_p->telescope() << endl;
    2108             :   }
    2109           4 :   outRec.define("uvscale", uvScale);
    2110           4 :   outRec.define("uvoffset", uvOffset);
    2111           4 :   outRec.define("cachesize", Int64(cachesize));
    2112           4 :   outRec.define("tilesize", tilesize);
    2113           4 :   outRec.define("maxabsdata", maxAbsData);
    2114           8 :   Vector<Int> center_loc(4), offset_loc(4);
    2115          20 :   for (Int k=0; k<4 ; k++){
    2116          16 :     center_loc(k)=centerLoc(k);
    2117          16 :     offset_loc(k)=offsetLoc(k);
    2118             :   }
    2119           4 :   outRec.define("centerloc", center_loc);
    2120           4 :   outRec.define("offsetloc", offset_loc);
    2121           4 :   outRec.define("usezero", usezero_p);
    2122           4 :   outRec.define("convfunc", convFunc);
    2123           4 :   outRec.define("weightconvfunc", weightConvFunc_p);
    2124           4 :   outRec.define("convsampling", convSampling);
    2125           4 :   outRec.define("convsize", convSize);
    2126           4 :   outRec.define("convsupport", convSupport);
    2127           4 :   outRec.define("convsupportplanes", convSupportPlanes_p);
    2128           4 :   outRec.define("convsizeplanes", convSizePlanes_p);
    2129           4 :   outRec.define("convRowMap",  convRowMap_p);
    2130           4 :   outRec.define("stokes", stokes_p);
    2131           4 :   outRec.define("useconjconvfunc", useConjConvFunc_p);
    2132           4 :   outRec.define("usepointingtable", usePointingTable_p);
    2133           4 :   if(!pbConvFunc_p.null()){
    2134           4 :     Record subRec;
    2135             :     //cerr << "Doing pbconvrec " << endl;
    2136           4 :     pbConvFunc_p->toRecord(subRec);
    2137           4 :     outRec.defineRecord("pbconvfunc", subRec);        
    2138             :   }
    2139             :   
    2140             : 
    2141           4 :   return retval;
    2142             : }
    2143             : 
    2144           0 : Bool MosaicFT::fromRecord(String& error,
    2145             :                           const RecordInterface& inRec)
    2146             : {
    2147           0 :   Bool retval = true;
    2148           0 :   pointingToImage=0;
    2149           0 :   doneWeightImage_p=false;
    2150           0 :   convWeightImage_p=nullptr;
    2151             :   
    2152           0 :   if(!FTMachine::fromRecord(error, inRec))
    2153           0 :     return false;
    2154           0 :   sj_p=0;
    2155           0 :   if(inRec.isDefined("telescope")){
    2156           0 :     String tel=inRec.asString("telescope");
    2157             :     PBMath::CommonPB pbtype;
    2158           0 :     Quantity freq(1e12, "Hz");// no useful band...just get default beam
    2159           0 :     String band="";
    2160           0 :     String pbname;
    2161           0 :     PBMath::whichCommonPBtoUse(tel, freq, band, pbtype, pbname);
    2162           0 :     if(pbtype != PBMath::UNKNOWN)
    2163           0 :       sj_p.reset(new VPSkyJones(tel,pbtype));
    2164             :   }
    2165             : 
    2166           0 :   inRec.get("name", machineName_p);
    2167           0 :   inRec.get("uvscale", uvScale);
    2168           0 :   inRec.get("uvoffset", uvOffset);
    2169           0 :   cachesize=inRec.asInt64("cachesize");
    2170           0 :   inRec.get("tilesize", tilesize);
    2171           0 :   inRec.get("maxabsdata", maxAbsData);
    2172           0 :   Vector<Int> center_loc(4), offset_loc(4);
    2173           0 :   inRec.get("centerloc", center_loc);
    2174           0 :   inRec.get("offsetloc", offset_loc);
    2175           0 :   uInt ndim4 = 4;
    2176           0 :   centerLoc=IPosition(ndim4, center_loc(0), center_loc(1), center_loc(2), 
    2177           0 :                       center_loc(3));
    2178           0 :   offsetLoc=IPosition(ndim4, offset_loc(0), offset_loc(1), offset_loc(2), 
    2179           0 :                       offset_loc(3));
    2180           0 :   imageCache=0; lattice=0; arrayLattice=0;
    2181           0 :   inRec.get("usezero", usezero_p);
    2182           0 :   inRec.get("convfunc", convFunc);
    2183           0 :   inRec.get("weightconvfunc", weightConvFunc_p);
    2184           0 :   inRec.get("convsampling", convSampling);
    2185           0 :   inRec.get("convsize", convSize);
    2186           0 :   inRec.get("convsupport", convSupport);
    2187           0 :   inRec.get("convsupportplanes", convSupportPlanes_p);
    2188           0 :   inRec.get("convsizeplanes", convSizePlanes_p);
    2189           0 :   inRec.get("convRowMap",  convRowMap_p);
    2190           0 :   inRec.get("stokes", stokes_p);
    2191           0 :   inRec.get("useconjconvfunc", useConjConvFunc_p);
    2192           0 :   inRec.get("usepointingtable", usePointingTable_p);
    2193           0 :   if(inRec.isDefined("pbconvfunc")){
    2194           0 :     Record subRec=inRec.asRecord("pbconvfunc");
    2195           0 :     String elname=subRec.asString("name");
    2196             :     // if we are predicting only ...no need to estimate fluxscale
    2197           0 :     if(elname=="HetArrayConvFunc"){
    2198             :     
    2199           0 :       pbConvFunc_p=new HetArrayConvFunc(subRec, !toVis_p);
    2200             :     }
    2201             :     else{
    2202           0 :       pbConvFunc_p=new SimplePBConvFunc(subRec, !toVis_p);
    2203           0 :       if(!sj_p)
    2204           0 :         throw(AipsError("Failed to recovermosaic FTmachine;\n If you are seeing this message when try to get model vis \n then either try to reset the model or use scratch column for now"));
    2205             :     }
    2206             :   }
    2207             :   else{
    2208           0 :     pbConvFunc_p=0;
    2209             :   }
    2210           0 :   gridder.reset(nullptr);
    2211           0 :    return retval;
    2212             : }
    2213             : 
    2214       82283 : void MosaicFT::ok() {
    2215       82283 :   AlwaysAssert(image, AipsError);
    2216       82283 : }
    2217             : 
    2218             : // Make a plain straightforward honest-to-God image. This returns
    2219             : // a complex image, without conversion to Stokes. The representation
    2220             : // is that required for the visibilities.
    2221             : //----------------------------------------------------------------------
    2222           2 : void MosaicFT::makeImage(FTMachine::Type type, 
    2223             :                          vi::VisibilityIterator2& vi,
    2224             :                          ImageInterface<Complex>& theImage,
    2225             :                          Matrix<Float>& weight) {
    2226             :   
    2227             :   
    2228           2 :   logIO() << LogOrigin("MosaicFT", "makeImage") << LogIO::NORMAL;
    2229             :   
    2230           2 :   if(type==FTMachine::COVERAGE) {
    2231             :     logIO() << "Type COVERAGE not defined for Fourier transforms"
    2232           0 :             << LogIO::EXCEPTION;
    2233             :   }
    2234             :   
    2235             :   
    2236             : 
    2237             :   // Loop over all visibilities and pixels
    2238           2 :   vi::VisBuffer2* vb=vi.getVisBuffer();
    2239             :   
    2240             :   // Initialize put (i.e. transform to Sky) for this model
    2241           2 :   vi.origin();
    2242             :   
    2243           2 :   if(vb->polarizationFrame()==MSIter::Linear) {
    2244           0 :     StokesImageUtil::changeCStokesRep(theImage, StokesImageUtil::LINEAR);
    2245             :   }
    2246             :   else {
    2247           2 :     StokesImageUtil::changeCStokesRep(theImage, StokesImageUtil::CIRCULAR);
    2248             :   }
    2249             :   
    2250           2 :   initializeToSky(theImage,weight,*vb);
    2251             :   //This call is a NOP for all weighting schemes except for cube-briggs-perchanweightdensity
    2252           2 :   initBriggsWeightor(vi);
    2253             :   // Loop over the visibilities, putting VisBuffers
    2254          10 :   for (vi.originChunks();vi.moreChunks();vi.nextChunk()) {
    2255         872 :     for (vi.origin(); vi.more(); vi.next()) {
    2256             :       
    2257         864 :       switch(type) {
    2258           0 :       case FTMachine::RESIDUAL:
    2259           0 :         vb->setVisCube(vb->visCubeCorrected()-vb->visCubeModel());
    2260           0 :         put(*vb, -1, false);
    2261           0 :         break;
    2262           0 :       case FTMachine::MODEL:
    2263           0 :         vb->setVisCube(vb->visCubeModel());
    2264           0 :         put(*vb, -1, false);
    2265           0 :         break;
    2266           0 :       case FTMachine::CORRECTED:
    2267           0 :         vb->setVisCube(vb->visCubeCorrected());
    2268           0 :         put(*vb, -1, false);
    2269           0 :         break;
    2270         864 :       case FTMachine::PSF:
    2271         864 :         vb->setVisCube(Complex(1.0,0.0));
    2272         864 :         put(*vb, -1, true);
    2273         864 :         break;
    2274           0 :       case FTMachine::OBSERVED:
    2275             :       default:
    2276           0 :         put(*vb, -1, false);
    2277           0 :         break;
    2278             :       }
    2279             :     }
    2280             :   }
    2281           2 :   finalizeToSky();
    2282             :   // Normalize by dividing out weights, etc.
    2283           2 :   getImage(weight, true);
    2284           2 : }
    2285             : 
    2286           0 : Bool MosaicFT::getXYPos(const vi::VisBuffer2& vb, Int row) {
    2287             :   
    2288           0 :   MSColumns mscol(vb.ms());
    2289           0 :   const MSPointingColumns& act_mspc=mscol.pointing();
    2290           0 :   Int pointIndex=getIndex(act_mspc, vb.time()(row), vb.timeInterval()(row));
    2291           0 :   if((pointIndex<0)||pointIndex>=Int(act_mspc.time().nrow())) {
    2292             :     //    ostringstream o;
    2293             :     //    o << "Failed to find pointing information for time " <<
    2294             :     //      MVTime(vb.time()(row)/86400.0);
    2295             :     //    logIO_p << LogIO::DEBUGGING << String(o) << LogIO::POST;
    2296             :     //    logIO_p << String(o) << LogIO::POST;
    2297             :     
    2298           0 :     worldPosMeas = mscol.field().phaseDirMeas(vb.fieldId()(0));
    2299             :   }
    2300             :   else {
    2301             :    
    2302           0 :       worldPosMeas=act_mspc.directionMeas(pointIndex);
    2303             :       // Make a machine to convert from the worldPosMeas to the output
    2304             :       // Direction Measure type for the relevant frame
    2305             :  
    2306             : 
    2307             :  
    2308             :   }
    2309             : 
    2310           0 :   if(!pointingToImage) {
    2311             :     // Set the frame - choose the first antenna. For e.g. VLBI, we
    2312             :     // will need to reset the frame per antenna
    2313           0 :     FTMachine::mLocation_p=mscol.antenna().positionMeas()(0);
    2314           0 :     mFrame_p=MeasFrame(MEpoch(Quantity(vb.time()(row), "s")),
    2315           0 :                        FTMachine::mLocation_p);
    2316           0 :     MDirection::Ref outRef(directionCoord.directionType(), mFrame_p);
    2317           0 :     pointingToImage = new MDirection::Convert(worldPosMeas, outRef);
    2318             :   
    2319           0 :     if(!pointingToImage) {
    2320           0 :       logIO_p << "Cannot make direction conversion machine" << LogIO::EXCEPTION;
    2321             :     }
    2322             :   }
    2323             :   else {
    2324           0 :     mFrame_p.resetEpoch(MEpoch(Quantity(vb.time()(row), "s")));
    2325             :   }
    2326             :   
    2327           0 :   worldPosMeas=(*pointingToImage)(worldPosMeas);
    2328             :  
    2329           0 :   Bool result=directionCoord.toPixel(xyPos, worldPosMeas);
    2330           0 :   if(!result) {
    2331           0 :     logIO_p << "Failed to find pixel location for " 
    2332           0 :             << worldPosMeas.getAngle().getValue() << LogIO::EXCEPTION;
    2333           0 :     return false;
    2334             :   }
    2335           0 :   return result;
    2336             :   
    2337             : }
    2338             : // Get the index into the pointing table for this time. Note that the 
    2339             : // in the pointing table, TIME specifies the beginning of the spanned
    2340             : // time range, whereas for the main table, TIME is the centroid.
    2341             : // Note that the behavior for multiple matches is not specified! i.e.
    2342             : // if there are multiple matches, the index returned depends on the
    2343             : // history of previous matches. It is deterministic but not obvious.
    2344             : // One could cure this by searching but it would be considerably
    2345             : // costlier.
    2346           0 : Int MosaicFT::getIndex(const MSPointingColumns& mspc, const Double& time,
    2347             :                        const Double& /*interval*/) {
    2348           0 :   Int start=lastIndex_p;
    2349             :   // Search forwards
    2350           0 :   Int nrows=mspc.time().nrow();
    2351           0 :   if(nrows<1) {
    2352             :     //    logIO_p << "No rows in POINTING table - cannot proceed" << LogIO::EXCEPTION;
    2353           0 :     return -1;
    2354             :   }
    2355           0 :   for (Int i=start;i<nrows;i++) {
    2356           0 :     Double midpoint = mspc.time()(i); // time in POINTING table is midpoint
    2357             :     // If the interval in the pointing table is negative, use the last
    2358             :     // entry. Note that this may be invalid (-1) but in that case 
    2359             :     // the calling routine will generate an error
    2360           0 :     if(mspc.interval()(i)<0.0) {
    2361           0 :       return lastIndex_p;
    2362             :     }
    2363             :     // Pointing table interval is specified so we have to do a match
    2364             :     else {
    2365             :       // Is the midpoint of this pointing table entry within the specified
    2366             :       // tolerance of the main table entry?
    2367           0 :       if(abs(midpoint-time) < (mspc.interval()(i)/2.0)) {
    2368           0 :         lastIndex_p=i;
    2369           0 :         return i;
    2370             :       }
    2371             :     }
    2372             :   }
    2373             :   // Search backwards
    2374           0 :   for (Int i=start;i>=0;i--) {
    2375           0 :     Double midpoint = mspc.time()(i); // time in POINTING table is midpoint
    2376           0 :     if(mspc.interval()(i)<0.0) {
    2377           0 :       return lastIndex_p;
    2378             :     }
    2379             :     // Pointing table interval is specified so we have to do a match
    2380             :     else {
    2381             :       // Is the midpoint of this pointing table entry within the specified
    2382             :       // tolerance of the main table entry?
    2383           0 :       if(abs(midpoint-time) < (mspc.interval()(i)/2.0)) {
    2384           0 :         lastIndex_p=i;
    2385           0 :         return i;
    2386             :       }
    2387             :     }
    2388             :   }
    2389             :   // No match!
    2390           0 :   return -1;
    2391             : }
    2392             : 
    2393             : 
    2394             : 
    2395             : 
    2396           0 : void MosaicFT::addBeamCoverage(ImageInterface<Complex>& pbImage){
    2397             : 
    2398           0 :   CoordinateSystem cs(pbImage.coordinates());
    2399             :   //  IPosition blc(4,0,0,0,0);
    2400             :   //  IPosition trc(pbImage.shape());
    2401             :   //  trc(0)=trc(0)-1;
    2402             :   //  trc(1)=trc(1)-1;
    2403             :   // trc(2)=0;
    2404             :   //  trc(3)=0;
    2405           0 :   WCBox *wbox= new WCBox(LCBox(pbImage.shape()), cs);
    2406           0 :   SubImage<Float> toAddTo(*skyCoverage_p, ImageRegion(wbox), true);
    2407           0 :   TempImage<Float> beamStokes(pbImage.shape(), cs);
    2408           0 :   StokesImageUtil::To(beamStokes, pbImage);
    2409             :   //  toAddTo.copyData((LatticeExpr<Float>)(toAddTo + beamStokes ));
    2410           0 :   skyCoverage_p->copyData((LatticeExpr<Float>)(*skyCoverage_p + beamStokes ));
    2411             : 
    2412             : 
    2413           0 : }
    2414             : 
    2415             : 
    2416             : 
    2417             : 
    2418             : 
    2419           0 : String MosaicFT::name() const {
    2420           0 :   return machineName_p;
    2421             : }
    2422             : 
    2423             : } // REFIM ends
    2424             : } //# NAMESPACE CASA - END
    2425             : 
    2426             : 

Generated by: LCOV version 1.16