casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
LatticeCleaner.h
Go to the documentation of this file.
00001 //# Cleaner.h: this defines Cleaner a class for doing convolution
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //#
00027 //# $Id: LatticeCleaner.h 20739 2009-09-29 01:15:15Z Malte.Marquarding $
00028 
00029 #ifndef LATTICES_LATTICECLEANER_H
00030 #define LATTICES_LATTICECLEANER_H
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/Quanta/Quantum.h>
00035 #include <lattices/Lattices/TempLattice.h>
00036 #include <casa/Arrays/IPosition.h>
00037 #include <casa/Arrays/Vector.h>
00038 #include <casa/Containers/Block.h>
00039 
00040 namespace casa { //# NAMESPACE CASA - BEGIN
00041 
00042 //# Forward Declarations
00043 class LatticeCleanProgress;
00044 template <class T> class TempLattice;
00045 
00046 // <summary>Lists the different types of Convolutions that can be done</summary>
00047 // <synopsis>This enumerator is brought out as a separate class because g++
00048 // currently cannot handle enumerators in a templated class. When it can this
00049 // class will go away and this enumerator moved into the Cleaner
00050 // class</synopsis>
00051 class CleanEnums {
00052 public:
00053   enum CleanType {
00054     // Hogbom
00055     HOGBOM,
00056     // Multi-scale
00057     MULTISCALE,
00058     // Clark
00059     CLARK
00060   };
00061 };
00062 
00063 // <summary>A class for doing multi-dimensional cleaning</summary>
00064 
00065 // <use visibility=export>
00066 
00067 // <reviewed reviewer="" date="yyyy/mm/dd" tests="tLatticeCleaner">
00068 // </reviewed>
00069 
00070 // <prerequisite>
00071 //  <li> The mathematical concept of deconvolution
00072 // </prerequisite>
00073 //
00074 // <etymology>
00075 
00076 // The LatticeCleaner class will deconvolve Lattices.
00077 
00078 // </etymology>
00079 //
00080 // <synopsis>
00081 // This class will perform various types of Clean deconvolution
00082 // on Lattices.
00083 //
00084 // </synopsis>
00085 //
00086 // <example>
00087 // <srcblock>
00088 // </srcblock> 
00089 // </example>
00090 //
00091 // <motivation>
00092 // </motivation>
00093 //
00094 // <thrown>
00095 // <li> AipsError: if psf has more dimensions than the model. 
00096 // </thrown>
00097 //
00098 // <todo asof="yyyy/mm/dd">
00099 //   <li> Allow the psf to be specified with a
00100 //     <linkto class=Function>Function</linkto>. 
00101 // </todo>
00102 
00103 template<class T> class LatticeCleaner
00104 {
00105 public:
00106 
00107   // Create a cleaner : default constructor
00108   LatticeCleaner();
00109 
00110   // Create a cleaner for a specific dirty image and PSF
00111   LatticeCleaner(const Lattice<T> & psf, const Lattice<T> & dirty);
00112 
00113   // The copy constructor uses reference semantics
00114   LatticeCleaner(const LatticeCleaner<T> & other);
00115 
00116   // The assignment operator also uses reference semantics
00117   LatticeCleaner<T> & operator=(const LatticeCleaner<T> & other); 
00118 
00119   // The destructor does nothing special.
00120   ~LatticeCleaner();
00121 
00122   // Update the dirty image only
00123   void update(const Lattice<T> & dirty);
00124 
00125   // Set a number of scale sizes. The units of the scale are pixels.
00126   Bool setscales(const Int nscales, const Float scaleInc=1.0);
00127 
00128   // Set a specific set of scales
00129   Bool setscales(const Vector<Float> & scales);
00130 
00131   // Set up control parameters
00132   // cleanType - type of the cleaning algorithm to use (HOGBOM, MULTISCALE)
00133   // niter - number of iterations
00134   // gain - loop gain used in cleaning (a fraction of the maximum 
00135   //        subtracted at every iteration)
00136   // aThreshold - absolute threshold to stop iterations
00137   // fThreshold - fractional threshold (i.e. given w.r.t. maximum residual)
00138   //              to stop iterations. This parameter is specified as
00139   //              Quantity so it can be given in per cents. 
00140   // choose - unused at the moment, specify False. Original meaning is
00141   // to allow interactive decision on whether to continue iterations.
00142   // This method always returns True.
00143   Bool setcontrol(CleanEnums::CleanType cleanType, const Int niter,
00144                   const Float gain, const Quantity& aThreshold,
00145                   const Quantity& fThreshold,
00146                   const Bool choose=True);
00147 
00148   // This version of the method disables stopping on fractional threshold
00149   Bool setcontrol(CleanEnums::CleanType cleanType, const Int niter,
00150                   const Float gain, const Quantity& threshold,
00151                   const Bool choose=True);
00152 
00153   // return how many iterations we did do
00154   Int iteration() const { return itsIteration; }
00155   Int numberIterations() const { return itsIteration; }
00156 
00157   // what iteration number to start on
00158   void startingIteration(const Int starting = 0) {itsStartingIter = starting; }
00159 
00160   // Clean an image. 
00161   //return value gives you a hint of what's happening
00162   //  1 = converged
00163   //  0 = not converged but behaving normally
00164   // -1 = not converged and stopped on cleaning consecutive smallest scale
00165   // -2 = not converged and either large scale hit negative or diverging 
00166   // -3 = clean is diverging rather than converging 
00167   Int clean(Lattice<T> & model, LatticeCleanProgress* progress=0);
00168 
00169   // Set the mask
00170   // mask - input mask lattice
00171   // maskThreshold - if positive, the value is treated as a threshold value to determine
00172   // whether a pixel is good (mask value is greater than the threshold) or has to be 
00173   // masked (mask value is below the threshold). Negative threshold switches mask clipping
00174   // off. The mask value is used to weight the flux during cleaning. This mode is used
00175   // to implement cleaning based on the signal-to-noise as opposed to the standard cleaning
00176   // based on the flux. The default threshold value is 0.9, which ensures the behavior of the
00177   // code is exactly the same as before this parameter has been introduced.
00178   void setMask(Lattice<T> & mask, const T& maskThreshold = T(0.9));
00179 
00180   // Tell the algorithm to NOT clean just the inner quarter
00181   // (This is useful when multiscale clean is being used
00182   // inside a major cycle for MF or WF algorithms)
00183   // if True, the full image deconvolution will be attempted
00184   void ignoreCenterBox(Bool huh) { itsIgnoreCenterBox = huh; }
00185 
00186   // Consider the case of a point source: 
00187   // the flux on all scales is the same, and the first scale will be chosen.
00188   // Now, consider the case of a point source with a *little* bit of extended structure:
00189   // thats right, the largest scale will be chosen.  In this case, we should provide some
00190   // bias towards the small scales, or against the large scales.  We do this in
00191   // an ad hoc manner, multiplying the maxima found at each scale by
00192   // 1.0 - itsSmallScaleBias * itsScaleSizes(scale)/itsScaleSizes(nScalesToClean-1);
00193   // Typical bias values range from 0.2 to 1.0.
00194   void setSmallScaleBias(const Float x=0.5) { itsSmallScaleBias = x; }
00195 
00196   // During early iterations of a cycled MS Clean in mosaicing, it common
00197   // to come across an ocsilatory pattern going between positive and
00198   // negative in the large scale.  If this is set, we stop at the first
00199   // negative in the largest scale.
00200   void stopAtLargeScaleNegative() {itsStopAtLargeScaleNegative = True; }
00201 
00202   // Some algorithms require that the cycles be terminated when the image
00203   // is dominated by point sources; if we get nStopPointMode of the
00204   // smallest scale components in a row, we terminate the cycles
00205   void stopPointMode(Int nStopPointMode) {itsStopPointMode = nStopPointMode; }
00206 
00207   // After completion of cycle, querry this to find out if we stopped because
00208   // of stopPointMode
00209   Bool queryStopPointMode() const {return itsDidStopPointMode; }
00210 
00211   // speedup() will speed the clean iteration by raising the
00212   // threshold.  This may be required if the threshold is
00213   // accidentally set too low (ie, lower than can be achieved
00214   // given errors in the approximate PSF).
00215   //
00216   // threshold(iteration) = threshold(0) 
00217   //                        * ( exp( (iteration - startingiteration)/Ndouble )/ 2.718 )
00218   // If speedup() is NOT invoked, no effect on threshold
00219   void speedup(const Float Ndouble);
00220 
00221   // Look at what WE think the residuals look like
00222   // Assumes the first scale is zero-sized
00223   Lattice<T>*  residual() { return itsDirtyConvScales[0]; }
00224 
00225   // Method to return threshold, including any speedup factors
00226   Float threshold() const;
00227 
00228   // Method to return the strength optimum achieved at the last clean iteration
00229   // The output of this method makes sense only if it is called after clean
00230   T strengthOptimum() const { return itsStrengthOptimum; }
00231 
00232   // Helper function to optimize adding
00233   static void addTo(Lattice<T>& to, const Lattice<T>& add);
00234 
00235 protected:
00236   // Make sure that the peak of the Psf is within the image
00237   Bool validatePsf(const Lattice<T> & psf);
00238 
00239   // Make an lattice of the specified scale
00240   void makeScale(Lattice<T>& scale, const Float& scaleSize);
00241 
00242   // Make Spheroidal function for scale images
00243   Float spheroidal(Float nu);
00244   
00245   // Find the Peak of the Lattice
00246   static Bool findMaxAbsLattice(const Lattice<T>& lattice,
00247                          T& maxAbs, IPosition& posMax);
00248 
00249   // Find the Peak of the lattice, applying a mask
00250   Bool findMaxAbsMaskLattice(const Lattice<T>& lattice, const Lattice<T>& mask,
00251                              T& maxAbs, IPosition& posMax);
00252 
00253   // Helper function to reduce the box sizes until the have the same   
00254   // size keeping the centers intact  
00255   static void makeBoxesSameSize(IPosition& blc1, IPosition& trc1,                               
00256      IPosition &blc2, IPosition& trc2);
00257 
00258 
00259   CleanEnums::CleanType itsCleanType;
00260   Float itsGain;
00261   Int itsMaxNiter;      // maximum possible number of iterations
00262   Quantum<Double> itsThreshold;
00263   TempLattice<T>* itsMask;
00264   IPosition itsPositionPeakPsf;
00265 private:
00266 
00267   //# The following functions are used in various places in the code and are
00268   //# documented in the .cc file. Static functions are used when the functions
00269   //# do not modify the object state. They ensure that implicit assumptions
00270   //# about the current state and implicit side-effects are not possible
00271   //# because all information must be supplied in the input arguments
00272 
00273 
00274   TempLattice<T>* itsDirty;
00275   TempLattice<Complex>* itsXfr;
00276 
00277   Int itsNscales;
00278   Vector<Float> itsScaleSizes;
00279 
00280   PtrBlock<TempLattice<T>* > itsScales;
00281   PtrBlock<TempLattice<Complex>* > itsScaleXfrs;
00282   PtrBlock<TempLattice<T>* > itsPsfConvScales;
00283   PtrBlock<TempLattice<T>* > itsDirtyConvScales;
00284   PtrBlock<TempLattice<T>* > itsScaleMasks;
00285 
00286   Bool itsScalesValid;
00287 
00288   Int itsIteration;     // what iteration did we get to?
00289   Int itsStartingIter;  // what iteration did we get to?
00290   Quantum<Double> itsFracThreshold;
00291 
00292   Float itsMaximumResidual;
00293   T itsStrengthOptimum;
00294 
00295 
00296   Vector<Float> itsTotalFluxScale;
00297   Float itsTotalFlux;
00298 
00299   // Memory to be allocated per TempLattice
00300   Double itsMemoryMB;
00301 
00302   // Let the user choose whether to stop
00303   Bool itsChoose;
00304 
00305   // Threshold speedup factors:
00306   Bool  itsDoSpeedup;  // if false, threshold does not change with iteration
00307   Float itsNDouble;
00308 
00309   //# Stop now?
00310   //#//  Bool stopnow();   Removed on 8-Apr-2004 by GvD
00311 
00312   // Calculate index into PsfConvScales
00313   Int index(const Int scale, const Int otherscale);
00314   
00315   Bool destroyScales();
00316   Bool destroyMasks();
00317 
00318 
00319   Bool makeScaleMasks();
00320   Bool itsIgnoreCenterBox;
00321   Float itsSmallScaleBias;
00322   Bool itsStopAtLargeScaleNegative;
00323   Int itsStopPointMode;
00324   Bool itsDidStopPointMode;
00325   Bool itsJustStarting;
00326 
00327   // threshold for masks. If negative, mask values are used as weights and no pixels are
00328   // discarded (although effectively they would be discarded if the mask value is 0.)
00329   T itsMaskThreshold;
00330 
00331 };
00332 
00333 } //# NAMESPACE CASA - END
00334 
00335 #ifndef CASACORE_NO_AUTO_TEMPLATES
00336 #include <lattices/Lattices/LatticeCleaner.tcc>
00337 #endif //# CASACORE_NO_AUTO_TEMPLATES
00338 #endif