LCOV - code coverage report
Current view: top level - synthesis/MeasurementEquations - MatrixCleaner.h (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 5 9 55.6 %
Date: 2023-11-06 10:06:49 Functions: 5 9 55.6 %

          Line data    Source code
       1             : //# Cleaner.h: this defines Cleaner a class for doing convolution
       2             : //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
       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 Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library 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             : //#
      27             : //# $Id: LatticeCleaner.h 20739 2009-09-29 01:15:15Z Malte.Marquarding $
      28             : 
      29             : #ifndef SYNTHESIS_MATRIXCLEANER_H
      30             : #define SYNTHESIS_MATRIXCLEANER_H
      31             : 
      32             : //# Includes
      33             : #include <casacore/casa/aips.h>
      34             : #include <casacore/casa/Quanta/Quantum.h>
      35             : #include <casacore/lattices/Lattices/TempLattice.h>
      36             : #include <casacore/casa/Arrays/IPosition.h>
      37             : #include <casacore/casa/Arrays/Vector.h>
      38             : #include <casacore/casa/Containers/Block.h>
      39             : #include <casacore/lattices/LatticeMath/LatticeCleaner.h>
      40             : #include <casacore/casa/Arrays/ArrayFwd.h>
      41             : 
      42             : namespace casa { //# NAMESPACE CASA - BEGIN
      43             : 
      44             : //# Forward Declarations
      45             : class MatrixNACleaner;
      46             : // <summary>A copy of casacore::LatticeCleaner but just using 2-D matrices</summary>
      47             : // <synopsis> It is a mimic of the casacore::LatticeCleaner class but avoid a lot of
      48             : // of the lattice to array and back copies and uses openmp in the obvious places
      49             : // </synopsis>
      50             : 
      51             : // <summary>A class for doing multi-dimensional cleaning</summary>
      52             : 
      53             : // <use visibility=export>
      54             : 
      55             : // <reviewed reviewer="" date="yyyy/mm/dd" tests="tLatticeCleaner">
      56             : // </reviewed>
      57             : 
      58             : // <prerequisite>
      59             : //  <li> The mathematical concept of deconvolution
      60             : // </prerequisite>
      61             : //
      62             : // <etymology>
      63             : 
      64             : // The MatrixCleaner class will deconvolve 2-D arrays of floats.
      65             : 
      66             : // </etymology>
      67             : //
      68             : // <synopsis>
      69             : // This class will perform various types of Clean deconvolution
      70             : // on Lattices.
      71             : //
      72             : // </synopsis>
      73             : //
      74             : // <example>
      75             : // <srcblock>
      76             : // </srcblock>
      77             : // </example>
      78             : //
      79             : // <motivation>
      80             : // </motivation>
      81             : //
      82             : // <thrown>
      83             : // <li> casacore::AipsError: if psf has more dimensions than the model.
      84             : // </thrown>
      85             : //
      86             : // <todo asof="yyyy/mm/dd">
      87             : // </todo>
      88             : 
      89             : class MatrixCleaner
      90             : {
      91             : public:
      92             : 
      93             :   // Create a cleaner : default constructor
      94             :   MatrixCleaner();
      95             : 
      96             :   // Create a cleaner for a specific dirty image and PSF
      97             :   MatrixCleaner(const casacore::Matrix<casacore::Float> & psf, const casacore::Matrix<casacore::Float> & dirty);
      98             : 
      99             :   // The copy constructor uses reference semantics
     100             :   MatrixCleaner(const MatrixCleaner& other);
     101             : 
     102             :   // The assignment operator also uses reference semantics
     103             :   MatrixCleaner & operator=(const MatrixCleaner & other);
     104             : 
     105             :   // The destructor does nothing special.
     106             :   ~MatrixCleaner();
     107             : 
     108             :   //just define the scales...nothing else is done
     109             :   //the user will need to call setPsf+makePsfScales+setDirty+makeDirtyScales
     110             :   //to be in a good state to clean.
     111             :   void defineScales(const casacore::Vector<casacore::Float>& scales);
     112             : 
     113             :   //Set the dirty image without calculating convolutions..
     114             :   //can be done by calling  makeDirtyScales or setscales if one want to redo the
     115             :   //psfscales too.
     116             :   void setDirty(const casacore::Matrix<casacore::Float>& dirty);
     117             :   //Calculate the convolutions for the dirt
     118             :   //Obviously the
     119             :   void makeDirtyScales();
     120             :   // Update the dirty image only (equiv of setDirty + makeDirtyScales)
     121             :   void update(const casacore::Matrix<casacore::Float> & dirty);
     122             : 
     123             :   //change the psf
     124             :   //don't forget to redo the setscales or run makePsfScales,
     125             :   //followed by makeDirtyScales
     126             :   void setPsf(const casacore::Matrix<casacore::Float>& psf);
     127             :   //calculate the convolutions of the psf
     128             :   void makePsfScales();
     129             : 
     130             :   // Set a number of scale sizes. The units of the scale are pixels.
     131             :   // The 2 functions below assume you have the dirty image and the psf set
     132             :   // the convolutions are calculated automatically and the masks ones too
     133             :   // if it is set ....kept so as to be compatible function wise with LatticeCleaner
     134             :   casacore::Bool setscales(const casacore::Int nscales, const casacore::Float scaleInc=1.0);
     135             : 
     136             :   // Set a specific set of scales
     137             :   casacore::Bool setscales(const casacore::Vector<casacore::Float> & scales);
     138             : 
     139             : 
     140             : 
     141             :   // Set up control parameters
     142             :   // cleanType - type of the cleaning algorithm to use (HOGBOM, MULTISCALE)
     143             :   // niter - number of iterations
     144             :   // gain - loop gain used in cleaning (a fraction of the maximum
     145             :   //        subtracted at every iteration)
     146             :   // aThreshold - absolute threshold to stop iterations
     147             :   // fThreshold - fractional threshold (i.e. given w.r.t. maximum residual)
     148             :   //              to stop iterations. This parameter is specified as
     149             :   //              casacore::Quantity so it can be given in per cents.
     150             :   // choose - unused at the moment, specify false. Original meaning is
     151             :   // to allow interactive decision on whether to continue iterations.
     152             :   // This method always returns true.
     153             :   casacore::Bool setcontrol(casacore::CleanEnums::CleanType cleanType, const casacore::Int niter,
     154             :                   const casacore::Float gain, const casacore::Quantity& aThreshold,
     155             :                   const casacore::Quantity& fThreshold);
     156             : 
     157             :   // This version of the method disables stopping on fractional threshold
     158             :   casacore::Bool setcontrol(casacore::CleanEnums::CleanType cleanType, const casacore::Int niter,
     159             :                   const casacore::Float gain, const casacore::Quantity& threshold);
     160             : 
     161             :   // return how many iterations we did do
     162           0 :   casacore::Int iteration() const { return itsIteration; }
     163          84 :   casacore::Int numberIterations() const { return itsIteration; }
     164             : 
     165             :   // what iteration number to start on
     166          84 :   void startingIteration(const casacore::Int starting = 0) {itsStartingIter = starting; }
     167             : 
     168             :  //Total flux accumulated so far
     169             :   casacore::Float totalFlux() const {return itsTotalFlux;}
     170             : 
     171             : 
     172             :   // Clean an image.
     173             :   //return value gives you a hint of what's happening
     174             :   //  1 = converged
     175             :   //  0 = not converged but behaving normally
     176             :   // -1 = not converged and stopped on cleaning consecutive smallest scale
     177             :   // -2 = not converged and either large scale hit negative or diverging
     178             :   // -3 = clean is diverging rather than converging
     179             :   casacore::Int clean(casacore::Matrix<casacore::Float> & model, casacore::Bool doPlotProgress=false);
     180             : 
     181             :   // Set the mask
     182             :   // mask - input mask lattice
     183             :   // maskThreshold - if positive, the value is treated as a threshold value to determine
     184             :   // whether a pixel is good (mask value is greater than the threshold) or has to be
     185             :   // masked (mask value is below the threshold). Negative threshold switches mask clipping
     186             :   // off. The mask value is used to weight the flux during cleaning. This mode is used
     187             :   // to implement cleaning based on the signal-to-noise as opposed to the standard cleaning
     188             :   // based on the flux. The default threshold value is 0.9, which ensures the behavior of the
     189             :   // code is exactly the same as before this parameter has been introduced.
     190             :   void setMask(casacore::Matrix<casacore::Float> & mask, const casacore::Float& maskThreshold = 0.9);
     191             :   // Call the function below if the psf is changed ..no need to setMask again
     192             :   casacore::Bool makeScaleMasks();
     193             : 
     194             :   // remove the mask;
     195             :   // useful when keeping object and sending a new dirty image to clean
     196             :   // one can set another mask then
     197             :   void unsetMask();
     198             : 
     199             :   // Tell the algorithm to NOT clean just the inner quarter
     200             :   // (This is useful when multiscale clean is being used
     201             :   // inside a major cycle for MF or WF algorithms)
     202             :   // if true, the full image deconvolution will be attempted
     203          84 :   void ignoreCenterBox(casacore::Bool huh) { itsIgnoreCenterBox = huh; }
     204             : 
     205             :   // Consider the case of a point source:
     206             :   // the flux on all scales is the same, and the first scale will be chosen.
     207             :   // Now, consider the case of a point source with a *little* bit of extended structure:
     208             :   // thats right, the largest scale will be chosen.  In this case, we should provide some
     209             :   // bias towards the small scales, or against the large scales.  We do this in
     210             :   // an ad hoc manner, multiplying the maxima found at each scale by
     211             :   // 1.0 - itsSmallScaleBias * itsScaleSizes(scale)/itsScaleSizes(nScalesToClean-1);
     212             :   // Typical bias values range from 0.2 to 1.0.
     213         133 :   void setSmallScaleBias(const casacore::Float x=0.5) { itsSmallScaleBias = x; }
     214             : 
     215             :   // During early iterations of a cycled casacore::MS Clean in mosaicing, it common
     216             :   // to come across an ocsilatory pattern going between positive and
     217             :   // negative in the large scale.  If this is set, we stop at the first
     218             :   // negative in the largest scale.
     219           0 :   void stopAtLargeScaleNegative() {itsStopAtLargeScaleNegative = true; }
     220             : 
     221             :   // Some algorithms require that the cycles be terminated when the image
     222             :   // is dominated by point sources; if we get nStopPointMode of the
     223             :   // smallest scale components in a row, we terminate the cycles
     224          84 :   void stopPointMode(casacore::Int nStopPointMode) {itsStopPointMode = nStopPointMode; }
     225             : 
     226             :   // After completion of cycle, querry this to find out if we stopped because
     227             :   // of stopPointMode
     228           0 :   casacore::Bool queryStopPointMode() const {return itsDidStopPointMode; }
     229             : 
     230             :   // speedup() will speed the clean iteration by raising the
     231             :   // threshold.  This may be required if the threshold is
     232             :   // accidentally set too low (ie, lower than can be achieved
     233             :   // given errors in the approximate PSF).
     234             :   //
     235             :   // threshold(iteration) = threshold(0)
     236             :   //                        * ( exp( (iteration - startingiteration)/Ndouble )/ 2.718 )
     237             :   // If speedup() is NOT invoked, no effect on threshold
     238             :   void speedup(const casacore::Float Ndouble);
     239             : 
     240             :   // Look at what WE think the residuals look like
     241             :   // Assumes the first scale is zero-sized
     242             :   casacore::Matrix<casacore::Float>  residual() { return itsDirtyConvScales[0]; }
     243             :   //slightly better approximation of the residual: it convolves the given model
     244             :   //with the psf and remove it from the dirty image put in setdirty
     245             :   casacore::Matrix<casacore::Float>  residual(const casacore::Matrix<casacore::Float>& model);
     246             :   // Method to return threshold, including any speedup factors
     247             :   casacore::Float threshold() const;
     248             : 
     249             :   // Method to return the strength optimum achieved at the last clean iteration
     250             :   // The output of this method makes sense only if it is called after clean
     251           0 :   casacore::Float strengthOptimum() const { return itsStrengthOptimum; }
     252             : 
     253             :   // Helper function to optimize adding
     254             :   //static void addTo(casacore::Matrix<casacore::Float>& to, const casacore::Matrix<casacore::Float> & add);
     255             : 
     256             : protected:
     257             :   friend class MatrixNACleaner;
     258             :   // Make sure that the peak of the Psf is within the image
     259             :   casacore::Bool validatePsf(const casacore::Matrix<casacore::Float> & psf);
     260             : 
     261             :   // Make an array of the specified scale
     262             :   void makeScale(casacore::Matrix<casacore::Float>& scale, const casacore::Float& scaleSize);
     263             : 
     264             :   // Make Spheroidal function for scale images
     265             :   casacore::Float spheroidal(casacore::Float nu);
     266             : 
     267             :   // Find the Peak of the matrix
     268             :   static casacore::Bool findMaxAbs(const casacore::Matrix<casacore::Float>& lattice,
     269             :                          casacore::Float& maxAbs, casacore::IPosition& posMax);
     270             : 
     271             :   // This is made static since findMaxAbs is static(!).
     272             :   // Why is findMaxAbs static???
     273             :   //                       --SB
     274             :   static casacore::Bool findPSFMaxAbs(const casacore::Matrix<casacore::Float>& lattice,
     275             :                             casacore::Float& maxAbs, casacore::IPosition& posMax,
     276             :                             const casacore::Int& supportSize=100);
     277             : 
     278             :   casacore::Int findBeamPatch(const casacore::Float maxScaleSize, const casacore::Int& nx, const casacore::Int& ny,
     279             :                     const casacore::Float psfBeam=4.0, const casacore::Float nBeams=20.0);
     280             :   // Find the Peak of the lattice, applying a mask
     281             :   casacore::Bool findMaxAbsMask(const casacore::Matrix<casacore::Float>& lattice, const casacore::Matrix<casacore::Float>& mask,
     282             :                              casacore::Float& maxAbs, casacore::IPosition& posMax);
     283             : 
     284             :   // Helper function to reduce the box sizes until the have the same
     285             :   // size keeping the centers intact
     286             :   static void makeBoxesSameSize(casacore::IPosition& blc1, casacore::IPosition& trc1,
     287             :      casacore::IPosition &blc2, casacore::IPosition& trc2);
     288             : 
     289             : 
     290             :   casacore::CleanEnums::CleanType itsCleanType;
     291             :   casacore::Float itsGain;
     292             :   casacore::Int itsMaxNiter;      // maximum possible number of iterations
     293             :   casacore::Quantum<casacore::Double> itsThreshold;
     294             :   casacore::CountedPtr<casacore::Matrix<casacore::Float> > itsMask;
     295             :   casacore::IPosition itsPositionPeakPsf;
     296             :   casacore::Float itsSmallScaleBias;
     297             :   casacore::Block<casacore::Matrix<casacore::Float> > itsScaleMasks;
     298             :   casacore::Block<casacore::Matrix<casacore::Complex> > itsScaleXfrs;
     299             :   casacore::Bool itsScalesValid;
     300             :   casacore::Int itsNscales;
     301             :   casacore::Float itsMaskThreshold;
     302             : 
     303             :   //# The following functions are used in various places in the code and are
     304             :   //# documented in the .cc file. Static functions are used when the functions
     305             :   //# do not modify the object state. They ensure that implicit assumptions
     306             :   //# about the current state and implicit side-effects are not possible
     307             :   //# because all information must be supplied in the input arguments
     308             : 
     309             : 
     310             :   casacore::CountedPtr<casacore::Matrix<casacore::Float> > itsDirty;
     311             :   casacore::CountedPtr<casacore::Matrix<casacore::Complex> >itsXfr;
     312             : 
     313             :   casacore::Vector<casacore::Float> itsScaleSizes;
     314             : 
     315             :   casacore::Block<casacore::Matrix<casacore::Float> > itsScales;
     316             :   casacore::Block<casacore::Matrix<casacore::Float> > itsPsfConvScales;
     317             :   casacore::Block<casacore::Matrix<casacore::Float> > itsDirtyConvScales;
     318             : 
     319             : 
     320             :   casacore::Int itsIteration;   // what iteration did we get to?
     321             :   casacore::Int itsStartingIter;        // what iteration did we get to?
     322             :   casacore::Quantum<casacore::Double> itsFracThreshold;
     323             : 
     324             :   casacore::Float itsMaximumResidual;
     325             :   casacore::Float itsStrengthOptimum;
     326             : 
     327             : 
     328             :   casacore::Vector<casacore::Float> itsTotalFluxScale;
     329             :   casacore::Float itsTotalFlux;
     330             : 
     331             :   // Calculate index into PsfConvScales
     332             :   casacore::Int index(const casacore::Int scale, const casacore::Int otherscale);
     333             : 
     334             :   casacore::Bool destroyScales();
     335             :   casacore::Bool destroyMasks();
     336             : 
     337             :   casacore::Bool itsIgnoreCenterBox;
     338             :   casacore::Bool itsStopAtLargeScaleNegative;
     339             :   casacore::Int itsStopPointMode;
     340             :   casacore::Bool itsDidStopPointMode;
     341             : 
     342             :   casacore::IPosition psfShape_p;
     343             :   casacore::Bool noClean_p;
     344             : 
     345             : private:
     346             : 
     347             :   // casacore::Memory to be allocated per TempLattice
     348             :   casacore::Double itsMemoryMB;
     349             : 
     350             :   // Let the user choose whether to stop
     351             :   casacore::Bool itsChoose;
     352             : 
     353             :   // Threshold speedup factors:
     354             :   casacore::Bool  itsDoSpeedup;  // if false, threshold does not change with iteration
     355             :   casacore::Float itsNDouble;
     356             : 
     357             :   //# Stop now?
     358             :   //#//  casacore::Bool stopnow();   Removed on 8-Apr-2004 by GvD
     359             : 
     360             :   casacore::Bool itsJustStarting;
     361             : 
     362             :   // threshold for masks. If negative, mask values are used as weights and no pixels are
     363             :   // discarded (although effectively they would be discarded if the mask value is 0.)
     364             : };
     365             : 
     366             : } //# NAMESPACE CASA - END
     367             : 
     368             : #endif

Generated by: LCOV version 1.16