MomentCalcBase.h

Go to the documentation of this file.
00001 //# MomentCalcBase.h:
00002 //# Copyright (C) 1997,1999,2000,2001,2002
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 //# $Id: MomentCalculator.h 20299 2008-04-03 05:56:44Z gervandiepen $
00027 
00028 #ifndef IMAGEANALYSIS_MOMENTCALCBASE_H
00029 #define IMAGEANALYSIS_MOMENTCALCBASE_H
00030 
00031 namespace casa {
00032 
00033 //# Forward Declarations
00034 template <class T> class MomentsBase;
00035 // <summary>
00036 // Abstract base class for moment calculator classes
00037 // </summary>
00038 // <use visibility=export>
00039 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00040 // </reviewed>
00041 //
00042 // <prerequisite>
00043 //   <li> <linkto class="MomentsBase">MomentsBase</linkto>
00044 //   <li> <linkto class="ImageMoments">ImageMoments</linkto>
00045 //   <li> <linkto class="LatticeApply">LatticeApply</linkto>
00046 //   <li> <linkto class="LineCollapser">LineCollapser</linkto>
00047 // </prerequisite>
00048 //
00049 // <synopsis>
00050 //  This class, its concrete derived classes, and the classes LineCollapser,
00051 //  ImageMoments, MSMoments, and LatticeApply are connected as follows.   LatticeApply offers 
00052 //  functions so that the application programmer does not need to worry about how 
00053 //  to optimally iterate through a Lattice; it deals with tiling and to a 
00054 //  lesser extent memory.    LatticeApply functions are used by offering a class 
00055 //  object to them that has a member function with a name and signature 
00056 //  specified by an abstract base class that LatticeApply uses and the 
00057 //  offered class inherits from.   Specifically, in this case, MomentCalcBase
00058 //  inherits from LineCollapser and LatticeApply uses objects and methods of this
00059 //  class (but does not inherit from it).  This defines the functions
00060 //  <src>collapse</src> and <src>multiProcess</src> which operate on a vector
00061 //  extracted from a Lattice.  The former returns one number, the latter a vector
00062 //  of numbers from that profile.  MomentCalcBase is a base class for
00063 //  for moment calculation and the <src>multiProcess</src>
00064 //  functions are used to compute moments  (e.g., mean, sum, sum squared, 
00065 //  intensity weighted velocity etc).
00066 //
00067 //  It is actually the concrete classes derived from MomentCalcBase (call them,
00068 //  as a group, the MomentCalculator classes) that implement the <src>multiProcess</src> 
00069 //  functions.  These derived classes allow different 
00070 //  algorithms to be written with which moments of the vector can be computed. 
00071 //
00072 //  Now, so far, we have a LatticeApply function which iterates through Lattices,
00073 //  extracts vectors, and offers them up to functions implemented in the derived 
00074 //  MomentCalculator classes to compute the moments.   As well as that, we need some
00075 //  class to actually construct the MomentCalculator classes and to feed them to 
00076 //  LatticeApply.   This is the role of the ImageMoments or MSMoments classes.  
00077 //  They are a high level 
00078 //  class which takes control information from users specifying which moments they 
00079 //  would like to calculate and how. They also provide the ancilliary masking lattice to 
00080 //  the MomentCalculator constructors. The actual computational work is done by the 
00081 //  MomentCalculator classes. So MomentsBase, MomentCalcBase and their derived 
00082 //  MomentCalculator classes are really one unit; none of them are useful without 
00083 //  the others.  The separation of functionality is caused by having the
00084 //  LatticeApply class that knows all about optimally iterating through Lattices.
00085 //
00086 //  The coupling between these classes is done partly by the "friendship".   MomentsBase and 
00087 //  its inheritances 
00088 //  grant friendship to MomentCalcBase so that the latter has access to the private data and 
00089 //  private functions of the formers.  MomentCalcBase then operates as an interface between 
00090 //  its derived MomentCalculator classes and ImageMoments or MSMoments. It retrieves private data 
00091 //  from these classes, and also activates private functions in these classes, on behalf 
00092 //  of the MomentCalculator classes. The rest of the coupling is done via the constructors 
00093 //  of the derived MomentCalculator classes.  
00094 //
00095 //  Finally, MomentCalcBase also has a number of protected functions that are common to its
00096 //  derived classes (e.g. fitting, accumulating sums etc).  It also has protected
00097 //  data that is common to all the MomentCalculator classes.  This protected data is accessed 
00098 //  directly by name rather than with interface functions as there is too much of it.  Of 
00099 //  course, since MomentCalcBase is an abstract base class, it is up to the MomentCalculator 
00100 //  classes to give the MomentCalcBase protected data objects values.
00101 //
00102 //  For discussion about different moments and algorithms to compute them see the 
00103 //  discussion in <linkto class="MomentsBase">MomentsBase</linkto>, 
00104 //  <linkto class="ImageMoments">ImageMoments</linkto>, 
00105 //  <linkto class="MSMoments">MSMoments</linkto> and also in
00106 //  the derived classes documentation.
00107 // </synopsis>
00108 //
00109 // <example>
00110 //  Since MomentCalcBase is an abstract class, we defer code examples to
00111 //  the derived classes.
00112 // </example>
00113 //
00114 // <motivation>
00115 // We were desirous of writing functions to optimally iterate through Lattices
00116 // so that the application programmer did not have to know anything about tiling
00117 // or memory if possible.   These are the LatticeApply functions. To incorporate 
00118 // MomentsBase and its inheritances into this scheme required some of it to be shifted into 
00119 // MomentCalcBase and its derived classes.
00120 // </motivation>
00121 //
00122 // <note role=tip>
00123 // Note that there are is assignment operator or copy constructor.
00124 // Do not use the ones the system would generate either.
00125 // </note>
00126 //
00127 // <todo asof="yyyy/mm/dd">
00128 //  <li> Derive more classes !
00129 // </todo>
00130 
00131 
00132 template <class T> class MomentCalcBase : public LineCollapser<T,T> {
00133 public:
00134 
00135     using AccumType = typename NumericTraits<T>::PrecisionType;
00136     using DataIterator = typename Vector<T>::const_iterator;
00137     using MaskIterator = Vector<Bool>::const_iterator;
00138 
00139     virtual ~MomentCalcBase();
00140 
00141     // Returns the number of failed fits if doing fitting
00142     virtual inline uInt nFailedFits() const { return nFailed_p; }
00143 
00144 protected:
00145 
00146     // A number of private data members are kept here in the base class
00147     // as they are common to the derived classes.  Since this class
00148     // is abstract, they have to be filled by the derived classes.
00149 
00150     // CoordinateSystem
00151     CoordinateSystem cSys_p;
00152 
00153     // This vector is a container for all the possible moments that
00154     // can be calculated.  They are in the order given by the MomentsBase
00155     // enum MomentTypes
00156     Vector<T> calcMoments_p;
00157     Vector<Bool> calcMomentsMask_p;
00158 
00159     // This vector tells us which elements of the calcMoments_p vector
00160     // we wish to select
00161     Vector<Int> selectMoments_p;
00162 
00163     // Although the general philosophy of these classes is to compute
00164     // all the posisble moments and then select the ones we want,
00165     // some of them are too expensive to calculate unless they are
00166     // really wanted.  These are the median moments and those that
00167     // require a second pass.  These control Bools tell us whether
00168     // we really want to compute the expensive ones.
00169     Bool doMedianI_p, doMedianV_p, doAbsDev_p;
00170 
00171     // These vectors are used to transform coordinates between pixel and world
00172     Vector<Double> pixelIn_p, worldOut_p;
00173 
00174     // All computations involving Coordinate conversions are relatively expensive
00175     // These Bools signifies whether we need coordinate calculations or not for
00176     // the full profile, and for some occaisional calculations
00177     Bool doCoordProfile_p, doCoordRandom_p;
00178 
00179     // This vector houses the world coordinate values for the profile if it
00180     // was from a separable axis. This means this vector can be pre computed
00181     // just once, instead of working out the coordinates for each profile
00182     // (expensive).  It should only be filled if doCoordCalc_p is True
00183     Vector<Double> sepWorldCoord_p;
00184 
00185     // This vector is used to hold the abscissa values
00186     Vector<T> abcissa_p;
00187 
00188     // This string tells us the name of the moment axis (VELO or FREQ etc)
00189     String momAxisType_p;
00190 
00191     // This is the number of Gaussian fits that failed.
00192     uInt nFailed_p;
00193 
00194     // This scale factor is the increment along the moment axis
00195     // applied so that units for the Integrated moment are like
00196     // Jy/beam.km/s (or whatever is needed for the moment axis units)
00197     // For non-linear velocities (e.g. optical) this is approximate
00198     // only and is computed at the reference pixel
00199     Double integratedScaleFactor_p;
00200 
00201     // Accumulate statistical sums from a vector
00202     inline void accumSums(
00203         typename NumericTraits<T>::PrecisionType& s0,
00204         typename NumericTraits<T>::PrecisionType& s0Sq,
00205         typename NumericTraits<T>::PrecisionType& s1,
00206         typename NumericTraits<T>::PrecisionType& s2,
00207         Int& iMin, Int& iMax, T& dMin, T& dMax,
00208         Int i, T datum, Double coord
00209     ) const {
00210         // Accumulate statistical sums from this datum
00211         //
00212         // Input:
00213         //  i              Index
00214         //  datum          Pixel value
00215         //  coord          Coordinate value on moment axis
00216         // Input/output:
00217         //  iMin,max       index of dMin and dMax
00218         //  dMin,dMax      minimum and maximum value
00219         // Output:
00220         //  s0             sum (I)
00221         //  s0Sq           sum (I*I)
00222         //  s1             sum (I*v)
00223         //  s2             sum (I*v*v)
00224         typename NumericTraits<T>::PrecisionType dDatum = datum;
00225         s0 += dDatum;
00226         s0Sq += dDatum*dDatum;
00227         s1 += dDatum*coord;
00228         s2 += dDatum*coord*coord;
00229         if (datum < dMin) {
00230             iMin = i;
00231             dMin = datum;
00232         }
00233         if (datum > dMax) {
00234             iMax = i;
00235             dMax = datum;
00236         }
00237     }
00238 
00239     // Determine if the spectrum is pure noise
00240     uInt allNoise(T& dMean,
00241         const Vector<T>& data,
00242         const Vector<Bool>& mask,
00243         T peakSNR,
00244         T stdDeviation
00245     ) const;
00246 
00247     // Check validity of constructor inputs
00248     void constructorCheck(
00249         Vector<T>& calcMoments,
00250         Vector<Bool>& calcMomentsMask,
00251         const Vector<Int>& selectMoments,
00252         uInt nLatticeOut
00253     ) const;
00254 
00255     // Find out from the selectMoments array whether we want
00256     // to compute the more expensive moments
00257     void costlyMoments(
00258         MomentsBase<T>& iMom, Bool& doMedianI,
00259         Bool& doMedianV, Bool& doAbsDev
00260     ) const;
00261 
00262     // Return the Bool saying whether we need to compute coordinates
00263     // or not for the requested moments
00264     void doCoordCalc(
00265         Bool& doCoordProfile,
00266         Bool& doCoordRandom,
00267         const MomentsBase<T>& iMom
00268     ) const;
00269 
00270     // Return the Bool from the ImageMoments or MSMoments object saying whether we
00271     // are going to fit Gaussians to the profiles or not.
00272     Bool doFit(const MomentsBase<T>& iMom) const;
00273 
00274     // Find the next masked or unmasked point in a vector
00275     Bool findNextDatum(
00276         uInt& iFound, const uInt& n,
00277         const Vector<Bool>& mask, const uInt& iStart,
00278         const Bool& findGood
00279     ) const;
00280 
00281     // Fit a Gaussian to x and y arrays given guesses for the gaussian parameters
00282     Bool fitGaussian(
00283         uInt& nFailed, T& peak, T& pos,
00284         T& width, T& level, const Vector<T>& x,
00285         const Vector<T>& y, const Vector<Bool>& mask,
00286         T peakGuess, T posGuess, T widthGuess,
00287         T levelGuess
00288     ) const;
00289 
00290     // Automatically fit a Gaussian to a spectrum, including finding the
00291     // starting guesses.
00292     Bool getAutoGaussianFit(
00293         uInt& nFailed, Vector<T>& gaussPars,
00294         const Vector<T>& x, const Vector<T>& y,
00295         const Vector<Bool>& mask, T peakSNR,
00296         T stdDeviation
00297     ) const;
00298 
00299     // Automatically work out a guess for the Gaussian parameters
00300     // Returns False if all pixels masked.
00301     Bool getAutoGaussianGuess(
00302         T& peakGuess, T& posGuess,
00303         T& widthGuess, T& levelGuess,
00304         const Vector<T>& x, const Vector<T>& y,
00305         const Vector<Bool>& mask
00306     ) const;
00307 
00308     // Compute the world coordinate for the given moment axis pixel
00309     inline Double getMomentCoord(
00310         const MomentsBase<T>& iMom, Vector<Double>& pixelIn,
00311         Vector<Double>& worldOut, Double momentPixel,
00312         Bool asVelocity=False
00313     ) const {
00314         // Find the value of the world coordinate on the moment axis
00315         // for the given moment axis pixel value.
00316         //
00317         // Input
00318         //   momentPixel   is the index in the profile extracted from the data
00319         // Input/output
00320         //   pixelIn       Pixels to convert.  Must all be filled in except for
00321         //                 pixelIn(momentPixel).
00322         //   worldOut      Vector to hold result
00323         //
00324         // Should really return a Fallible as I don't check and see
00325         // if the coordinate transformation fails or not
00326         //
00327         // Should really check the result is True, but for speed ...
00328         pixelIn[iMom.momentAxis_p] = momentPixel;
00329         cSys_p.toWorld(worldOut, pixelIn);
00330         if (asVelocity) {
00331             Double velocity;
00332             cSys_p.spectralCoordinate().frequencyToVelocity(
00333                 velocity, worldOut(iMom.worldMomentAxis_p)
00334             );
00335             return velocity;
00336         }
00337         return worldOut(iMom.worldMomentAxis_p);
00338     }
00339 
00340     // Examine a mask and determine how many segments of unmasked points
00341     // it consists of.
00342     void lineSegments (
00343         uInt& nSeg, Vector<uInt>& start,
00344         Vector<uInt>& nPts, const Vector<Bool>& mask
00345     ) const;
00346 
00347     // Return the moment axis from the ImageMoments object
00348     Int& momentAxis(MomentsBase<T>& iMom) const;
00349 
00350     // Return the name of the moment/profile axis
00351     String momentAxisName(
00352         const CoordinateSystem&,
00353         const MomentsBase<T>& iMom
00354     ) const;
00355 
00356     // Return the peak SNR for determination of all noise spectra from
00357     // the ImageMoments or MSMoments object
00358     T& peakSNR(MomentsBase<T>& iMom) const;
00359 
00360     // Return the selected pixel intensity range from the ImageMoments or MSMoments
00361     // object and the Bools describing whether it is inclusion or exclusion
00362     void selectRange(
00363         Vector<T>& pixelRange,
00364         Bool& doInclude,
00365         Bool& doExlude,
00366         MomentsBase<T>& iMom
00367     ) const;
00368 
00369     // The MomentCalculators compute a vector of all possible moments.
00370     // This function returns a vector which selects the desired moments from that
00371     // "all moment" vector.
00372     Vector<Int> selectMoments(MomentsBase<T>& iMom) const;
00373 
00374     // Fill the ouput moments array
00375     void setCalcMoments(
00376         const MomentsBase<T>& iMom, Vector<T>& calcMoments,
00377         Vector<Bool>& calcMomentsMask, Vector<Double>& pixelIn,
00378         Vector<Double>& worldOut, Bool doCoord,
00379         Double integratedScaleFactor, T dMedian,
00380         T vMedian, Int nPts,
00381         typename NumericTraits<T>::PrecisionType s0,
00382         typename NumericTraits<T>::PrecisionType s1,
00383         typename NumericTraits<T>::PrecisionType s2,
00384         typename NumericTraits<T>::PrecisionType s0Sq,
00385         typename NumericTraits<T>::PrecisionType sumAbsDev,
00386         T dMin, T dMax, Int iMin, Int iMax
00387     ) const;
00388 
00389     // Fill a string with the position of the cursor
00390     void setPosLabel(String& title, const IPosition& pos) const;
00391 
00392     // Install CoordinateSystem and SpectralCoordinate
00393     // in protected data members
00394     void setCoordinateSystem(
00395         CoordinateSystem& cSys, MomentsBase<T>& iMom
00396     );
00397 
00398     // Set up separable moment axis coordinate vector and
00399     // conversion vectors if not separable
00400     void setUpCoords(
00401         const MomentsBase<T>& iMom, Vector<Double>& pixelIn,
00402         Vector<Double>& worldOut, Vector<Double>& sepWorldCoord,
00403         LogIO& os, Double& integratedScaleFactor,
00404         const CoordinateSystem& cSys, Bool doCoordProfile,
00405         Bool doCoordRandom
00406     ) const;
00407 
00408     // Return standard deviation of image from ImageMoments or MSMoments object
00409     T& stdDeviation(MomentsBase<T>& iMom) const;
00410 
00411 protected:
00412     // Check if #pixels is indeed 1.
00413     virtual void init (uInt nOutPixelsPerCollapse);
00414 };
00415 
00416 }
00417 
00418 #ifndef CASACORE_NO_AUTO_TEMPLATES
00419 #include <imageanalysis/ImageAnalysis/MomentCalcBase.tcc>
00420 #endif
00421 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1