LCOV - code coverage report
Current view: top level - imageanalysis/ImageAnalysis - ImageMoments.h (source / functions) Hit Total Coverage
Test: ctest_coverage.info Lines: 0 2 0.0 %
Date: 2023-11-06 10:06:49 Functions: 0 2 0.0 %

          Line data    Source code
       1             : //# ImageMoments.h: generate moments from images
       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: aips2-request@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: ImageMoments.h 20299 2008-04-03 05:56:44Z gervandiepen $
      27             : 
      28             : #ifndef IMAGES_IMAGEMOMENTS_H
      29             : #define IMAGES_IMAGEMOMENTS_H
      30             : 
      31             : #include <imageanalysis/ImageAnalysis/MomentsBase.h>
      32             : 
      33             : #include <imageanalysis/ImageTypedefs.h>
      34             : 
      35             : namespace casacore{
      36             : 
      37             : template <class T> class MaskedLattice;
      38             : }
      39             : 
      40             : namespace casa {
      41             : 
      42             : class ImageMomentsProgressMonitor;
      43             : 
      44             : // <summary>
      45             : // This class generates moments from an image.
      46             : // </summary>
      47             : 
      48             : // <use visibility=export>
      49             : 
      50             : // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
      51             : // </reviewed>
      52             : 
      53             : // <prerequisite>
      54             : //   <li> <linkto class="casacore::ImageInterface">casacore::ImageInterface</linkto>
      55             : //   <li> <linkto class="MomentsBase">MomentsBase</linkto>
      56             : //   <li> <linkto class="casacore::LatticeApply">casacore::LatticeApply</linkto>   
      57             : //   <li> <linkto class="MomentCalcBase">MomentCalcBase</linkto>
      58             : // </prerequisite>
      59             : 
      60             : // <etymology>
      61             : //   This class computes moments from images
      62             : // </etymology>
      63             : 
      64             : // <synopsis>
      65             : //  The primary goal of this class is to help spectral-line astronomers analyze 
      66             : //  their multi-dimensional images by generating moments of a specified axis.
      67             : //  The word "moment" is used loosely here.  It refers to collapsing an axis
      68             : //  to one pixel and putting the value of that pixel (for all of the other 
      69             : //  non-collapsed axes) to something computed from the data values along
      70             : //  the moment axis.  For example, take an RA-DEC-Velocity cube, collapse
      71             : //  the velocity axis by computing the mean intensity at each RA-DEC
      72             : //  pixel.  This class offers many different moments and a variety of
      73             : //  interactive and automatic ways to compute them.
      74             : //
      75             : //  This class only accepts images of type <src>casacore::Float</src> and <src>casacore::Double</src>.
      76             : //  This restriction is because of the plotting capabilities which are a
      77             : //  bit awkward for other types.
      78             : //
      79             : //  This class makes a distinction between a "moment" and a "method". This
      80             : //  boundary is a little blurred, but it claims to refer to the distinction 
      81             : //  of what you are computing, as to how the pixels that were included in the 
      82             : //  computation were selected.  For example,  a "moment" would be the average value 
      83             : //  of some pixels.  A method for selecting those pixels would be a simple range 
      84             : //  specifying  a range for which pixels should be included.
      85             : //
      86             : //  The default state of this class is to do nothing.  If you specify an image via
      87             : //  the <src>setImage</src> function then invoking the <src>createMoments</src>
      88             : //  function will cause it to compute the integrated itensity along the 
      89             : //  spectral axis of the image (if it can find one).  You can change the 
      90             : //  computational state of the class from this basic form via the remaining
      91             : //  <src>set</src> functions.  You can call any number of these functions to 
      92             : //  suit your needs.
      93             : //
      94             : //  Because there are a wide variety of methods available, if you specify an
      95             : //  invalid combination, a table showing the available methods is listed. It
      96             : //  is reproduced below for convenience.  
      97             : //
      98             : //  The basic method is to just compute moments directly from the pixel intensities.  
      99             : //  This can be modified by applying pixel intensity inclusion or exclusion ranges.  
     100             : //  You can then also smooth the image and compute a mask based on the inclusion or 
     101             : //  exclusion ranges applied to the smoothed image.  This mask is then applied to 
     102             : //  the unsmoothed data for moment computation.
     103             : //
     104             : //  The window method does no pixel intensity range selection.  Instead a spectral
     105             : //  window is found (hopefully surrounding the spectral line feature) and only the 
     106             : //  pixels in that window are used for computation.  This window can be found from the 
     107             : //  smoothed or unsmoothed data.  The moments are always computed from the unsmoothed 
     108             : //  data.  For each spectrum, the window can be found interactively or automatically.
     109             : //  There are two interactive methods.  Either you just mark the window with the
     110             : //  cursor, or you interactively fit a Gaussian to the profile and the +/- 3-sigma
     111             : //  window is returned.  There are two automatic methods.  Either Bosma's converging
     112             : //  mean algorithm is used, or an automatically  fit Gaussian +/- 3-sigma window
     113             : //  is returned.
     114             : //
     115             : //  The fitting method fits Gaussians to spectral features either automatically
     116             : //  or interactively.  The moments are then computed from the Gaussian fits
     117             : //  (not the data themselves).
     118             : //
     119             : //  When an output image is created, it will have N-1 axes, where the input image
     120             : //  has N axes.  In the output image, the physical axis corresponding to the moment
     121             : //  axis will have been removed, but the coordinate information will be retained 
     122             : //  for future coordinate transformations. For example, if you have a RA-DEC-VELOCITY 
     123             : //  image and you collapsed axis 2 (the DEC axis) the output images would be 
     124             : //  RA-VELOCITY with the coordinate information retained for the DEC axis so that 
     125             : //  the coupled nature of RA/DEC coordinates is preserved.    
     126             : //
     127             : //  Output images are created with an all true (good) mask.  If, for a given
     128             : //  pixel, the moment calculation fails, then the mask is set to F.
     129             : //
     130             : //  When making plots, the order in which the spectra are  displayed is determined
     131             : //  by the tiling sequence of the image (for optimum speed of access).  
     132             : //
     133             : //
     134             : // <srcblock>
     135             : //                   Allowed Methods
     136             : //                   ---------------
     137             : //
     138             : //   casacore::Smooth    Window      Fit   in/exclude   Interactive 
     139             : //   -----------------------------------------------------
     140             : //     N          N         N        N            N       
     141             : //     Y/N        N         N        Y            N       
     142             : // 
     143             : //     Y/N        Y         N        N            Y       
     144             : //     Y/N        Y         N        N            N       
     145             : //     Y/N        Y         Y        N            Y/N     
     146             : //
     147             : //     N          N         Y        N            Y/N     
     148             : //   ----------------------------------------------------
     149             : // </srcblock>
     150             : //
     151             : // <note role=caution>
     152             : // Note that the <src>MEDIAN_COORDINATE</src> moment is not very robust.
     153             : // It is very useful for generating quickly a velocity field in a way
     154             : // that is not sensitive to noise.    However, it will only give sensible
     155             : // results under certain conditions.   It treats the spectrum as a
     156             : // probability distribution, generates the cumulative distribution for
     157             : // the selected pixels (via an <src>include</src> or <src>exclude</src>
     158             : // pixel range, and finds the (interpolated) coordinate coresponding to 
     159             : // the 50% value.  The generation of the cumulative distribution and the
     160             : // finding of the 50% level really only makes sense if the cumulative
     161             : // distribution is monotonically increasing.  This essentially means only
     162             : // selecting pixels which are positive or negative.  For this reason, this
     163             : // moment type is *only* supported with the basic method (i.e. no smoothing,
     164             : // no windowing, no fitting) with a pixel selection range that is either
     165             : // all positive, or all negative.
     166             : // </note>
     167             : //
     168             : // <note role=tip>
     169             : // If you ignore return error statuses from the functions that set the
     170             : // state of the class, the internal status of the class is set to bad.
     171             : // This means it will just  keep on returning error conditions until you
     172             : // explicitly recover the situation.  A message describing the last
     173             : // error condition can be recovered with function errorMessage.
     174             : // </note>
     175             : // </synopsis>
     176             : 
     177             : // <example>
     178             : // <srcBlock>
     179             : //// Set state function argument values
     180             : //
     181             : //      casacore::Vector<casacore::Int> moments(2);
     182             : //      moments(0) = ImageMoments<casacore::Float>::AVERAGE;
     183             : //      moments(1) = ImageMoments<casacore::Float>::WEIGHTED_MEAN_COORDINATE;
     184             : //      casacore::Vector<int> methods(2);
     185             : //      methods(0) = ImageMoments<casacore::Float>::WINDOW;
     186             : //      methods(1) = ImageMoments<casacore::Float>::INTERACTIVE;
     187             : //      casacore::Vector<casacore::Int> nxy(2);
     188             : //      nxy(0) = 3;
     189             : //      nxy(1) = 3;
     190             : //
     191             : //// Open paged image
     192             : //     
     193             : //      casacore::PagedImage<casacore::Float> inImage(inName);  
     194             : //
     195             : //// Construct moment helper object
     196             : //
     197             : //      casacore::LogOrigin or("myClass", "myFunction(...)", WHERE);
     198             : //      casacore::LogIO os(or);
     199             : //      ImageMoments<casacore::Float> moment(casacore::SubImage<casacore::Float>(inName), os);
     200             : //
     201             : //// Specify state via control functions
     202             : //
     203             : //      if (!moment.setMoments(moments)) return 1;
     204             : //      if (!moment.setWinFitMethod(methods)) return 1;
     205             : //      if (!moment.setMomentAxis(3)) return 1;
     206             : //      if (!moment.setPlotting("/xs", nxy)) return 1;
     207             : //
     208             : //// Create the moments
     209             : //
     210             : //      if (!moment.createMoments()) return 1;
     211             : // </srcBlock>
     212             : // In this example, we generate two moments (average intensity and intensity
     213             : // weighted mean coordinate -- usually the velocity field) of axis 3 by the 
     214             : // interactive window method.  The interactive plotting is done on the 
     215             : // device called <src>/xs</src> (no longer supported).   We put 9 subplots on each page.  The output 
     216             : // file names are constructed by the class from the input file name plus some 
     217             : // internally generated suffixes.
     218             : // </example>
     219             : 
     220             : // <motivation>
     221             : //  This is a fundamental and traditional piece of spectral-line image analysis.
     222             : // </motivation>
     223             : 
     224             : // <todo asof="1996/11/26">
     225             : //   <li> more control over histogram of image noise at start (pixel
     226             : //        range and number of bins)
     227             : //   <li> better algorithm for seeing if spectrum is pure noise
     228             : //   <li> Make this class extensible so users could add their own method.
     229             : // </todo>
     230             :  
     231             : 
     232             : template <class T> class ImageMoments : public MomentsBase<T> {
     233             : public:
     234             : 
     235             :     // Note that if I don't put MomentCalcBase as a forward declaration
     236             :     // and use instead  "friend class MomentCalcBase<T>"  The gnu compiler
     237             :     // fails with a typedef problem.  But I can't solve it with say
     238             :     // <src>typedef MomentCalcBase<T> gpp_type;</src>  because you can only do a
     239             :     // typedef with an actual type, not a <tt>T</tt> !
     240             :     friend class MomentCalcBase<T>;
     241             : 
     242             :     ImageMoments() = delete;
     243             : 
     244             :     // Constructor takes an image and a <src>casacore::LogIO</src> object for logging purposes.
     245             :     // You specify whether output images are  automatically overwritten if pre-existing,
     246             :     // or whether an intercative choice dialog widget appears (overWriteOutput=F)
     247             :     // You may also determine whether a progress meter is displayed or not.
     248             :     ImageMoments (
     249             :         const casacore::ImageInterface<T>& image,
     250             :         casacore::LogIO &os,
     251             :         casacore::Bool overWriteOutput=false,
     252             :         casacore::Bool showProgress=true
     253             :     );
     254             : 
     255             :     ImageMoments(const ImageMoments<T> &other) = delete;
     256             : 
     257             :     // Destructor
     258             :     ~ImageMoments();
     259             : 
     260             :     ImageMoments<T> &operator=(const ImageMoments<T> &other) = delete;
     261             : 
     262             :     // Set the moment axis (0 relative).  A return value of <src>false</src>
     263             :     // indicates that the axis was not contained in the image. If you don't
     264             :     // call this function, the default state of the class is to set the
     265             :     // moment axis to the spectral axis if it can find one.  Otherwise
     266             :     // an error will result.
     267             :     casacore::Bool setMomentAxis (casacore::Int momentAxis);
     268             : 
     269             :     // This function invokes smoothing of the input image.  Give <src>casacore::Int</src>
     270             :     // arrays for the axes (0 relative) to be smoothed and the smoothing kernel
     271             :     // types (use the <src>enum KernelTypes</src>) for each axis.  Give a
     272             :     // <src>casacore::Double</src> array for the widths (full width for BOXCAR and full
     273             :     // width at half maximum for GAUSSIAN) in pixels of the smoothing kernels for
     274             :     // each axis.  For HANNING smoothing, you always get the quarter-half-quarter
     275             :     // kernel (no matter what you might ask for).  A return value of <src>false</src>
     276             :     // indicates that you have given an inconsistent or invalid set of smoothing
     277             :     // parameters.  If you don't call this function the default state of the
     278             :     // class is to do no smoothing.  The kernel types are specified with
     279             :     // the casacore::VectorKernel::KernelTypes enum
     280             :     casacore::Bool setSmoothMethod(
     281             :         const casacore::Vector<casacore::Int>& smoothAxes,
     282             :         const casacore::Vector<casacore::Int>& kernelTypes,
     283             :         const casacore::Vector<casacore::Quantum<casacore::Double> >& kernelWidths
     284             :    );
     285             : 
     286             :    casacore::Bool setSmoothMethod(
     287             :        const casacore::Vector<casacore::Int>& smoothAxes,
     288             :        const casacore::Vector<casacore::Int>& kernelTypes,
     289             :        const casacore::Vector<casacore::Double>& kernelWidths
     290             :    );
     291             : 
     292             :    // This is the function that does all the computational work.  It should be called
     293             :    // after the <src>set</src> functions.
     294             :    // If the axis being collapsed comes from a coordinate with one axis only,
     295             :    // the axis and its coordinate are physically removed from the output image.  Otherwise,
     296             :    // if <src>removeAxes=true</src> then the output axis is logically removed from the
     297             :    // the output CoordinateSystem.  If <src>removeAxes=false</src> then the axis
     298             :    // is retained with shape=1 and with its original coordinate information (which
     299             :    // is probably meaningless).
     300             :    //
     301             :    // The output vector will hold PagedImages or TempImages (doTemp=true).
     302             :    // If doTemp is true, the outFileName is not used.
     303             :    //
     304             :    // If you create PagedImages, outFileName is the root name for
     305             :    // the output files.  Suffixes will be made up internally to append
     306             :    // to this root.  If you only ask for one moment,
     307             :    // this will be the actual name of the output file.  If you don't set this
     308             :    // variable, the default state of the class is to set the output name root to
     309             :    // the name of the input file.
     310             :    std::vector<std::shared_ptr<casacore::MaskedLattice<T> > >  createMoments(
     311             :        casacore::Bool doTemp, const casacore::String& outFileName,
     312             :        casacore::Bool removeAxes=true
     313             :    );
     314             : 
     315             :    // Set a new image.  A return value of <src>false</src> indicates the
     316             :    // image had an invalid type (this class only accepts casacore::Float or casacore::Double images).
     317             :    casacore::Bool setNewImage (const casacore::ImageInterface<T>& image);
     318             : 
     319             :    // Get CoordinateSystem
     320           0 :    const casacore::CoordinateSystem& coordinates() {return _image->coordinates();};
     321             : 
     322             :    // Get shape
     323           0 :    casacore::IPosition getShape() const { return _image->shape(); }
     324             : 
     325             :    //Set an ImageMomentsProgressMonitor interested in getting updates on the
     326             :    //progress of the collapse process.
     327             :    void setProgressMonitor(ImageMomentsProgressMonitor* progressMonitor);
     328             : 
     329             : private:
     330             : 
     331             :    SPCIIT _image = SPCIIT(nullptr);
     332             :    ImageMomentsProgressMonitor* _progressMonitor = nullptr;
     333             : 
     334             :    // casacore::Smooth an image
     335             :    SPIIT _smoothImage();
     336             : 
     337             :    // Determine the noise by fitting a Gaussian to a histogram
     338             :    // of the entire image above the 25% levels.  If a plotting
     339             :    // device is set, the user can interact with this process.
     340             :    void _whatIsTheNoise (T& noise, const casacore::ImageInterface<T>& image);
     341             : 
     342             : protected:
     343             :    using MomentsBase<T>::os_p;
     344             :    using MomentsBase<T>::showProgress_p;
     345             :    using MomentsBase<T>::momentAxisDefault_p;
     346             :    using MomentsBase<T>::peakSNR_p;
     347             :    using MomentsBase<T>::stdDeviation_p;
     348             :    using MomentsBase<T>::yMin_p;
     349             :    using MomentsBase<T>::yMax_p;
     350             :    using MomentsBase<T>::out_p;
     351             :    using MomentsBase<T>::smoothOut_p;
     352             :    using MomentsBase<T>::goodParameterStatus_p;
     353             :    using MomentsBase<T>::doWindow_p;
     354             :    using MomentsBase<T>::doFit_p;
     355             :    using MomentsBase<T>::doSmooth_p;
     356             :    using MomentsBase<T>::noInclude_p;
     357             :    using MomentsBase<T>::noExclude_p;
     358             :    using MomentsBase<T>::fixedYLimits_p;
     359             :    using MomentsBase<T>::momentAxis_p;
     360             :    using MomentsBase<T>::worldMomentAxis_p;
     361             :    using MomentsBase<T>::kernelTypes_p;
     362             :    using MomentsBase<T>::kernelWidths_p;
     363             :    using MomentsBase<T>::moments_p;
     364             :    using MomentsBase<T>::selectRange_p;
     365             :    using MomentsBase<T>::smoothAxes_p;
     366             :    using MomentsBase<T>::overWriteOutput_p;
     367             :    using MomentsBase<T>::error_p;
     368             :    using MomentsBase<T>::convertToVelocity_p;
     369             :    using MomentsBase<T>::velocityType_p;
     370             :    using MomentsBase<T>::_checkMethod;
     371             : };
     372             : 
     373             : }
     374             : 
     375             : #ifndef CASACORE_NO_AUTO_TEMPLATES
     376             : #include <imageanalysis/ImageAnalysis/ImageMoments.tcc>
     377             : #endif
     378             : #endif

Generated by: LCOV version 1.16