LCOV - code coverage report
Current view: top level - imageanalysis/ImageAnalysis - MomentCalcBase.h (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 22 0.0 %
Date: 2024-12-11 20:54:31 Functions: 0 3 0.0 %

          Line data    Source code
       1             : //# MomentCalcBase.h:
       2             : //# Copyright (C) 1997,1999,2000,2001,2002
       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             : //# $Id: MomentCalculator.h 20299 2008-04-03 05:56:44Z gervandiepen $
      27             : 
      28             : #ifndef IMAGEANALYSIS_MOMENTCALCBASE_H
      29             : #define IMAGEANALYSIS_MOMENTCALCBASE_H
      30             : 
      31             : namespace casa {
      32             : 
      33             : //# Forward Declarations
      34             : template <class T> class MomentsBase;
      35             : // <summary>
      36             : // Abstract base class for moment calculator classes
      37             : // </summary>
      38             : // <use visibility=export>
      39             : // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
      40             : // </reviewed>
      41             : //
      42             : // <prerequisite>
      43             : //   <li> <linkto class="MomentsBase">MomentsBase</linkto>
      44             : //   <li> <linkto class="ImageMoments">ImageMoments</linkto>
      45             : //   <li> <linkto class="casacore::LatticeApply">casacore::LatticeApply</linkto>
      46             : //   <li> <linkto class="casacore::LineCollapser">casacore::LineCollapser</linkto>
      47             : // </prerequisite>
      48             : //
      49             : // <synopsis>
      50             : //  This class, its concrete derived classes, and the classes casacore::LineCollapser,
      51             : //  ImageMoments, MSMoments, and casacore::LatticeApply are connected as follows.   casacore::LatticeApply offers 
      52             : //  functions so that the application programmer does not need to worry about how 
      53             : //  to optimally iterate through a casacore::Lattice; it deals with tiling and to a 
      54             : //  lesser extent memory.    casacore::LatticeApply functions are used by offering a class 
      55             : //  object to them that has a member function with a name and signature 
      56             : //  specified by an abstract base class that casacore::LatticeApply uses and the 
      57             : //  offered class inherits from.   Specifically, in this case, MomentCalcBase
      58             : //  inherits from casacore::LineCollapser and casacore::LatticeApply uses objects and methods of this
      59             : //  class (but does not inherit from it).  This defines the functions
      60             : //  <src>collapse</src> and <src>multiProcess</src> which operate on a vector
      61             : //  extracted from a Lattice.  The former returns one number, the latter a vector
      62             : //  of numbers from that profile.  MomentCalcBase is a base class for
      63             : //  for moment calculation and the <src>multiProcess</src>
      64             : //  functions are used to compute moments  (e.g., mean, sum, sum squared, 
      65             : //  intensity weighted velocity etc).
      66             : //
      67             : //  It is actually the concrete classes derived from MomentCalcBase (call them,
      68             : //  as a group, the MomentCalculator classes) that implement the <src>multiProcess</src> 
      69             : //  functions.  These derived classes allow different 
      70             : //  algorithms to be written with which moments of the vector can be computed. 
      71             : //
      72             : //  Now, so far, we have a casacore::LatticeApply function which iterates through Lattices,
      73             : //  extracts vectors, and offers them up to functions implemented in the derived 
      74             : //  MomentCalculator classes to compute the moments.   As well as that, we need some
      75             : //  class to actually construct the MomentCalculator classes and to feed them to 
      76             : //  LatticeApply.   This is the role of the ImageMoments or MSMoments classes.  
      77             : //  They are a high level 
      78             : //  class which takes control information from users specifying which moments they 
      79             : //  would like to calculate and how. They also provide the ancilliary masking lattice to 
      80             : //  the MomentCalculator constructors. The actual computational work is done by the 
      81             : //  MomentCalculator classes. So MomentsBase, MomentCalcBase and their derived 
      82             : //  MomentCalculator classes are really one unit; none of them are useful without 
      83             : //  the others.  The separation of functionality is caused by having the
      84             : //  casacore::LatticeApply class that knows all about optimally iterating through Lattices.
      85             : //
      86             : //  The coupling between these classes is done partly by the "friendship".   MomentsBase and 
      87             : //  its inheritances 
      88             : //  grant friendship to MomentCalcBase so that the latter has access to the private data and 
      89             : //  private functions of the formers.  MomentCalcBase then operates as an interface between 
      90             : //  its derived MomentCalculator classes and ImageMoments or MSMoments. It retrieves private data 
      91             : //  from these classes, and also activates private functions in these classes, on behalf 
      92             : //  of the MomentCalculator classes. The rest of the coupling is done via the constructors 
      93             : //  of the derived MomentCalculator classes.  
      94             : //
      95             : //  Finally, MomentCalcBase also has a number of protected functions that are common to its
      96             : //  derived classes (e.g. fitting, accumulating sums etc).  It also has protected
      97             : //  data that is common to all the MomentCalculator classes.  This protected data is accessed 
      98             : //  directly by name rather than with interface functions as there is too much of it.  Of 
      99             : //  course, since MomentCalcBase is an abstract base class, it is up to the MomentCalculator 
     100             : //  classes to give the MomentCalcBase protected data objects values.
     101             : //
     102             : //  For discussion about different moments and algorithms to compute them see the 
     103             : //  discussion in <linkto class="MomentsBase">MomentsBase</linkto>, 
     104             : //  <linkto class="ImageMoments">ImageMoments</linkto>, 
     105             : //  <linkto class="MSMoments">MSMoments</linkto> and also in
     106             : //  the derived classes documentation.
     107             : // </synopsis>
     108             : //
     109             : // <example>
     110             : //  Since MomentCalcBase is an abstract class, we defer code examples to
     111             : //  the derived classes.
     112             : // </example>
     113             : //
     114             : // <motivation>
     115             : // We were desirous of writing functions to optimally iterate through Lattices
     116             : // so that the application programmer did not have to know anything about tiling
     117             : // or memory if possible.   These are the casacore::LatticeApply functions. To incorporate 
     118             : // MomentsBase and its inheritances into this scheme required some of it to be shifted into 
     119             : // MomentCalcBase and its derived classes.
     120             : // </motivation>
     121             : //
     122             : // <note role=tip>
     123             : // Note that there are is assignment operator or copy constructor.
     124             : // Do not use the ones the system would generate either.
     125             : // </note>
     126             : //
     127             : // <todo asof="yyyy/mm/dd">
     128             : //  <li> Derive more classes !
     129             : // </todo>
     130             : 
     131             : 
     132             : template <class T> class MomentCalcBase : public casacore::LineCollapser<T,T> {
     133             : public:
     134             : 
     135             :     using AccumType = typename casacore::NumericTraits<T>::PrecisionType;
     136             :     using DataIterator = typename casacore::Vector<T>::const_iterator;
     137             :     using MaskIterator = casacore::Vector<casacore::Bool>::const_iterator;
     138             : 
     139             :     virtual ~MomentCalcBase();
     140             : 
     141             :     // Returns the number of failed fits if doing fitting
     142           0 :     virtual inline casacore::uInt nFailedFits() const { return nFailed_p; }
     143             : 
     144             : protected:
     145             : 
     146             :     // A number of private data members are kept here in the base class
     147             :     // as they are common to the derived classes.  Since this class
     148             :     // is abstract, they have to be filled by the derived classes.
     149             : 
     150             :     // CoordinateSystem
     151             :     casacore::CoordinateSystem cSys_p;
     152             : 
     153             :     // This vector is a container for all the possible moments that
     154             :     // can be calculated.  They are in the order given by the MomentsBase
     155             :     // enum MomentTypes
     156             :     casacore::Vector<T> calcMoments_p;
     157             :     casacore::Vector<casacore::Bool> calcMomentsMask_p;
     158             : 
     159             :     // This vector tells us which elements of the calcMoments_p vector
     160             :     // we wish to select
     161             :     casacore::Vector<casacore::Int> selectMoments_p;
     162             : 
     163             :     // Although the general philosophy of these classes is to compute
     164             :     // all the posisble moments and then select the ones we want,
     165             :     // some of them are too expensive to calculate unless they are
     166             :     // really wanted.  These are the median moments and those that
     167             :     // require a second pass.  These control Bools tell us whether
     168             :     // we really want to compute the expensive ones.
     169             :     casacore::Bool doMedianI_p, doMedianV_p, doAbsDev_p;
     170             : 
     171             :     // These vectors are used to transform coordinates between pixel and world
     172             :     casacore::Vector<casacore::Double> pixelIn_p, worldOut_p;
     173             : 
     174             :     // All computations involving casacore::Coordinate conversions are relatively expensive
     175             :     // These Bools signifies whether we need coordinate calculations or not for
     176             :     // the full profile, and for some occaisional calculations
     177             :     casacore::Bool doCoordProfile_p, doCoordRandom_p;
     178             : 
     179             :     // This vector houses the world coordinate values for the profile if it
     180             :     // was from a separable axis. This means this vector can be pre computed
     181             :     // just once, instead of working out the coordinates for each profile
     182             :     // (expensive).  It should only be filled if doCoordCalc_p is true
     183             :     casacore::Vector<casacore::Double> sepWorldCoord_p;
     184             : 
     185             :     // This vector is used to hold the abscissa values
     186             :     casacore::Vector<T> abcissa_p;
     187             : 
     188             :     // This string tells us the name of the moment axis (VELO or FREQ etc)
     189             :     casacore::String momAxisType_p;
     190             : 
     191             :     // This is the number of Gaussian fits that failed.
     192             :     casacore::uInt nFailed_p;
     193             : 
     194             :     // This scale factor is the increment along the moment axis
     195             :     // applied so that units for the Integrated moment are like
     196             :     // Jy/beam.km/s (or whatever is needed for the moment axis units)
     197             :     // For non-linear velocities (e.g. optical) this is approximate
     198             :     // only and is computed at the reference pixel
     199             :     casacore::Double integratedScaleFactor_p;
     200             : 
     201             :     // Accumulate statistical sums from a vector
     202           0 :     inline void accumSums(
     203             :         typename casacore::NumericTraits<T>::PrecisionType& s0,
     204             :         typename casacore::NumericTraits<T>::PrecisionType& s0Sq,
     205             :         typename casacore::NumericTraits<T>::PrecisionType& s1,
     206             :         typename casacore::NumericTraits<T>::PrecisionType& s2,
     207             :         casacore::Int& iMin, casacore::Int& iMax, T& dMin, T& dMax,
     208             :         casacore::Int i, T datum, casacore::Double coord
     209             :     ) const {
     210             :         // Accumulate statistical sums from this datum
     211             :         //
     212             :         // casacore::Input:
     213             :         //  i              Index
     214             :         //  datum          Pixel value
     215             :         //  coord          casacore::Coordinate value on moment axis
     216             :         // casacore::Input/output:
     217             :         //  iMin,max       index of dMin and dMax
     218             :         //  dMin,dMax      minimum and maximum value
     219             :         // Output:
     220             :         //  s0             sum (I)
     221             :         //  s0Sq           sum (I*I)
     222             :         //  s1             sum (I*v)
     223             :         //  s2             sum (I*v*v)
     224           0 :         typename casacore::NumericTraits<T>::PrecisionType dDatum = datum;
     225           0 :         s0 += dDatum;
     226           0 :         s0Sq += dDatum*dDatum;
     227           0 :         s1 += dDatum*coord;
     228           0 :         s2 += dDatum*coord*coord;
     229           0 :         if (datum < dMin) {
     230           0 :             iMin = i;
     231           0 :             dMin = datum;
     232             :         }
     233           0 :         if (datum > dMax) {
     234           0 :             iMax = i;
     235           0 :             dMax = datum;
     236             :         }
     237           0 :     }
     238             : 
     239             :     // Determine if the spectrum is pure noise
     240             :     casacore::uInt allNoise(T& dMean,
     241             :         const casacore::Vector<T>& data,
     242             :         const casacore::Vector<casacore::Bool>& mask,
     243             :         T peakSNR,
     244             :         T stdDeviation
     245             :     ) const;
     246             : 
     247             :     // Check validity of constructor inputs
     248             :     void constructorCheck(
     249             :         casacore::Vector<T>& calcMoments,
     250             :         casacore::Vector<casacore::Bool>& calcMomentsMask,
     251             :         const casacore::Vector<casacore::Int>& selectMoments,
     252             :         casacore::uInt nLatticeOut
     253             :     ) const;
     254             : 
     255             :     // Find out from the selectMoments array whether we want
     256             :     // to compute the more expensive moments
     257             :     void costlyMoments(
     258             :         MomentsBase<T>& iMom, casacore::Bool& doMedianI,
     259             :         casacore::Bool& doMedianV, casacore::Bool& doAbsDev
     260             :     ) const;
     261             : 
     262             :     // Return the casacore::Bool saying whether we need to compute coordinates
     263             :     // or not for the requested moments
     264             :     void doCoordCalc(
     265             :         casacore::Bool& doCoordProfile,
     266             :         casacore::Bool& doCoordRandom,
     267             :         const MomentsBase<T>& iMom
     268             :     ) const;
     269             : 
     270             :     // Return the casacore::Bool from the ImageMoments or MSMoments object saying whether we
     271             :     // are going to fit Gaussians to the profiles or not.
     272             :     casacore::Bool doFit(const MomentsBase<T>& iMom) const;
     273             : 
     274             :     // Find the next masked or unmasked point in a vector
     275             :     casacore::Bool findNextDatum(
     276             :         casacore::uInt& iFound, const casacore::uInt& n,
     277             :         const casacore::Vector<casacore::Bool>& mask, const casacore::uInt& iStart,
     278             :         const casacore::Bool& findGood
     279             :     ) const;
     280             : 
     281             :     // Fit a Gaussian to x and y arrays given guesses for the gaussian parameters
     282             :     casacore::Bool fitGaussian(
     283             :         casacore::uInt& nFailed, T& peak, T& pos,
     284             :         T& width, T& level, const casacore::Vector<T>& x,
     285             :         const casacore::Vector<T>& y, const casacore::Vector<casacore::Bool>& mask,
     286             :         T peakGuess, T posGuess, T widthGuess,
     287             :         T levelGuess
     288             :     ) const;
     289             : 
     290             :     // Automatically fit a Gaussian to a spectrum, including finding the
     291             :     // starting guesses.
     292             :     casacore::Bool getAutoGaussianFit(
     293             :         casacore::uInt& nFailed, casacore::Vector<T>& gaussPars,
     294             :         const casacore::Vector<T>& x, const casacore::Vector<T>& y,
     295             :         const casacore::Vector<casacore::Bool>& mask, T peakSNR,
     296             :         T stdDeviation
     297             :     ) const;
     298             : 
     299             :     // Automatically work out a guess for the Gaussian parameters
     300             :     // Returns false if all pixels masked.
     301             :     casacore::Bool getAutoGaussianGuess(
     302             :         T& peakGuess, T& posGuess,
     303             :         T& widthGuess, T& levelGuess,
     304             :         const casacore::Vector<T>& x, const casacore::Vector<T>& y,
     305             :         const casacore::Vector<casacore::Bool>& mask
     306             :     ) const;
     307             : 
     308             :     // Compute the world coordinate for the given moment axis pixel
     309           0 :     inline casacore::Double getMomentCoord(
     310             :         const MomentsBase<T>& iMom, casacore::Vector<casacore::Double>& pixelIn,
     311             :         casacore::Vector<casacore::Double>& worldOut, casacore::Double momentPixel,
     312             :         casacore::Bool asVelocity=false
     313             :     ) const {
     314             :         // Find the value of the world coordinate on the moment axis
     315             :         // for the given moment axis pixel value.
     316             :         //
     317             :         // Input
     318             :         //   momentPixel   is the index in the profile extracted from the data
     319             :         // casacore::Input/output
     320             :         //   pixelIn       Pixels to convert.  Must all be filled in except for
     321             :         //                 pixelIn(momentPixel).
     322             :         //   worldOut      casacore::Vector to hold result
     323             :         //
     324             :         // Should really return a casacore::Fallible as I don't check and see
     325             :         // if the coordinate transformation fails or not
     326             :         //
     327             :         // Should really check the result is true, but for speed ...
     328           0 :         pixelIn[iMom.momentAxis_p] = momentPixel;
     329           0 :         cSys_p.toWorld(worldOut, pixelIn);
     330           0 :         if (asVelocity) {
     331             :             casacore::Double velocity;
     332           0 :             cSys_p.spectralCoordinate().frequencyToVelocity(
     333           0 :                 velocity, worldOut(iMom.worldMomentAxis_p)
     334             :             );
     335           0 :             return velocity;
     336             :         }
     337           0 :         return worldOut(iMom.worldMomentAxis_p);
     338             :     }
     339             : 
     340             :     // Examine a mask and determine how many segments of unmasked points
     341             :     // it consists of.
     342             :     void lineSegments (
     343             :         casacore::uInt& nSeg, casacore::Vector<casacore::uInt>& start,
     344             :         casacore::Vector<casacore::uInt>& nPts, const casacore::Vector<casacore::Bool>& mask
     345             :     ) const;
     346             : 
     347             :     // Return the moment axis from the ImageMoments object
     348             :     casacore::Int& momentAxis(MomentsBase<T>& iMom) const;
     349             : 
     350             :     // Return the name of the moment/profile axis
     351             :     casacore::String momentAxisName(
     352             :         const casacore::CoordinateSystem&,
     353             :         const MomentsBase<T>& iMom
     354             :     ) const;
     355             : 
     356             :     // Return the peak SNR for determination of all noise spectra from
     357             :     // the ImageMoments or MSMoments object
     358             :     T& peakSNR(MomentsBase<T>& iMom) const;
     359             : 
     360             :     // Return the selected pixel intensity range from the ImageMoments or MSMoments
     361             :     // object and the Bools describing whether it is inclusion or exclusion
     362             :     void selectRange(
     363             :         casacore::Vector<T>& pixelRange,
     364             :         casacore::Bool& doInclude,
     365             :         casacore::Bool& doExlude,
     366             :         MomentsBase<T>& iMom
     367             :     ) const;
     368             : 
     369             :     // The MomentCalculators compute a vector of all possible moments.
     370             :     // This function returns a vector which selects the desired moments from that
     371             :     // "all moment" vector.
     372             :     casacore::Vector<casacore::Int> selectMoments(MomentsBase<T>& iMom) const;
     373             : 
     374             :     // Fill the ouput moments array
     375             :     void setCalcMoments(
     376             :         const MomentsBase<T>& iMom, casacore::Vector<T>& calcMoments,
     377             :         casacore::Vector<casacore::Bool>& calcMomentsMask, casacore::Vector<casacore::Double>& pixelIn,
     378             :         casacore::Vector<casacore::Double>& worldOut, casacore::Bool doCoord,
     379             :         casacore::Double integratedScaleFactor, T dMedian,
     380             :         T vMedian, casacore::Int nPts,
     381             :         typename casacore::NumericTraits<T>::PrecisionType s0,
     382             :         typename casacore::NumericTraits<T>::PrecisionType s1,
     383             :         typename casacore::NumericTraits<T>::PrecisionType s2,
     384             :         typename casacore::NumericTraits<T>::PrecisionType s0Sq,
     385             :         typename casacore::NumericTraits<T>::PrecisionType sumAbsDev,
     386             :         T dMin, T dMax, casacore::Int iMin, casacore::Int iMax
     387             :     ) const;
     388             : 
     389             :     // Fill a string with the position of the cursor
     390             :     void setPosLabel(casacore::String& title, const casacore::IPosition& pos) const;
     391             : 
     392             :     // Install casacore::CoordinateSystem and SpectralCoordinate
     393             :     // in protected data members
     394             :     void setCoordinateSystem(
     395             :         casacore::CoordinateSystem& cSys, MomentsBase<T>& iMom
     396             :     );
     397             : 
     398             :     // Set up separable moment axis coordinate vector and
     399             :     // conversion vectors if not separable
     400             :     void setUpCoords(
     401             :         const MomentsBase<T>& iMom, casacore::Vector<casacore::Double>& pixelIn,
     402             :         casacore::Vector<casacore::Double>& worldOut, casacore::Vector<casacore::Double>& sepWorldCoord,
     403             :         casacore::LogIO& os, casacore::Double& integratedScaleFactor,
     404             :         const casacore::CoordinateSystem& cSys, casacore::Bool doCoordProfile,
     405             :         casacore::Bool doCoordRandom
     406             :     ) const;
     407             : 
     408             :     // Return standard deviation of image from ImageMoments or MSMoments object
     409             :     T& stdDeviation(MomentsBase<T>& iMom) const;
     410             : 
     411             : protected:
     412             :     // Check if #pixels is indeed 1.
     413             :     virtual void init (casacore::uInt nOutPixelsPerCollapse);
     414             : };
     415             : 
     416             : }
     417             : 
     418             : #ifndef CASACORE_NO_AUTO_TEMPLATES
     419             : #include <imageanalysis/ImageAnalysis/MomentCalcBase.tcc>
     420             : #endif
     421             : #endif

Generated by: LCOV version 1.16