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

Generated by: LCOV version 1.16