LCOV - code coverage report
Current view: top level - synthesis/TransformMachines2 - AWProjectWBFT.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 288 0.0 %
Date: 2025-08-21 08:01:32 Functions: 0 19 0.0 %

          Line data    Source code
       1             : // -*- C++ -*-
       2             : //# AWProjectWBFT.cc: Implementation of AWProjectWBFT class
       3             : //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003
       4             : //# Associated Universities, Inc. Washington DC, USA.
       5             : //#
       6             : //# This library is free software; you can redistribute it and/or modify it
       7             : //# under the terms of the GNU Library General Public License as published by
       8             : //# the Free Software Foundation; either version 2 of the License, or (at your
       9             : //# option) any later version.
      10             : //#
      11             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      12             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      14             : //# License for more details.
      15             : //#
      16             : //# You should have received a copy of the GNU Library General Public License
      17             : //# along with this library; if not, write to the Free Software Foundation,
      18             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      19             : //#
      20             : //# Correspondence concerning AIPS++ should be addressed as follows:
      21             : //#        Internet email: casa-feedback@nrao.edu.
      22             : //#        Postal address: AIPS++ Project Office
      23             : //#                        National Radio Astronomy Observatory
      24             : //#                        520 Edgemont Road
      25             : //#                        Charlottesville, VA 22903-2475 USA
      26             : //#
      27             : //# $Id$
      28             : 
      29             : #include <synthesis/TransformMachines2/VB2CFBMap.h>
      30             : #include <synthesis/TransformMachines2/AWProjectWBFT.h>
      31             : #include <synthesis/TransformMachines2/AWVisResampler.h>
      32             : #include <synthesis/TransformMachines/StokesImageUtil.h>
      33             : #include <casacore/coordinates/Coordinates/CoordinateSystem.h>
      34             : #include <casacore/scimath/Mathematics/FFTServer.h>
      35             : #include <casacore/scimath/Mathematics/Convolver.h>
      36             : #include <casacore/lattices/LatticeMath/LatticeFFT.h>
      37             : #include <casacore/images/Images/ImageInterface.h>
      38             : #include <casacore/images/Images/PagedImage.h>
      39             : #include <msvis/MSVis/VisBuffer2.h>
      40             : #include <casacore/casa/Arrays/Vector.h>
      41             : #include <casacore/casa/Arrays/Slice.h>
      42             : #include <casacore/casa/Arrays/ArrayMath.h>
      43             : #include <casacore/casa/Arrays/Array.h>
      44             : #include <casacore/casa/OS/HostInfo.h>
      45             : #include <sstream>
      46             : #include <casacore/casa/Utilities/CompositeNumber.h>
      47             : 
      48             : using namespace casacore;
      49             : namespace casa { //# NAMESPACE CASA - BEGIN
      50             :   namespace refim{
      51             :     //==================================================================================================
      52             :     // Various template instantiations
      53             :     //
      54             :     template
      55             :     void AWProjectWBFT::ftWeightImage(Lattice<casacore::Complex>& wtImage, 
      56             :                                       const Matrix<Float>& sumWt,
      57             :                                       const Bool& doFFTNorm);
      58             :     template
      59             :     void AWProjectWBFT::makeWBSensitivityImage(Lattice<casacore::Complex>& wtImage,
      60             :                                                ImageInterface<Float>& sensitivityImage,
      61             :                                                const Matrix<Float>& sumWt,
      62             :                                                const Bool& doFFTNorm);
      63             :     //==================================================================================================
      64             :     template
      65             :     void AWProjectWBFT::ftWeightImage(Lattice<casacore::DComplex>& wtImage, 
      66             :                                       const Matrix<Float>& sumWt,
      67             :                                       const Bool& doFFTNorm);
      68             :     template
      69             :     void AWProjectWBFT::makeWBSensitivityImage(Lattice<casacore::DComplex>& wtImage,
      70             :                                                ImageInterface<Float>& sensitivityImage,
      71             :                                                const Matrix<Float>& sumWt,
      72             :                                                const Bool& doFFTNorm);
      73             :     //==================================================================================================
      74             :     template 
      75             :     void AWProjectWBFT::resampleCFToGrid(Array<casacore::Complex>& gwts, 
      76             :                                          VBStore& vbs, const VisBuffer2& vb);
      77             :     template 
      78             :     void AWProjectWBFT::resampleCFToGrid(Array<casacore::DComplex>& gwts, 
      79             :                                          VBStore& vbs, const VisBuffer2& vb);
      80             :     //==================================================================================================
      81             : 
      82             :   //
      83             :   //---------------------------------------------------------------
      84             :   //
      85           0 :   AWProjectWBFT::AWProjectWBFT(Int nWPlanes, Long icachesize, 
      86             :                                CountedPtr<CFCache>& cfcache,
      87             :                                CountedPtr<ConvolutionFunction>& cf,
      88             :                                CountedPtr<VisibilityResamplerBase>& visResampler,
      89             :                                Bool applyPointingOffset,
      90             :                                vector<float> pointingOffsetSigDev,
      91             :                                Bool doPBCorr,
      92             :                                Int itilesize, 
      93             :                                Float paSteps,
      94             :                                Float pbLimit,
      95             :                                Bool usezero,
      96             :                                Bool conjBeams,
      97           0 :                                Bool doublePrecGrid)
      98             :     : AWProjectFT(nWPlanes,icachesize,cfcache,cf,visResampler,applyPointingOffset,pointingOffsetSigDev,doPBCorr, itilesize,pbLimit,usezero,conjBeams,doublePrecGrid),
      99             :       //avgPBReady_p(false),
     100           0 :       resetPBs_p(true),wtImageFTDone_p(false),fieldIds_p(0),rotatedCFWts_p(),visResamplerWt_p(nullptr),oneTimeMessage_p(false)
     101             :   {
     102             :     (void)paSteps;
     103             :     //
     104             :     // Set the function pointer for FORTRAN call for GCF services.  
     105             :     // This is a pure C function pointer which FORTRAN can call.  
     106             :     // The function itself uses GCF object services.
     107             :     //
     108           0 :     paChangeDetector.reset();
     109           0 :     pbLimit_p=pbLimit;
     110           0 :     if (applyPointingOffset) doPointing=1; else doPointing=0;
     111           0 :     maxConvSupport=-1;  
     112             :     //
     113             :     // Set up the Conv. Func. disk cache manager object.
     114             :     //
     115             :     //use memory size defined in aipsrc if exists
     116           0 :     Long hostRAM = (HostInfo::memoryTotal(true)*1024); // In bytes
     117           0 :     hostRAM = hostRAM/(sizeof(Float)*2); // In complex pixels
     118           0 :     if (cachesize > hostRAM) cachesize=hostRAM;
     119             : 
     120           0 :     lastPAUsedForWtImg = MAGICPAVALUE;
     121           0 :   }
     122             :   //
     123             :   //---------------------------------------------------------------
     124             :   //
     125           0 :   AWProjectWBFT::AWProjectWBFT(const RecordInterface& stateRec)
     126           0 :     : AWProjectFT(stateRec), oneTimeMessage_p(false)
     127             :   {
     128           0 :     LogIO log_l(LogOrigin("AWProjectWBFT2", "AWProjectWBFT[R&D]"));
     129             :     // Construct from the input state record
     130             : 
     131           0 :     if (!fromRecord(stateRec)) 
     132           0 :       log_l << "Failed to create " << name() << " object." << LogIO::EXCEPTION;
     133             : 
     134           0 :     maxConvSupport=-1;
     135           0 :     visResampler_p->init(useDoubleGrid_p);
     136           0 :   }
     137             :   //
     138             :   //---------------------------------------------------------------
     139             :   //
     140           0 :   AWProjectWBFT& AWProjectWBFT::operator=(const AWProjectWBFT& other)
     141             :   {
     142           0 :     if(this!=&other) 
     143             :       {
     144           0 :         AWProjectFT::operator=(other);
     145           0 :         padding_p       =   other.padding_p;
     146           0 :         nWPlanes_p      =   other.nWPlanes_p;
     147           0 :         imageCache      =   other.imageCache;
     148           0 :         cachesize       =   other.cachesize;
     149           0 :         tilesize        =   other.tilesize;
     150           0 :         gridder         =   other.gridder;
     151           0 :         isTiled         =   other.isTiled;
     152           0 :         lattice         =   other.lattice;
     153           0 :         maxAbsData      =   other.maxAbsData;
     154           0 :         centerLoc       =   other.centerLoc;
     155           0 :         offsetLoc       =   other.offsetLoc;
     156           0 :         pointingToImage =   other.pointingToImage;
     157           0 :         usezero_p       =   other.usezero_p;
     158           0 :         doPBCorrection  =   other.doPBCorrection;
     159           0 :         maxConvSupport  =   other.maxConvSupport;
     160           0 :         avgPBReady_p= other.avgPBReady_p;
     161           0 :         resetPBs_p      =   other.resetPBs_p;
     162           0 :         wtImageFTDone_p =   other.wtImageFTDone_p;
     163           0 :         rotatedCFWts_p  =   other.rotatedCFWts_p;
     164           0 :         visResamplerWt_p=other.visResamplerWt_p; // Copy the counted pointer
     165           0 :         oneTimeMessage_p = other.oneTimeMessage_p;
     166             :     };
     167           0 :     return *this;
     168             :   };
     169             :   //
     170             :   //----------------------------------------------------------------------
     171             :   //
     172           0 :   Int AWProjectWBFT::findPointingOffsets(const VisBuffer2& vb, 
     173             :                                          Array<Float> &l_off,
     174             :                                          Array<Float> &m_off,
     175             :                                          Bool Evaluate)
     176             :   {
     177           0 :     LogIO log_l(LogOrigin("AWProjectWBFT2","findPointingOffsets[R&D]"));
     178           0 :     Int NAnt=0;
     179             :     //
     180             :     // This will return 0 if EPJ Table is not given.  Otherwise will
     181             :     // return the number of antennas it detected (from the EPJ table)
     182             :     // and the offsets in l_off and m_off.
     183             :     //
     184           0 :     NAnt = AWProjectFT::findPointingOffsets(vb,l_off,m_off,Evaluate);
     185             :     //
     186             :     // Resize the offset arrays if no pointing table was given.
     187             :     //
     188           0 :     if (NAnt <=0 )
     189             :       {
     190           0 :         NAnt=vb.subtableColumns().antenna().nrow();
     191           0 :         l_off.resize(IPosition(3,1,1,NAnt)); // Poln x NChan x NAnt 
     192           0 :         m_off.resize(IPosition(3,1,1,NAnt)); // Poln x NChan x NAnt 
     193           0 :         l_off = m_off = 0.0; 
     194             :       }
     195             :     //
     196             :     // Add field offsets to the pointing errors.
     197             :     //
     198             :     //
     199             :     // Convert the direction from image co-ordinate system and the VB
     200             :     // to MDirection.  Then convert the MDirection to Quantity so that
     201             :     // arithematic operation (subtraction) can be done.  Then use the
     202             :     // subtracted Quantity to construct another MDirection and use
     203             :     // *it's* getAngle().getValue() to extract the difference in the
     204             :     // sky direction (from image co-ordinate system) and the phase
     205             :     // center direction of the VB in radians!  
     206             :     //
     207             :     // If only VisBuffer, and DirectionCoordinate class could return
     208             :     // MDirection, and MDirection class had operator-(), the code
     209             :     // below could look more readable as:
     210             :     //  MDirection diff=vb.mDirection()-directionCoord.mDirection();
     211             :     // 
     212           0 :     CoordinateSystem coords(image->coordinates());
     213           0 :     Int directionIndex=coords.findCoordinate(Coordinate::DIRECTION);
     214           0 :     AlwaysAssert(directionIndex>=0, AipsError);
     215           0 :     DirectionCoordinate directionCoord=coords.directionCoordinate(directionIndex);
     216           0 :     MDirection vbMDir(vb.direction1()(0)),skyMDir, diff;
     217           0 :     directionCoord.toWorld(skyMDir, directionCoord.referencePixel());
     218             : 
     219           0 :     diff = MDirection(skyMDir.getAngle()-vbMDir.getAngle());
     220           0 :     l_off = l_off - (Float)diff.getAngle().getValue()(0);
     221           0 :     m_off = m_off - (Float)diff.getAngle().getValue()(1);
     222             : 
     223             :     static int firstPass=0;
     224             :     //    static int fieldID=-1;
     225           0 :     static Vector<Float> offsets0,offsets1;
     226           0 :     if (firstPass==0)
     227             :       {
     228           0 :         offsets0.resize(NAnt);
     229           0 :         offsets1.resize(NAnt);
     230           0 :         offsets0 = offsets1 = 0.0;
     231             :       }
     232           0 :     for(Int i=0;i<NAnt;i++)
     233             :       {
     234           0 :         l_off(IPosition(3,0,0,i)) = l_off(IPosition(3,0,0,i)) + offsets0(i)/2.062642e+05;
     235           0 :         m_off(IPosition(3,0,0,i)) = m_off(IPosition(3,0,0,i)) + offsets1(i)/2.062642e+05;
     236             :       }
     237             : 
     238           0 :     if (firstPass==0) 
     239             :       {
     240             : //       cout << (Float)(directionCoord.referenceValue()(0)) << " "
     241             : //            << (Float)(directionCoord.referenceValue()(1)) << endl;
     242             : //       cout << vb.direction1()(0).getAngle().getValue()(0) << " "
     243             : //            << vb.direction1()(0).getAngle().getValue()(1) << endl;
     244             : //      cout << l_off << endl;
     245             : //      cout << m_off << endl;
     246             :        }
     247           0 :      firstPass++;
     248           0 :     return NAnt;
     249           0 :   }
     250             :   //
     251             :   //---------------------------------------------------------------
     252             :   //
     253             :   // void AWProjectWBFT::normalizeAvgPB()
     254             :   // {
     255             :   //   LogIO log_l(LogOrigin("AWProjectWBFT2","normalizeAvgPB[R&D]"));
     256             :   //   // We accumulated normalized PBs.  So don't normalize the average
     257             :   //   // PB.
     258             :   //   pbNormalized_p = false;
     259             :     
     260             :   // }
     261             :   //
     262             :   //---------------------------------------------------------------
     263             :   // For wide-band case, this just tells the user that the sensitivity
     264             :   // image will be computed during the first gridding cycle.
     265             :   //
     266             :   // Weights image (sum of convolution functions) is accumulated
     267             :   // during gridding.  At the end of the gridding cycle, the weight
     268             :   // image is FT'ed (using ftWeightImage()) and properly normalized
     269             :   // and converted to sensitivity image (using
     270             :   // makeSensitivityImage()).  These methods are triggred in the first
     271             :   // call to getImage().  In subsequent calls to getImage() these
     272             :   // calls are NoOps.
     273             :   //
     274           0 :   void AWProjectWBFT::makeSensitivityImage(const VisBuffer2&,
     275             :                                            const ImageInterface<Complex>& /*Complex imageTemplate*/,
     276             :                                            ImageInterface<Float>& /*sensitivityImage*/)
     277             :   {
     278           0 :     if (avgPBReady_p == false)
     279             :       {
     280           0 :         if (oneTimeMessage_p == false)
     281             :           {
     282           0 :             LogIO log_l(LogOrigin("AWProjectWBFT2", "makeSensitivityImage(Complex)[R&D]"));
     283           0 :             log_l << "Setting up for weights accumulation ";
     284           0 :             if (sensitivityPatternQualifierStr_p != "") log_l << "for term " << sensitivityPatternQualifier_p << " ";
     285             :             log_l << "during gridding to compute sensitivity pattern."
     286             :                   << endl
     287             :                   << "Consequently, the first gridding cycle will be slower than the subsequent ones." 
     288           0 :                   << LogIO::WARN;
     289           0 :             oneTimeMessage_p=true;
     290           0 :           }
     291             :       }
     292           0 :   }
     293           0 :     void AWProjectWBFT::makeSensitivityImage(const VisBuffer2&,
     294             :                                              const ImageInterface<DComplex>& /* DComplex imageTemplate*/,
     295             :                                              ImageInterface<Float>& /*sensitivityImage*/)
     296             :     {
     297           0 :       if (avgPBReady_p == false)
     298             :         {
     299           0 :           if (oneTimeMessage_p == false)
     300             :             {
     301           0 :               LogIO log_l(LogOrigin("AWProjectWBFT2", "makeSensitivityImage(DComplex)[R&D]"));
     302           0 :               log_l << "Setting up for weights accumulation ";
     303           0 :               if (sensitivityPatternQualifierStr_p != "") log_l << "for term " << sensitivityPatternQualifier_p << " ";
     304             :               log_l << "during gridding to compute sensitivity pattern."
     305             :                     << endl
     306             :                     << "Consequently, the first gridding cycle will be slower than the subsequent ones."
     307           0 :                     << LogIO::WARN;
     308           0 :               oneTimeMessage_p=true;
     309           0 :             }
     310             :         }
     311           0 :     }
     312             :   //
     313             :   //---------------------------------------------------------------
     314             :   // 
     315             :     template <class T>
     316           0 :   void AWProjectWBFT::ftWeightImage(Lattice<T>& wtImage, 
     317             :                                     const Matrix<Float>& sumWt,
     318             :                                     const Bool& doFFTNorm)
     319             :   {
     320           0 :     LogIO log_l(LogOrigin("AWProjectWBFT2", "ftWeightImage[R&D]"));
     321           0 :     if (wtImageFTDone_p) return;
     322             : 
     323           0 :     if ((sumWt.shape().nelements() < 2) || 
     324           0 :         (sumWt.shape()(0) != wtImage.shape()(2)) || 
     325           0 :         (sumWt.shape()(1) != wtImage.shape()(3)))
     326           0 :       log_l << "Sum of weights per poln and chan is required" << LogIO::EXCEPTION;
     327             :     //
     328             :     // Use only the amplitude of the gridded weights.  LatticeExpr
     329             :     // classes while useful, appear to be too strict about types (the
     330             :     // code below will not compile if the abs(wtImage) is not
     331             :     // converted back to a complex type).
     332             : 
     333           0 :     LatticeFFT::cfft2d(wtImage,false);
     334           0 :     wtImageFTDone_p=true;
     335             : 
     336           0 :     Int sizeX=wtImage.shape()(0), sizeY=wtImage.shape()(1);
     337             : 
     338           0 :     Array<T> wtBuf; wtImage.get(wtBuf,false);
     339           0 :     ArrayLattice<T> wtLat(wtBuf,true);
     340             :     //
     341             :     // Copy one 2D plane at a time, normalizing by the sum of weights
     342             :     // and possibly 2D FFT.
     343             :     //
     344             :     // Set up Lattice iterators on wtImage and sensitivityImage
     345             :     //
     346           0 :     IPosition axisPath(4, 0, 1, 2, 3);
     347           0 :     IPosition cursorShape(4, sizeX, sizeY, 1, 1);
     348             : 
     349           0 :     LatticeStepper wtImStepper(wtImage.shape(), cursorShape, axisPath);
     350           0 :     LatticeIterator<T> wtImIter(wtImage, wtImStepper);
     351             :     //
     352             :     // Iterate over channel and polarization axis
     353             :     //
     354           0 :     if (!doFFTNorm) sizeX=sizeY=1;
     355             :     //
     356             :     // Normalize each frequency and polarization plane of the complex
     357             :     // sensitivity pattern
     358             :     //
     359             :     // getSumOfCFWeights() returns the sum-of-weight appropriate for
     360             :     // computing sensitivity patterns (which could be different from
     361             :     // the data-sum-of-weights.
     362             :     //
     363             : 
     364           0 :     for(wtImIter.reset(); !wtImIter.atEnd(); wtImIter++)
     365             :       {
     366           0 :         wtImIter.rwCursor() = (wtImIter.rwCursor()
     367           0 :                                *Float(sizeX)*Float(sizeY));
     368             :       }
     369           0 :   }
     370             :   //
     371             :   //---------------------------------------------------------------
     372             :   // 
     373             :     template <class T>
     374           0 :   void AWProjectWBFT::makeWBSensitivityImage(Lattice<T>& wtImage,
     375             :                                              ImageInterface<Float>& sensitivityImage,
     376             :                                              const Matrix<Float>& sumWt,
     377             :                                              const Bool& doFFTNorm)
     378             :   {
     379           0 :     if (avgPBReady_p) return;
     380           0 :     LogIO log_l(LogOrigin("AWProjectWBFT2", "makeWBSensitivityImage[R&D]"));
     381             : 
     382           0 :     ftWeightImage(wtImage, sumWt, doFFTNorm);
     383             : 
     384           0 :     if (useDoubleGrid_p)
     385             :       {
     386           0 :         sensitivityImage.resize(griddedWeights_D.shape()); 
     387           0 :         sensitivityImage.setCoordinateInfo(griddedWeights_D.coordinates());
     388             :       }
     389             :     else
     390             :       {
     391           0 :         sensitivityImage.resize(griddedWeights.shape()); 
     392           0 :         sensitivityImage.setCoordinateInfo(griddedWeights.coordinates());
     393             :       }
     394             :     //
     395             :     // Rest of the code below is to (1) average the poln planes of the
     396             :     // weight image for each freq. channel, and (2) copy the averaged
     397             :     // value to the all the poln planes for each freq. channels of the
     398             :     // sensitivity image.  
     399             :     //
     400             :     // Set up Lattice iterator on wtImage for averaging all poln
     401             :     // planes and writing the result the only the first poln plane.
     402             :     //
     403           0 :     IPosition axisPath(2, 2, 3); // Step through the Poln (2) and Freq (3) axis.
     404           0 :     IPosition cursorShapeWt(4, wtImage.shape()(0), wtImage.shape()(1), 1, 1);
     405             : 
     406           0 :     LatticeStepper wtImStepper(wtImage.shape(), cursorShapeWt, axisPath);
     407           0 :     LatticeIterator<T> wtImIter(wtImage, wtImStepper);
     408           0 :     int nPolPlanes=wtImage.shape()(2);
     409             :     // First average all poln planes and write the result back to the first poln plane.
     410           0 :     for(wtImIter.reset(); !wtImIter.atEnd(); /*increment is inside the for-loop below*/)
     411             :     {
     412           0 :       Matrix<T> tmpWt(wtImIter.rwMatrixCursor().shape());
     413           0 :       ArrayLattice<T> tt(tmpWt,true);
     414           0 :       for(int i=0;i<nPolPlanes;i++)
     415             :         {
     416           0 :           Matrix<T> tmp0_ref;tmp0_ref.reference(wtImIter.rwMatrixCursor().nonDegenerate());
     417           0 :           ArrayLattice<T> p0(tmp0_ref,true); //Make ArrayLattice from Array by refence
     418           0 :           LatticeExpr<T> le(tt+p0);
     419           0 :           tt.copyData(le); 
     420           0 :           wtImIter++;
     421             :         }
     422           0 :       LatticeExpr<T> le(tt/nPolPlanes);
     423           0 :       tt.copyData(le); 
     424             :     }
     425             :     
     426           0 :     IPosition cursorShape(4, sensitivityImage.shape()(0), sensitivityImage.shape()(1), 1, 1);
     427           0 :     LatticeStepper senImStepper(sensitivityImage.shape(), cursorShape, axisPath);
     428           0 :     LatticeIterator<Float> senImIter(sensitivityImage, senImStepper);
     429             :     //
     430             :     // Copy the real part of the average of all planes of the wtImage
     431             :     // to all the planes of the sensitivity image (senImage).
     432             :     //
     433           0 :     for(wtImIter.reset(),senImIter.reset(); !wtImIter.atEnd();/*increment is inside the first for-loop below*/)
     434             :       {
     435             :         // Extract the first polarization plane from the weight image. 
     436           0 :         Matrix<T> wt_ref;wt_ref.reference(wtImIter.rwMatrixCursor().nonDegenerate());
     437           0 :         ArrayLattice<T> p0(wt_ref,true);
     438           0 :         for (int i=0;i<nPolPlanes;i++) wtImIter++; // Skip the rest of the poln planes
     439             : 
     440           0 :         for(int i=0;i<sensitivityImage.shape()(2);i++)
     441             :           {
     442             :             // // Now replace the polarization planes with their average.  REVIEW THIS FOR FM CASE.
     443           0 :             Matrix<Float> tmp;tmp.reference(senImIter.rwMatrixCursor().nonDegenerate());
     444           0 :             ArrayLattice<Float> tt(tmp,true); //Make ArrayLattice from Array by refence
     445           0 :             LatticeExpr<Float> le(abs(p0));
     446           0 :             tt.copyData(le); 
     447             : 
     448           0 :             senImIter++;
     449             :           }
     450             :       }
     451             : 
     452           0 :     if (tt_pp == "")
     453           0 :       cfCache_p->flush(sensitivityImage,sensitivityPatternQualifierStr_p);
     454             : 
     455           0 :     pbNormalized_p=false;
     456           0 :     resetPBs_p=false;
     457             : 
     458           0 :     avgPBReady_p=true;
     459           0 :   }
     460             :   //
     461             :   //---------------------------------------------------------------
     462             :   //
     463             :   // Convert the gridded visibilities to image. This implements the
     464             :   // basic 2D transform (vC-Z Theorem) using the FFT.
     465             :   //
     466             :   // This specialization of getImage() exists since the sensitivity
     467             :   // pattern in this FTMachine is computed as the FT of the gridded
     468             :   // weights (convolution functions).  The gridded weights are
     469             :   // available along with the gridded data at the end of the gridding
     470             :   // cycle.  This method first converts the gridded weights to
     471             :   // sensitivity image and then calls AWProjectFT::getImage(), which
     472             :   // in-turn calls normalizeImage() with the sensitivityImage and the
     473             :   // sum of weights.
     474             :   //
     475           0 :   ImageInterface<Complex>& AWProjectWBFT::getImage(Matrix<Float>& weights,
     476             :                                                    Bool fftNormalization) 
     477             :   {
     478           0 :     AlwaysAssert(image, AipsError);
     479           0 :     LogIO log_l(LogOrigin("AWProjectWBFT2", "getImage[R&D]"));
     480             : 
     481           0 :     weights.resize(sumWeight.shape());
     482           0 :     convertArray(weights, sumWeight);//I suppose this converts a
     483             :                                      //Matrix<Double> (sumWeights) to
     484             :                                      //Matrix<Float> (weights).  Why
     485             :                                      //is this conversion required?
     486             :                                      //--SB (Dec. 2010)
     487             :     //
     488             :     // Compute the sensitivity image as FT of the griddedWeigths.
     489             :     // Return the result in avgPB_p.  Cache it in the cfCache_p
     490             :     // object.  And raise the avgPBReady_p flag so that this becomes a
     491             :     // null call the next time around.
     492           0 :     if (useDoubleGrid_p)
     493           0 :       makeWBSensitivityImage(griddedWeights_D, *avgPB_p, weights, true);
     494             :     else
     495           0 :       makeWBSensitivityImage(griddedWeights, *avgPB_p, weights, true);
     496             :     //
     497             :     // This calls the overloadable method normalizeImage() which
     498             :     // normalizes the raw image by the sensitivty pattern (avgPB_p).
     499             :     //
     500           0 :     AWProjectFT::getImage(weights,fftNormalization);
     501             :         
     502           0 :     return *image;
     503           0 :   }
     504             :   //
     505             :   //---------------------------------------------------------------
     506             :   //
     507             :   // Initialize the FFT to the Sky. Here we have to setup and
     508             :   // initialize the grid.
     509             :   //
     510           0 :   void AWProjectWBFT::initializeToSky(ImageInterface<Complex>& iimage,
     511             :                                    Matrix<Float>& weight,
     512             :                                    const VisBuffer2& vb)
     513             :   {
     514           0 :     LogIO log_l(LogOrigin("AWProjectWBFT2","initializeToSky[R&D]"));
     515           0 :     AWProjectFT::initializeToSky(iimage,weight,vb);
     516             : 
     517           0 :     if (resetPBs_p)
     518             :       {
     519           0 :         if (useDoubleGrid_p)
     520             :           {
     521           0 :             griddedWeights_D.resize(iimage.shape()); 
     522           0 :             griddedWeights_D.setCoordinateInfo(iimage.coordinates());
     523           0 :             griddedWeights_D.set(0.0);
     524           0 :             pbPeaks.resize(griddedWeights_D.shape()(2));
     525           0 :             pbPeaks.set(0.0);
     526             :           }
     527             :         else
     528             :           {
     529           0 :             griddedWeights.resize(iimage.shape()); 
     530           0 :             griddedWeights.setCoordinateInfo(iimage.coordinates());
     531           0 :             griddedWeights.set(0.0);
     532           0 :             pbPeaks.resize(griddedWeights.shape()(2));
     533           0 :             pbPeaks.set(0.0);
     534             :           }
     535             : 
     536           0 :         resetPBs_p=false;
     537             :       }
     538             : 
     539           0 :     std::tuple<int, double>cubeinfo(1,-1.0);    
     540             :     double freqofBegChan;
     541           0 :     spectralCoord_p.toWorld(freqofBegChan, 0.0);
     542             :         
     543           0 :     cubeinfo=std::make_tuple(iimage.shape()(3),freqofBegChan);
     544             : 
     545             :     ///load AVGPB is quite the memory consumer for cubes as it will load the whole cube in memory a couple of times even.
     546             :     //cerr << "###Avoiding loading of avgPB " << avgPBReady_p << endl;
     547             :     ////TESTOO need to oveload this init in HPG
     548           0 :     if(!avgPBReady_p)
     549           0 :       avgPBReady_p = (cfCache_p->loadAvgPB(avgPB_p,sensitivityPatternQualifierStr_p, cubeinfo) != CFDefs::NOTCACHED);
     550             :     
     551           0 :     if(avgPBReady_p){
     552           0 :         LatticeExprNode le( max( *avgPB_p ) );
     553           0 :         Float avgPB_max=le.getFloat();
     554             :         
     555           0 :         if(avgPB_max <= 0.0) avgPBReady_p = false;
     556           0 :     }
     557             :     // Need to grid the weighted Convolution Functions to make the sensitivity pattern.
     558           0 :     if (!avgPBReady_p)
     559             :       {
     560             :         // Make a copy of the re-sampler and set it up.
     561           0 :         if (visResamplerWt_p.null()) visResamplerWt_p = visResampler_p->clone();
     562           0 :         visResamplerWt_p = visResampler_p;
     563           0 :         visResamplerWt_p->setMaps(chanMap, polMap);
     564           0 :         if (useDoubleGrid_p)
     565             :           {
     566           0 :             Array<DComplex> gwts; Bool removeDegenerateAxis=false;
     567           0 :             griddedWeights_D.get(gwts, removeDegenerateAxis);
     568           0 :             visResamplerWt_p->initializeToSky(gwts, sumCFWeight); //A NoOp right now.
     569           0 :           }
     570             :         else
     571             :           {
     572           0 :             Array<Complex> gwts; Bool removeDegenerateAxis=false;
     573           0 :             griddedWeights.get(gwts, removeDegenerateAxis);
     574           0 :             visResamplerWt_p->initializeToSky(gwts, sumCFWeight); //A NoOp right now.
     575           0 :           }
     576             :       }
     577           0 :   }
     578             :   //
     579             :   //---------------------------------------------------------------
     580             :   //
     581           0 :   void AWProjectWBFT::finalizeToSky()
     582             :   {
     583           0 :     LogIO log_l(LogOrigin("AWProjectWBFT2", "finalizeToSky[R&D]"));
     584           0 :     AWProjectFT::finalizeToSky();
     585             : 
     586             :     
     587           0 :     if(name()=="AWProjectWBFTHPG")
     588           0 :       return;
     589             :     ////
     590           0 :     if(!visResamplerWt_p)
     591           0 :       return;
     592             : 
     593             :     //
     594             :     // SB: Not sure why the follwing if-stmt (not by SB) needs to be
     595             :     // in this class.  This be simply avoided by overloading this
     596             :     // method in the AWProjectWBFTHPG class making the NoOp obvious
     597             :     // for that class, and easily extendable & maintainable.
     598             :     //
     599             :    
     600             : 
     601           0 :      if (!avgPBReady_p) 
     602             :       {
     603           0 :         if (useDoubleGrid_p)
     604             :           {
     605           0 :             Array<DComplex> gwts; Bool removeDegenerateAxis=false;
     606           0 :             griddedWeights_D.get(gwts, removeDegenerateAxis);
     607           0 :             visResamplerWt_p->finalizeToSky(gwts, sumCFWeight);
     608           0 :             visResamplerWt_p->releaseBuffers();
     609           0 :           }
     610             :         else
     611             :           {
     612           0 :             Array<Complex> gwts; Bool removeDegenerateAxis=false;
     613           0 :             griddedWeights.get(gwts, removeDegenerateAxis);
     614           0 :             visResamplerWt_p->finalizeToSky(gwts, sumCFWeight);
     615           0 :             visResamplerWt_p->releaseBuffers();
     616           0 :           }
     617             :       }
     618             :     
     619           0 :     visResampler_p->runTimeG_p
     620           0 :       =visResampler_p->runTimeG1_p
     621           0 :       =visResampler_p->runTimeG2_p
     622           0 :       =visResampler_p->runTimeG3_p
     623           0 :       =visResampler_p->runTimeG4_p
     624           0 :       =visResampler_p->runTimeG5_p
     625           0 :       =visResampler_p->runTimeG6_p
     626           0 :       =visResampler_p->runTimeG7_p
     627           0 :       =0.0;
     628           0 :     runTime1_p=0;
     629           0 :   }
     630             :   //
     631             :   //---------------------------------------------------------------
     632             :   // Method sets up the inputs for the VisResampler::DataToGrid()
     633             :   // method for gridding the CFs at the origin of the UVW-plane.  This
     634             :   // includes application of pointing offset correction and any other
     635             :   // term that might be included in VB2CFBMap::makeVBRow2CFBMap()
     636             :   // method.
     637             :     template <class T>
     638           0 :     void AWProjectWBFT::resampleCFToGrid(Array<T>& gwts, 
     639             :                                          VBStore& vbs, const VisBuffer2& vb)
     640             :     {
     641           0 :       visResamplerWt_p->copy(*visResampler_p);
     642             :     
     643           0 :       po_p->fetchPointingOffset(*image, vb, doPointing);
     644           0 :       vb2CFBMap_p->makeVBRow2CFBMap(*cfwts2_p,vb,
     645             :                                     paChangeDetector.getParAngleTolerance(),
     646           0 :                                     chanMap,polMap,po_p);
     647           0 :       convFuncCtor_p->prepareConvFunction(vb,*vb2CFBMap_p);
     648             :       //
     649             :       // Set the uvw array to zero-sized array and dopsf=true.
     650             :       // uvw.nelements()==0 is a hint to the re-sampler to put the
     651             :       // gridded weights at the origin of the uv-grid. dopsf=true so
     652             :       // that CF*Wts are accumulated (as against CF*Wts*Vis).
     653             :       //
     654             :       // Receive the sum-of-weights in a dummy array.
     655           0 :       Matrix<Double> uvwOrigin;
     656           0 :       vbs.uvw_p.reference(uvwOrigin); 
     657           0 :       Bool dopsf_l=true;
     658           0 :       vbs.accumCFs_p=((vbs.uvw_p.nelements() == 0) && dopsf_l);
     659           0 :       vbs.ftmType_p=casa::refim::FTMachine::WEIGHT;  
     660           0 :       Int nDataChan = vbs.flagCube_p.shape()[1];
     661             :       
     662           0 :       visResamplerWt_p->setVB2CFMap(vb2CFBMap_p);
     663           0 :       vbs.startChan_p = 0; vbs.endChan_p = nDataChan;
     664             : 
     665           0 :       visResamplerWt_p->DataToGrid(gwts, vbs, sumCFWeight, dopsf_l); 
     666           0 :     }
     667             :   //
     668             :   //---------------------------------------------------------------
     669             :   // Methods to accumulate data on the grid.  If necessary, also
     670             :   // trigger the accumulation of CFs via ::resampleCFToGrid() method.
     671             :   //
     672           0 :   void AWProjectWBFT::resampleDataToGrid(Array<Complex>& griddedData_l,
     673             :                                          VBStore& vbs, const VisBuffer2& vb, 
     674             :                                          Bool& dopsf) 
     675             :   {
     676           0 :     AWProjectFT::resampleDataToGrid(griddedData_l,vbs,vb,dopsf);
     677           0 :     if (!avgPBReady_p)
     678             :       {
     679             :         //
     680             :         // Get a reference to the pixels of griddedWeights (a
     681             :         // TempImage!)
     682             :         //
     683           0 :         Array<Complex> gwts; Bool removeDegenerateAxis=false;
     684           0 :         griddedWeights.get(gwts, removeDegenerateAxis);
     685           0 :         resampleCFToGrid(gwts, vbs, vb);
     686           0 :       }
     687           0 :   };
     688             :   //
     689             :   //---------------------------------------------------------------
     690             :   //
     691           0 :   void AWProjectWBFT::resampleDataToGrid(Array<DComplex>& griddedData_l,
     692             :                                          VBStore& vbs, const VisBuffer2& vb, 
     693             :                                          Bool& dopsf) 
     694             :   {
     695           0 :     AWProjectFT::resampleDataToGrid(griddedData_l,vbs,vb,dopsf);
     696             :     
     697           0 :     if (!avgPBReady_p)
     698             :       {
     699             :         //
     700             :         // Get a reference to the pixels of griddedWeights (a
     701             :         // TempImage!)
     702             :         //
     703           0 :         Array<DComplex> gwts; Bool removeDegenerateAxis=false;
     704           0 :         griddedWeights_D.get(gwts, removeDegenerateAxis);
     705           0 :         resampleCFToGrid(gwts, vbs, vb);
     706           0 :       }
     707           0 :   };
     708             :     
     709             :     ////-----------------------------------------------------------------
     710             :     // SB: Is this functionality not served by the
     711             :     // ::resampleCFToGrid() method above?  Recommend that that be used
     712             :     // (or modifed as required) to ensure all mathematical terms are
     713             :     // included.
     714             :     //
     715           0 :  void  AWProjectWBFT::gridImgWeights(const VisBuffer2& vb)
     716             :  {
     717           0 :    findConvFunction(*image, vb);
     718             :    //cerr << "IN gridWTImage" << endl;
     719           0 :    if(avgPBReady_p)
     720           0 :      return;
     721             :    else
     722           0 :      avgPB_p=nullptr;  ///make sure it is not pointing to anything
     723             : 
     724             :    // This does WEIGHTs gridding via the framework route 
     725             :    // (set ftmType and use ::put() for *all* gridding)
     726           0 :    ftmType_p=casa::refim::FTMachine::WEIGHT;
     727           0 :    put(vb,-1,false);
     728           0 :    return;
     729             :    
     730             :    // try
     731             :    //   {
     732             :    //     findConvFunction(*image, vb);
     733             :    //      if(avgPBReady_p)
     734             :    //        return;
     735             :    //   }
     736             :    // catch(AipsError& x)
     737             :    //   {
     738             :    //     LogIO log_l(LogOrigin("AWProjectFT2", "put[R&D]"));
     739             :    //     log_l << x.getMesg() << LogIO::WARN;
     740             :    //     return;
     741             :    //   }
     742             :    // Matrix<Float> imagingweight;
     743             :    // getImagingWeight(imagingweight, vb);
     744             :    // matchChannel(vb);
     745             :    // Cube<Complex> data;
     746             :    // //Fortran gridder need the flag as ints 
     747             :    // Cube<Int> flags;
     748             :    // Matrix<Float> elWeight;
     749             :    
     750             :    // interpolateFrequencyTogrid(vb, imagingweight,data, flags , elWeight, FTMachine::PSF);
     751             :    // Matrix<Double> uvw(negateUV(vb));
     752             :    // Vector<Double> dphase(vb.nRows());
     753             :    // dphase=0.0;
     754             :    // doUVWRotation_p=true;
     755             :    // VBStore vbs;
     756             :    // Vector<Int> gridShape = griddedData2.shape().asVector();
     757             :    // setupVBStore(vbs,vb, elWeight,data,uvw,flags, dphase, True /*dopsf*/,gridShape);
     758             :    // if (useDoubleGrid_p){
     759             :    //           Array<DComplex> gwts; Bool removeDegenerateAxis=false;
     760             :    //   griddedWeights_D.get(gwts, removeDegenerateAxis);
     761             :    //   resampleCFToGrid(gwts, vbs, vb);
     762             :         
     763             :    //  }
     764             :    // else{
     765             :    //   Array<Complex> gwts; Bool removeDegenerateAxis=false;
     766             :    //   griddedWeights.get(gwts, removeDegenerateAxis);
     767             :    //   resampleCFToGrid(gwts, vbs, vb);
     768             :      
     769             :    // }
     770             :  }
     771             :   
     772           0 :   void AWProjectWBFT::setCFCache(CountedPtr<CFCache>& cfc, const Bool resetCFC) 
     773             :   {
     774           0 :     if (resetCFC) cfCache_p = cfc;
     775           0 :     if (!cfCache_p.null())
     776             :       {
     777           0 :         cfs2_p = CountedPtr<CFStore2>(&cfCache_p->memCache2_p[0],false);//new CFStore2;
     778           0 :         cfwts2_p =  CountedPtr<CFStore2>(&cfCache_p->memCacheWt2_p[0],false);//new CFStore2;
     779             :         
     780           0 :         avgPBReady_p=false;
     781             :       }
     782           0 :   }
     783             : 
     784             : } //# NAMESPACE CASA - END
     785             : };

Generated by: LCOV version 1.16