LCOV - code coverage report
Current view: top level - synthesis/MeasurementEquations - ClarkCleanModel.h (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 3 0.0 %
Date: 2024-10-04 16:51:10 Functions: 0 3 0.0 %

          Line data    Source code
       1             : //# ClarkCleanModel.h: this defines ClarkCleanModel
       2             : //# Copyright (C) 1996,1997,1998,1999,2000,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$
      28             : 
      29             : #ifndef SYNTHESIS_CLARKCLEANMODEL_H
      30             : #define SYNTHESIS_CLARKCLEANMODEL_H
      31             : 
      32             : #include <casacore/casa/aips.h>
      33             : #include <casacore/casa/Arrays/Matrix.h>
      34             : #include <casacore/casa/Arrays/Vector.h>
      35             : #include <casacore/casa/Arrays/Array.h>
      36             : #include <synthesis/MeasurementEquations/ArrayModel.h>
      37             : #include <synthesis/MeasurementEquations/Iterate.h>
      38             : //#include <synthesis/MeasurementEquations/ResidualEquation.h>
      39             : #include <synthesis/MeasurementEquations/ConvolutionEquation.h>
      40             : #include <casacore/casa/Logging/LogIO.h>
      41             : 
      42             : namespace casa { //# NAMESPACE CASA - BEGIN
      43             : 
      44             : class ClarkCleanProgress;
      45             : 
      46             : // <summary>
      47             : // A Class for performing the Clark Clean Algorithm on Arrays
      48             : // </summary>
      49             : 
      50             : // <use visibility=export>
      51             : 
      52             : // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
      53             : // </reviewed>
      54             : 
      55             : // <prerequisite> 
      56             : // <li> ResidualEquation/ConvolutionEquation 
      57             : // <li> LinearModel/LinearEquation Paradigm 
      58             : // </prerequisite>
      59             : //
      60             : // <etymology>
      61             : // This class is called ClarkCleanModel because thats the algorithm it uses
      62             : // deconvolve the model. 
      63             : // </etymology>
      64             : //
      65             : // <synopsis>
      66             : // This class is used to perform the Clark Clean Algorithm on an
      67             : // Array. Only the deconvolved model of the sky are directly stored by this
      68             : // class. The point spread function (psf) and convolved (dirty) image are
      69             : // stored in a companion class which is must be derived from
      70             : // ResidualEquation. 
      71             : // 
      72             : // The cleaning works like this. The user constructs a ClarkCleanModel by
      73             : // specifying an initial model of the sky. This can by be
      74             : // one,two,three... dimensional depending on the dimension of the psf (see
      75             : // below). The user then constructs a class which implements the forward
      76             : // equation between the model and the dirty image. Typically this will be
      77             : // the ConvolutionEquation class, although any class which has a
      78             : // ResidualEquation interface will be work (but perhaps very slowly, as the
      79             : // ConvolutionEquation class has member functions optimised for cleaning)
      80             : //
      81             : // The user then calls the solve() function (with the appropriate equation
      82             : // class as an arguement), and this class will perform the Clark clean.
      83             : // The various clean parameters are set (prior to calling solve) using the
      84             : // functions derived from the Iterate class, in particular setGain(),
      85             : // setNumberIterations() & setThreshold() (to set a flux limit). 
      86             : // 
      87             : // The solve() function does not return either the deconvolved model or the
      88             : // residuals. The solved model can be obtained using the getModel() function
      89             : // (derived from ArrayModel()) and the residual can be obtained using the
      90             : // residual() member function of the Convolution/Residual Equation Class.
      91             : // 
      92             : // The size and shape of the model used in this class MUST be the same as
      93             : // the convolved data (Dirty Image), stored in the companion
      94             : // ResidualEquation Class. However the model (and convolved data) can have
      95             : // more dimensions than the psf, as well as a different size (either larger
      96             : // or smaller). When the dimensionality is different the cleaning is done
      97             : // independendtly in each "plane" of the model. (Note this has not
      98             : // been implemented yet but is relatively simple to do if necessary). 
      99             : //
     100             : // This multi-dimensionalty is exploited when cleaning arrays of
     101             : // StokesVectors. Here the casacore::Array of StokesVectors is decomposed into a stack
     102             : // of 4 Floating point arrays and the cleaning is done on all the the arrays
     103             : // simultaneosly. The criterion for choosing the brightest pixel has been
     104             : // generalised by using the "length" of the Stokesvector in 4 dimensional
     105             : // space. 
     106             : //
     107             : // A companion class to this one is MaskedClarkCleanModel. This provides
     108             : // the same functionality but is used with MaskedArrays which indicate which
     109             : // regions of the model to search for clean components. 
     110             : //
     111             : // </synopsis>
     112             : //
     113             : // <example>
     114             : // <srcblock>
     115             : // casacore::Matrix<casacore::Float> psf(12,12), dirty(10,10), initialModel(10,10);
     116             : // ...put appropriate values into psf, dirty, & initialModel....
     117             : // ClarkCleanModel<casacore::Float> deconvolvedModel(initialModel); 
     118             : // ConvolutionEquation convEqn(psf, dirty);
     119             : // deconvolvedModel.setGain(0.2); 
     120             : // deconvolvedModel.setNumberIterations(1000);
     121             : // casacore::Bool convWorked = deconvolvedModel.solve(convEqn);
     122             : // casacore::Array<casacore::Float> finalModel, residuals;
     123             : // if (convWorked){
     124             : //   finalModel = deconvolvedModel.getModel();
     125             : //   ConvEqn.residual(deconvolvedModel, finalResidual);
     126             : // }
     127             : // </srcblock> 
     128             : // </example>
     129             : //
     130             : // <motivation>
     131             : // This class is needed to deconvolve images.
     132             : // </motivation>
     133             : //
     134             : // <templating arg=T>
     135             : // I have tested this class with Arrays of
     136             : //    <li> Float
     137             : //    <li> StokesVector
     138             : // </templating>
     139             : //
     140             : // <todo asof="1996/05/02">
     141             : //   <li> Make changes so that multidimensions work as advertised
     142             : //   <li> compare timing with other clean implementations (ie, Mark's
     143             : //   CleanTools, SDE, AIPS & miriad) 
     144             : // </todo>
     145             : 
     146             : class ClarkCleanModel: 
     147             :   public ArrayModel<casacore::Float>,
     148             :   public Iterate
     149             : {
     150             : public:
     151             :   // The default constructor does nothing more than initialise a zero length
     152             :   // array to hold the deconvolved model. If this constructor is used then 
     153             :   // the actual model must be set using the setModel() function of the
     154             :   // ArrayModel class.
     155             :   ClarkCleanModel();
     156             :   // Construct the ClarkCleanModel object and initialise the model.
     157             :   ClarkCleanModel(casacore::Array<casacore::Float> & model);
     158             :   // Construct the ClarkCleanModel object and initialise the model ans mask
     159             :   ClarkCleanModel(casacore::Array<casacore::Float> & model, casacore::Array<casacore::Float> & mask);
     160             : 
     161             :   void getMask(casacore::Array<casacore::Float>& mask) const;
     162             :   void setMask(const casacore::Array<casacore::Float>& mask);
     163             :   void setMask(casacore::Array<casacore::Float> & mask);
     164             : 
     165             :   void getModel(casacore::Array<casacore::Float>& model) const;
     166             :   void setModel(const casacore::Array<casacore::Float>& model);
     167             :   void setModel(casacore::Array<casacore::Float> & model);
     168             : 
     169             :   // Set/get the progress display 
     170             :   // <group>
     171           0 :   virtual void setProgress(ClarkCleanProgress& ccp) { itsProgressPtr = &ccp; }
     172           0 :   virtual ClarkCleanProgress& getProgress() { return *itsProgressPtr; }
     173             :   // </group>
     174             : 
     175             :   // Using a Clark clean deconvolution proceedure solve for an improved
     176             :   // estimate of the deconvolved object. The convolution/residual equation
     177             :   // contains the psf and dirty image. When called with a ResidualEquation
     178             :   // arguement a quite general interface is used that is slow. The
     179             :   // convolution equation contains functions that speed things up. The
     180             :   // functions return false if the deconvolution could not be done.
     181             :   // <group>
     182             :   casacore::Bool solve(ConvolutionEquation & eqn);
     183             :   casacore::Bool singleSolve(ConvolutionEquation & eqn, casacore::Array<casacore::Float>& residual);
     184             :   // </group>
     185             : 
     186             :   // These functions set various "knobs" that the user can tweak and are
     187             :   // specific to the Clark clean algorithm. The more generic parameters
     188             :   // ie. clean gain, and maximum residual fluxlimit, are set using functions
     189             :   // in the Iterate base class. The get functions return the value that was
     190             :   // actually used after the cleaning was done.
     191             :   // <group>
     192             :   // set the size of the PSF used in the minor iterations. If not set it
     193             :   // defaults to the largest useful Psf (ie. min(modelSize*2, psfSize))
     194             :   virtual void setPsfPatchSize(const casacore::IPosition & psfPatchSize); 
     195             :   virtual casacore::IPosition getPsfPatchSize(); 
     196             :   // Set the size of the histogram used to determine how many pixels are
     197             :   // "active" in a minor iteration. Default value is 1000 is OK for
     198             :   // everything except very small cleans.
     199             :   virtual void setHistLength(const casacore::uInt HistBins ); 
     200             :   virtual casacore::uInt getHistLength(); 
     201             :   // Set the maximum number of minor iterations to perform for each major
     202             :   // cycle. 
     203             :   virtual void setMaxNumberMinorIterations(const casacore::uInt maxNumMinorIterations); 
     204             :   virtual casacore::uInt getMaxNumberMinorIterations();
     205             :   // Set and get the initial number of iterations
     206             :   virtual void setInitialNumberIterations(const casacore::uInt initialNumberIterations); 
     207             :   virtual casacore::uInt getInitialNumberIterations();
     208             :   // Set the maximum number of major cycles to perform
     209             :   virtual void setMaxNumberMajorCycles(const casacore::uInt maxNumMajorCycles); 
     210             :   virtual casacore::uInt getMaxNumberMajorCycles();
     211             :   // Set the maximum number of active pixels to use in the minor
     212             :   // iterations. The specified number can be exceeded if the topmost bin of
     213             :   // the histogram contains more pixels than specified here. The default is
     214             :   // 10,000 which is suitable for images of 512by512 pixels. Reduce this for
     215             :   // smaller images and increase it for larger ones. 
     216             :   virtual void setMaxNumPix(const casacore::uInt maxNumPix ); 
     217             :   virtual casacore::uInt getMaxNumPix(); 
     218             :   // Set the maximum exterior psf value. This is used to determine when to
     219             :   // stop the minor itartions. This is normally determined from the psf and
     220             :   // the number set here is only used if this cannot be determined. The
     221             :   // default is zero.
     222             :   virtual void setMaxExtPsf(const casacore::Float maxExtPsf ); 
     223             :   virtual casacore::Float getMaxExtPsf(); 
     224             :   // An exponent on the F(m,n) factor (see Clark[1980]) which influences how
     225             :   // quickly active pixels are treated as unreliable. Larger values mean
     226             :   // more major iterations. The default is zero. I have no experience on
     227             :   // when to use this factor.
     228             :   virtual void setSpeedup(const casacore::Float speedup ); 
     229             :   virtual casacore::Float getSpeedup(); 
     230             :   // The structure of various AIPS++ algorithms creates major cycles around
     231             :   // the Clark Clean (or other deconvolution algrithms.  The cycleSpeedup
     232             :   // parameter causes the threshold to edge up as
     233             :   // thresh = thresh_0 * 2^( iter/cycleSpeedup ); 
     234             :   // ignored if cycleSpeedup <= 0.
     235             :   virtual void setCycleSpeedup(const casacore::Float speedup ); 
     236             :   virtual casacore::Float getCycleSpeedup(); 
     237             :   // We are overwriting Iterate's threshold() method to put out speedup in it
     238             :   virtual casacore::Float threshold();
     239             :   // The user can be asked whether to stop after every minor cycle
     240             :   virtual void setChoose(const casacore::Bool askForChoice);
     241             :   virtual casacore::Bool getChoose();
     242             :   // </group>
     243           0 :   casacore::Float getMaxResidual() { return itsMaxRes;};
     244             : 
     245             : private:
     246             : // Do all the minor iterations for one major cycle. Cleaning stops
     247             : // when the flux or iteration limit is reached.
     248             :   void doMinorIterations(casacore::Array<casacore::Float> & model, 
     249             :                          casacore::Matrix<casacore::Float> & pixelValue, 
     250             :                          const casacore::Matrix<casacore::Int> & pixelPos, 
     251             :                          const casacore::Int numPix,
     252             :                          casacore::Matrix<casacore::Float> & psfPatch,
     253             :                          casacore::Float fluxLimit, 
     254             :                          casacore::uInt & numberIterations, 
     255             :                          casacore::Float Fmn, 
     256             :                          const casacore::uInt totalIterations,
     257             :                          casacore::Float& totalflux);
     258             : // Find all the pixels in the residual that are greater than fluxlimit, and
     259             : // store the values in the pixelsValue casacore::Matrix, and their positions in the
     260             : // pixelPos Matrix. Increases the size of the output matrices as
     261             : // necessary, but does not decrease them. So the actual number of "active"
     262             : // pixels is returned. This will always be less than (or equal to) the matrix
     263             : // size.
     264             :   casacore::Int cacheActivePixels(casacore::Matrix<casacore::Float> & pixVal, casacore::Matrix<casacore::Int> & pixPos, 
     265             :                          const casacore::Array<casacore::Float> & data, const casacore::Float fluxLimit);
     266             : // make histogram of absolute values in array
     267             :   void absHistogram(casacore::Vector<casacore::Int> & hist, casacore::Float & minVal, 
     268             :                     casacore::Float & maxVal, const casacore::Array<casacore::Float> & data);
     269             : // Determine the flux limit if we only select the maxNumPix biggest
     270             : // residuals. Flux limit is not exact due to quantising by the histogram
     271             :   casacore::Float biggestResiduals(casacore::Float & maxRes, const casacore::uInt maxNumPix, 
     272             :                          const casacore::Float fluxLimit, const casacore::Array<casacore::Float> & residual);
     273             : // Work out the size of the Psf patch to use. 
     274             :   casacore::Float getPsfPatch(casacore::Array<casacore::Float>& psfPatch, ConvolutionEquation& eqn);
     275             : // The maximum residual is the absolute maximum.
     276             :   casacore::Float maxResidual(const casacore::Array<casacore::Float> & residual);
     277             :   void maxVect(casacore::Vector<casacore::Float> & maxVal, casacore::Float & absVal, casacore::Int & offset,
     278             :                const casacore::Matrix<casacore::Float> & pixVal, const casacore::Int numPix);
     279             :   void subtractComponent(casacore::Matrix<casacore::Float> & pixVal, const casacore::Matrix<casacore::Int> & pixPos,
     280             :                          const casacore::Int numPix, const casacore::Vector<casacore::Float> & maxVal,
     281             :                          const casacore::Vector<casacore::Int> & maxPos, const casacore::Matrix<casacore::Float> & psf);
     282             :   casacore::Float absMaxBeyondDist(const casacore::IPosition &maxDist, const casacore::IPosition &centre,
     283             :                          const casacore::Array<casacore::Float> &array);
     284             :   casacore::Bool stopnow();
     285             : 
     286             :   casacore::uInt theHistBins;
     287             :   casacore::Float theMaxExtPsf;
     288             :   casacore::uInt theMaxNumberMinorIterations;
     289             :   casacore::uInt theInitialNumberIterations;
     290             :   casacore::Int theMaxNumberMajorCycles;
     291             :   casacore::uInt theMaxNumPix;
     292             :   casacore::IPosition thePsfPatchSize;
     293             :   casacore::Float theSpeedup;
     294             :   casacore::Float theCycleSpeedup;
     295             :   casacore::Bool theChoose;
     296             :   casacore::Array<casacore::Float> theMask;
     297             :   casacore::LogIO theLog;
     298             :   // There are too many iterations counters.
     299             :   // This one is required for theCycleSpeedup and threshold(),
     300             :   // and just keeps track of the total iterations done by THIS
     301             :   // ClarkCleanModel
     302             :   casacore::Int theIterCounter; 
     303             :   ClarkCleanProgress* itsProgressPtr;
     304             :   casacore::Bool itsJustStarting;
     305             : 
     306             :   casacore::Float itsMaxRes;
     307             : };
     308             : 
     309             : 
     310             : } //# NAMESPACE CASA - END
     311             : 
     312             : #endif

Generated by: LCOV version 1.16