ImageMoments.h

Go to the documentation of this file.
00001 //# ImageMoments.h: generate moments from images
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 //# $Id: ImageMoments.h 20299 2008-04-03 05:56:44Z gervandiepen $
00027 
00028 #ifndef IMAGES_IMAGEMOMENTS_H
00029 #define IMAGES_IMAGEMOMENTS_H
00030 
00031 #include <imageanalysis/ImageAnalysis/MomentsBase.h>
00032 
00033 #include <imageanalysis/ImageTypedefs.h>
00034 
00035 namespace casa {
00036 
00037 class ImageMomentsProgressMonitor;
00038 template <class T> class MaskedLattice;
00039 
00040 // <summary>
00041 // This class generates moments from an image.
00042 // </summary>
00043 
00044 // <use visibility=export>
00045 
00046 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00047 // </reviewed>
00048 
00049 // <prerequisite>
00050 //   <li> <linkto class="ImageInterface">ImageInterface</linkto>
00051 //   <li> <linkto class="MomentsBase">MomentsBase</linkto>
00052 //   <li> <linkto class="LatticeApply">LatticeApply</linkto>   
00053 //   <li> <linkto class="MomentCalcBase">MomentCalcBase</linkto>
00054 // </prerequisite>
00055 
00056 // <etymology>
00057 //   This class computes moments from images
00058 // </etymology>
00059 
00060 // <synopsis>
00061 //  The primary goal of this class is to help spectral-line astronomers analyze 
00062 //  their multi-dimensional images by generating moments of a specified axis.
00063 //  The word "moment" is used loosely here.  It refers to collapsing an axis
00064 //  to one pixel and putting the value of that pixel (for all of the other 
00065 //  non-collapsed axes) to something computed from the data values along
00066 //  the moment axis.  For example, take an RA-DEC-Velocity cube, collapse
00067 //  the velocity axis by computing the mean intensity at each RA-DEC
00068 //  pixel.  This class offers many different moments and a variety of
00069 //  interactive and automatic ways to compute them.
00070 //
00071 //  This class only accepts images of type <src>Float</src> and <src>Double</src>.
00072 //  This restriction is because of the plotting capabilities which are a
00073 //  bit awkward for other types.
00074 //
00075 //  This class makes a distinction between a "moment" and a "method". This
00076 //  boundary is a little blurred, but it claims to refer to the distinction 
00077 //  of what you are computing, as to how the pixels that were included in the 
00078 //  computation were selected.  For example,  a "moment" would be the average value 
00079 //  of some pixels.  A method for selecting those pixels would be a simple range 
00080 //  specifying  a range for which pixels should be included.
00081 //
00082 //  The default state of this class is to do nothing.  If you specify an image via
00083 //  the <src>setImage</src> function then invoking the <src>createMoments</src>
00084 //  function will cause it to compute the integrated itensity along the 
00085 //  spectral axis of the image (if it can find one).  You can change the 
00086 //  computational state of the class from this basic form via the remaining
00087 //  <src>set</src> functions.  You can call any number of these functions to 
00088 //  suit your needs.
00089 //
00090 //  Because there are a wide variety of methods available, if you specify an
00091 //  invalid combination, a table showing the available methods is listed. It
00092 //  is reproduced below for convenience.  
00093 //
00094 //  The basic method is to just compute moments directly from the pixel intensities.  
00095 //  This can be modified by applying pixel intensity inclusion or exclusion ranges.  
00096 //  You can then also smooth the image and compute a mask based on the inclusion or 
00097 //  exclusion ranges applied to the smoothed image.  This mask is then applied to 
00098 //  the unsmoothed data for moment computation.
00099 //
00100 //  The window method does no pixel intensity range selection.  Instead a spectral
00101 //  window is found (hopefully surrounding the spectral line feature) and only the 
00102 //  pixels in that window are used for computation.  This window can be found from the 
00103 //  smoothed or unsmoothed data.  The moments are always computed from the unsmoothed 
00104 //  data.  For each spectrum, the window can be found interactively or automatically.
00105 //  There are two interactive methods.  Either you just mark the window with the
00106 //  cursor, or you interactively fit a Gaussian to the profile and the +/- 3-sigma
00107 //  window is returned.  There are two automatic methods.  Either Bosma's converging
00108 //  mean algorithm is used, or an automatically  fit Gaussian +/- 3-sigma window
00109 //  is returned.
00110 //
00111 //  The fitting method fits Gaussians to spectral features either automatically
00112 //  or interactively.  The moments are then computed from the Gaussian fits
00113 //  (not the data themselves).
00114 //
00115 //  When an output image is created, it will have N-1 axes, where the input image
00116 //  has N axes.  In the output image, the physical axis corresponding to the moment
00117 //  axis will have been removed, but the coordinate information will be retained 
00118 //  for future coordinate transformations. For example, if you have a RA-DEC-VELOCITY 
00119 //  image and you collapsed axis 2 (the DEC axis) the output images would be 
00120 //  RA-VELOCITY with the coordinate information retained for the DEC axis so that 
00121 //  the coupled nature of RA/DEC coordinates is preserved.    
00122 //
00123 //  Output images are created with an all True (good) mask.  If, for a given
00124 //  pixel, the moment calculation fails, then the mask is set to F.
00125 //
00126 //  When making plots, the order in which the spectra are  displayed is determined
00127 //  by the tiling sequence of the image (for optimum speed of access).  
00128 //
00129 //
00130 // <srcblock>
00131 //                   Allowed Methods
00132 //                   ---------------
00133 //
00134 //   Smooth    Window      Fit   in/exclude   Interactive 
00135 //   -----------------------------------------------------
00136 //     N          N         N        N            N       
00137 //     Y/N        N         N        Y            N       
00138 // 
00139 //     Y/N        Y         N        N            Y       
00140 //     Y/N        Y         N        N            N       
00141 //     Y/N        Y         Y        N            Y/N     
00142 //
00143 //     N          N         Y        N            Y/N     
00144 //   ----------------------------------------------------
00145 // </srcblock>
00146 //
00147 // <note role=caution>
00148 // Note that the <src>MEDIAN_COORDINATE</src> moment is not very robust.
00149 // It is very useful for generating quickly a velocity field in a way
00150 // that is not sensitive to noise.    However, it will only give sensible
00151 // results under certain conditions.   It treats the spectrum as a
00152 // probability distribution, generates the cumulative distribution for
00153 // the selected pixels (via an <src>include</src> or <src>exclude</src>
00154 // pixel range, and finds the (interpolated) coordinate coresponding to 
00155 // the 50% value.  The generation of the cumulative distribution and the
00156 // finding of the 50% level really only makes sense if the cumulative
00157 // distribution is monotonically increasing.  This essentially means only
00158 // selecting pixels which are positive or negative.  For this reason, this
00159 // moment type is *only* supported with the basic method (i.e. no smoothing,
00160 // no windowing, no fitting) with a pixel selection range that is either
00161 // all positive, or all negative.
00162 // </note>
00163 //
00164 // <note role=tip>
00165 // If you ignore return error statuses from the functions that set the
00166 // state of the class, the internal status of the class is set to bad.
00167 // This means it will just  keep on returning error conditions until you
00168 // explicitly recover the situation.  A message describing the last
00169 // error condition can be recovered with function errorMessage.
00170 // </note>
00171 // </synopsis>
00172 
00173 // <example>
00174 // <srcBlock>
00176 //
00177 //      Vector<Int> moments(2);
00178 //      moments(0) = ImageMoments<Float>::AVERAGE;
00179 //      moments(1) = ImageMoments<Float>::WEIGHTED_MEAN_COORDINATE;
00180 //      Vector<int> methods(2);
00181 //      methods(0) = ImageMoments<Float>::WINDOW;
00182 //      methods(1) = ImageMoments<Float>::INTERACTIVE;
00183 //      Vector<Int> nxy(2);
00184 //      nxy(0) = 3;
00185 //      nxy(1) = 3;
00186 //
00188 //     
00189 //      PagedImage<Float> inImage(inName);  
00190 //
00192 //
00193 //      LogOrigin or("myClass", "myFunction(...)", WHERE);
00194 //      LogIO os(or);
00195 //      ImageMoments<Float> moment(SubImage<Float>(inName), os);
00196 //
00198 //
00199 //      if (!moment.setMoments(moments)) return 1;
00200 //      if (!moment.setWinFitMethod(methods)) return 1;
00201 //      if (!moment.setMomentAxis(3)) return 1;
00202 //      if (!moment.setPlotting("/xs", nxy)) return 1;
00203 //
00205 //
00206 //      if (!moment.createMoments()) return 1;
00207 // </srcBlock>
00208 // In this example, we generate two moments (average intensity and intensity
00209 // weighted mean coordinate -- usually the velocity field) of axis 3 by the 
00210 // interactive window method.  The interactive plotting is done on the 
00211 // device called <src>/xs</src> (no longer supported).   We put 9 subplots on each page.  The output 
00212 // file names are constructed by the class from the input file name plus some 
00213 // internally generated suffixes.
00214 // </example>
00215 
00216 // <motivation>
00217 //  This is a fundamental and traditional piece of spectral-line image analysis.
00218 // </motivation>
00219 
00220 // <todo asof="1996/11/26">
00221 //   <li> more control over histogram of image noise at start (pixel
00222 //        range and number of bins)
00223 //   <li> better algorithm for seeing if spectrum is pure noise
00224 //   <li> Make this class extensible so users could add their own method.
00225 // </todo>
00226  
00227 
00228 template <class T> class ImageMoments : public MomentsBase<T> {
00229 public:
00230 
00231     // Note that if I don't put MomentCalcBase as a forward declaration
00232     // and use instead  "friend class MomentCalcBase<T>"  The gnu compiler
00233     // fails with a typedef problem.  But I can't solve it with say
00234     // <src>typedef MomentCalcBase<T> gpp_type;</src>  because you can only do a
00235     // typedef with an actual type, not a <tt>T</tt> !
00236     friend class MomentCalcBase<T>;
00237 
00238     ImageMoments() = delete;
00239 
00240     // Constructor takes an image and a <src>LogIO</src> object for logging purposes.
00241     // You specify whether output images are  automatically overwritten if pre-existing,
00242     // or whether an intercative choice dialog widget appears (overWriteOutput=F)
00243     // You may also determine whether a progress meter is displayed or not.
00244     ImageMoments (
00245         const ImageInterface<T>& image,
00246         LogIO &os,
00247         Bool overWriteOutput=False,
00248         Bool showProgress=True
00249     );
00250 
00251     ImageMoments(const ImageMoments<T> &other) = delete;
00252 
00253     // Destructor
00254     ~ImageMoments();
00255 
00256     ImageMoments<T> &operator=(const ImageMoments<T> &other) = delete;
00257 
00258     // Set the moment axis (0 relative).  A return value of <src>False</src>
00259     // indicates that the axis was not contained in the image. If you don't
00260     // call this function, the default state of the class is to set the
00261     // moment axis to the spectral axis if it can find one.  Otherwise
00262     // an error will result.
00263     Bool setMomentAxis (Int momentAxis);
00264 
00265     // This function invokes smoothing of the input image.  Give <src>Int</src>
00266     // arrays for the axes (0 relative) to be smoothed and the smoothing kernel
00267     // types (use the <src>enum KernelTypes</src>) for each axis.  Give a
00268     // <src>Double</src> array for the widths (full width for BOXCAR and full
00269     // width at half maximum for GAUSSIAN) in pixels of the smoothing kernels for
00270     // each axis.  For HANNING smoothing, you always get the quarter-half-quarter
00271     // kernel (no matter what you might ask for).  A return value of <src>False</src>
00272     // indicates that you have given an inconsistent or invalid set of smoothing
00273     // parameters.  If you don't call this function the default state of the
00274     // class is to do no smoothing.  The kernel types are specified with
00275     // the VectorKernel::KernelTypes enum
00276     Bool setSmoothMethod(
00277         const Vector<Int>& smoothAxes,
00278         const Vector<Int>& kernelTypes,
00279         const Vector<Quantum<Double> >& kernelWidths
00280    );
00281 
00282    Bool setSmoothMethod(
00283        const Vector<Int>& smoothAxes,
00284        const Vector<Int>& kernelTypes,
00285        const Vector<Double>& kernelWidths
00286    );
00287 
00288    // This is the function that does all the computational work.  It should be called
00289    // after the <src>set</src> functions.
00290    // If the axis being collapsed comes from a coordinate with one axis only,
00291    // the axis and its coordinate are physically removed from the output image.  Otherwise,
00292    // if <src>removeAxes=True</src> then the output axis is logically removed from the
00293    // the output CoordinateSystem.  If <src>removeAxes=False</src> then the axis
00294    // is retained with shape=1 and with its original coordinate information (which
00295    // is probably meaningless).
00296    //
00297    // The output vector will hold PagedImages or TempImages (doTemp=True).
00298    // If doTemp is True, the outFileName is not used.
00299    //
00300    // If you create PagedImages, outFileName is the root name for
00301    // the output files.  Suffixes will be made up internally to append
00302    // to this root.  If you only ask for one moment,
00303    // this will be the actual name of the output file.  If you don't set this
00304    // variable, the default state of the class is to set the output name root to
00305    // the name of the input file.
00306    vector<SHARED_PTR<MaskedLattice<T> > >  createMoments(
00307        Bool doTemp, const String& outFileName,
00308        Bool removeAxes=True
00309    );
00310 
00311    // Set a new image.  A return value of <src>False</src> indicates the
00312    // image had an invalid type (this class only accepts Float or Double images).
00313    Bool setNewImage (const ImageInterface<T>& image);
00314 
00315    // Get CoordinateSystem
00316    const CoordinateSystem& coordinates() {return _image->coordinates();};
00317 
00318    // Get shape
00319    IPosition getShape() const { return _image->shape(); }
00320 
00321    //Set an ImageMomentsProgressMonitor interested in getting updates on the
00322    //progress of the collapse process.
00323    void setProgressMonitor(ImageMomentsProgressMonitor* progressMonitor);
00324 
00325 private:
00326 
00327    SPCIIT _image = SPCIIT(nullptr);
00328    ImageMomentsProgressMonitor* _progressMonitor = nullptr;
00329 
00330    // Smooth an image
00331    SPIIT _smoothImage();
00332 
00333    // Determine the noise by fitting a Gaussian to a histogram
00334    // of the entire image above the 25% levels.  If a plotting
00335    // device is set, the user can interact with this process.
00336    void _whatIsTheNoise (T& noise, const ImageInterface<T>& image);
00337 
00338 protected:
00339    using MomentsBase<T>::os_p;
00340    using MomentsBase<T>::showProgress_p;
00341    using MomentsBase<T>::momentAxisDefault_p;
00342    using MomentsBase<T>::peakSNR_p;
00343    using MomentsBase<T>::stdDeviation_p;
00344    using MomentsBase<T>::yMin_p;
00345    using MomentsBase<T>::yMax_p;
00346    using MomentsBase<T>::out_p;
00347    using MomentsBase<T>::smoothOut_p;
00348    using MomentsBase<T>::goodParameterStatus_p;
00349    using MomentsBase<T>::doWindow_p;
00350    using MomentsBase<T>::doFit_p;
00351    using MomentsBase<T>::doSmooth_p;
00352    using MomentsBase<T>::noInclude_p;
00353    using MomentsBase<T>::noExclude_p;
00354    using MomentsBase<T>::fixedYLimits_p;
00355    using MomentsBase<T>::momentAxis_p;
00356    using MomentsBase<T>::worldMomentAxis_p;
00357    using MomentsBase<T>::kernelTypes_p;
00358    using MomentsBase<T>::kernelWidths_p;
00359    using MomentsBase<T>::moments_p;
00360    using MomentsBase<T>::selectRange_p;
00361    using MomentsBase<T>::smoothAxes_p;
00362    using MomentsBase<T>::overWriteOutput_p;
00363    using MomentsBase<T>::error_p;
00364    using MomentsBase<T>::convertToVelocity_p;
00365    using MomentsBase<T>::velocityType_p;
00366    using MomentsBase<T>::_checkMethod;
00367 };
00368 
00369 }
00370 
00371 #ifndef CASACORE_NO_AUTO_TEMPLATES
00372 #include <imageanalysis/ImageAnalysis/ImageMoments.tcc>
00373 #endif
00374 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1