casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MomentsBase.h
Go to the documentation of this file.
00001 //# MomentsBase.h: base class for moment generator 
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: MomentsBase.h 20299 2008-04-03 05:56:44Z gervandiepen $
00027 
00028 #ifndef IMAGES_MOMENTSBASE_H
00029 #define IMAGES_MOMENTSBASE_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <coordinates/Coordinates/CoordinateSystem.h>
00035 #include <casa/Quanta/Quantum.h>
00036 #include <measures/Measures/MDoppler.h>
00037 #include <casa/System/PGPlotter.h>
00038 #include <casa/Logging/LogIO.h>
00039 #include <casa/Arrays/Vector.h>
00040 #include <casa/iosfwd.h>
00041 
00042 namespace casa { //# NAMESPACE CASA - BEGIN
00043 
00044 //# Forward Declarations
00045 template <class T> class MomentCalcBase;
00046 class IPosition;
00047 class String;
00048 class Unit;
00049 
00050 // <summary>
00051 // This class is a base class for generating moments from an image or a spectral data.
00052 // </summary>
00053 
00054 // <use visibility=export>
00055 
00056 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00057 // </reviewed>
00058 
00059 // <prerequisite>
00060 //   <li> <linkto class="ImageMoments">ImageMoments</linkto>   
00061 //   <li> <linkto class="MSMoments">MSMoments</linkto>   
00062 //   <li> <linkto class="LatticeApply">LatticeApply</linkto>   
00063 //   <li> <linkto class="MomentCalcBase">MomentCalcBase</linkto>
00064 // </prerequisite>
00065 
00066 // <etymology>
00067 //   This class is an abstract class to compute moments from images or spectral data.
00068 // </etymology>
00069 
00070 // <synopsis>
00071 //  The primary goal of MSMoments, ImageMoments, and MSMoments are to help 
00072 //  spectral-line astronomers analyze their multi-dimensional images or 
00073 //  spectral data (in the form of MeasurementSet) by generating moments of 
00074 //  a specified axis.  ImageMoments is a specialized class to generate moments 
00075 //  from images, while MSMoments is designed properly for MeasurementSet input.
00076 //  MSMoments class is an abstract class that is inherited by the above two 
00077 //  concrete classes.
00078 //  MomentsBase provides interface layer to the MomentCalculators so that 
00079 //  functionalities in MomentCalculators can be shared with ImageMoments and 
00080 //  MSMoments.
00081 //  The word "moment" is used loosely here.  It refers to collapsing an axis
00082 //  to one pixel and putting the value of that pixel (for all of the other 
00083 //  non-collapsed axes) to something computed from the data values along
00084 //  the moment axis.  For example, take an RA-DEC-Velocity cube, collapse
00085 //  the velocity axis by computing the mean intensity at each RA-DEC
00086 //  pixel.  This class and its inheritances offer many different moments and a variety of
00087 //  interactive and automatic ways to compute them. 
00088 //
00089 
00090 // <motivation>
00091 //  MSMoments is defined so that moments can be generated from both images 
00092 //  and spectral data (in the form of MeasurementSet).  
00093 // </motivation>
00094  
00095 
00096 template <class T> class MomentsBase
00097 {
00098 public:
00099 
00100 // Note that if I don't put MomentCalcBase as a forward declaration
00101 // and use instead  "friend class MomentCalcBase<T>"  The gnu compiler
00102 // fails with a typedef problem.  But I can't solve it with say
00103 // <src>typedef MomentCalcBase<T> gpp_type;</src>  because you can only do a 
00104 // typedef with an actual type, not a <tt>T</tt> !
00105    friend class MomentCalcBase<T>;
00106 
00107 // Constructor takes an image and a <src>LogIO</src> object for logging purposes.
00108 // You specify whether output images are  automatically overwritten if pre-existing,
00109 // or whether an intercative choice dialog widget appears (overWriteOutput=F)
00110 // You may also determine whether a progress meter is displayed or not.
00111    MomentsBase( LogIO &os,
00112                 Bool overWriteOutput=False,
00113                 Bool showProgress=True );
00114 
00115 // Destructor
00116    virtual ~MomentsBase();
00117 
00118 // This <src>enum MomentTypes</src> is provided for use with the
00119 // <src>setMoments</src> function.  It gives the allowed moment
00120 // types that you can ask for. 
00121 
00122 enum MomentTypes {
00123     
00124 // The average intensity
00125    AVERAGE,
00126 
00127 // The integrated intensity
00128    INTEGRATED,
00129 
00130 // The intensity weighted mean coordinate (usually velocity)
00131    WEIGHTED_MEAN_COORDINATE,
00132 
00133 // The intensity weighted coordinate (usually velocity) dispersion
00134    WEIGHTED_DISPERSION_COORDINATE,
00135 
00136 // The median intensity
00137    MEDIAN,
00138 
00139 // The median coordinate (usually velocity). Treat the spectrum as
00140 // a probability distribution, generate the cumulative distribution, 
00141 // and find the coordinate corresponding to the 50% value.
00142    MEDIAN_COORDINATE,
00143 
00144 // The standard deviation about the mean of the intensity
00145    STANDARD_DEVIATION,
00146 
00147 // The rms of the intensity
00148    RMS,
00149 
00150 // The absolute mean deviation of the intensity
00151    ABS_MEAN_DEVIATION,
00152 
00153 // The maximum value of the intensity
00154    MAXIMUM,
00155 
00156 // The coordinate (usually velocity) of the maximum value of the intensity
00157    MAXIMUM_COORDINATE,
00158 
00159 // The minimum value of the intensity
00160    MINIMUM,
00161 
00162 // The coordinate (usually velocity) of the minimum value of the intensity
00163    MINIMUM_COORDINATE,
00164 
00165 // Total number
00166    NMOMENTS,
00167 
00168 // Default value is the integrated intensity
00169    DEFAULT = INTEGRATED};
00170 
00171 // Set the desired moments via an <src>Int</src> array.  Each <src>Int</src>
00172 // specifies a different moment; the allowed values and their meanings
00173 // are given by the <src>enum MomentTypes</src>.   A return value
00174 // of <src>False</src> indicates you asked for an out of range 
00175 // moment.  If you don't call this function, the default state of the 
00176 // class is to request the integrated intensity.
00177    Bool setMoments (const Vector<Int>& moments);
00178 
00179 // Set the moment axis (0 relative).  A return value of <src>False</src> 
00180 // indicates that the axis was not contained in the image. If you don't
00181 // call this function, the default state of the class is to set the 
00182 // moment axis to the spectral axis if it can find one.  Otherwise 
00183 // an error will result.
00184    virtual Bool setMomentAxis (const Int&) ;
00185 
00186 // The <src>enum MethodTypes</src> is provided for use with the
00187 // <src>setWinFitMethod</src> function.  It gives the allowed moment
00188 // methods which are available with this function.  The use of these
00189 // methods is described further with the description of this function
00190 // as well as in the general documentation earlier.
00191 enum MethodTypes {
00192 
00193 // Invokes the spectral windowing method
00194    WINDOW,
00195 
00196 // Invokes Gaussian fitting
00197    FIT,
00198 
00199 // Invokes interactive methods
00200    INTERACTIVE,
00201 
00202    NMETHODS};
00203 
00204 
00205 // The method by which you compute the moments is specified by calling
00206 // (or not calling) the <src>setWinFitMethod</src> and
00207 // <src>setSmoothMethod</src> functions.  The default state of the class 
00208 // is to compute directly on all (or some according to <src>setInExClude</src>) 
00209 // of the pixels in the spectrum.  Calling these functions modifies the 
00210 // computational state to something more complicated. 
00211 // 
00212 // The <src>setWinMethod</src> function requires an <src>Int</src> array
00213 // as its argument.  Each <src>Int</src> specifies a different method
00214 // that you can invoke (either separately or in combination).  The
00215 // allowed values and their meanings are given by the 
00216 // <src>enum MethodTypes</src>.
00217 //
00218 // Both the windowing and fitting methods have interactive modes. The
00219 // windowing method also has a fitting flavour, so if you set both 
00220 // MomentsBase::WINDOW and MomentsBase::FIT, you would be invoking the 
00221 // windowing method but determining the window by fitting Gaussians 
00222 // automatically (as MomentsBase::INTERACTIVE) was not given.
00223 //               
00224 // If you don't call this function, then neither the windowing nor fitting
00225 // methods are invoked.  A return value of <src>False</src> indicates
00226 // that you asked for an illegal method.
00227    Bool setWinFitMethod(const Vector<Int>& method);
00228 
00229 
00230 // This function invokes smoothing of the input image.  Give <src>Int</src> 
00231 // arrays for the axes (0 relative) to be smoothed and the smoothing kernel 
00232 // types (use the <src>enum KernelTypes</src>) for each axis.  Give a
00233 // <src>Double</src> array for the widths (full width for BOXCAR and full 
00234 // width at half maximum for GAUSSIAN) in pixels of the smoothing kernels for
00235 // each axis.  For HANNING smoothing, you always get the quarter-half-quarter
00236 // kernel (no matter what you might ask for).  A return value of <src>False</src>
00237 // indicates that you have given an inconsistent or invalid set of smoothing 
00238 // parameters.  If you don't call this function the default state of the
00239 // class is to do no smoothing.  The kernel types are specified with
00240 // the VectorKernel::KernelTypes enum
00241 // <group>
00242    virtual Bool setSmoothMethod(const Vector<Int>&,
00243                                 const Vector<Int>&,
00244                                 const Vector<Quantum<Double> >&);
00245    Bool setSmoothMethod(const Vector<Int>& smoothAxes,
00246                         const Vector<Int>& kernelTypes,
00247                         const Vector<Double>& kernelWidths);
00248 // </group>
00249 
00250 // You may specify a pixel intensity range as either one for which
00251 // all pixels in that range are included in the moment calculation,
00252 // or one for which all pixels in that range are excluded from the moment
00253 // calculations.  One or the other of <src>include</src> and <src>exclude</src>
00254 // must therefore be a zero length vector if you call this function.
00255 // A return value of <src>False</src> indicates that you have given both
00256 // an <src>include</src> and an <src>exclude</src> range.  If you don't call
00257 // this function, the default state of the class is to include all pixels.
00258    Bool setInExCludeRange(const Vector<T>& include,
00259                           const Vector<T>& exclude);
00260 
00261 // This function is used to help assess whether a spectrum along the moment 
00262 // axis is all noise or not.  If it is all noise, there is not a lot of point
00263 // to trying to computing the moment.  This is only needed for the automatic
00264 // window or fit methods.  If you are using an interactive nethod, you assess
00265 // yourself whether the spectrum contains signal or not.
00266 // 
00267 // <src>peakSNR</src> is the signal-to-noise ratio of the peak value in the
00268 // spectrum below which the spectrum is considered pure noise.  
00269 // <src>stdDeviation</src> is the standard deviation of the noise for the
00270 // input image.  
00271 //
00272 // Default values for one or the other parameter are indicated by giving zero.
00273 //
00274 // The default state of the class then is to set <src>peakSNR=3</src>
00275 // and/or to work out the noise level from a Gaussian fit to a histogram
00276 // (above 25%) of the entire image (it is very hard to get an accurate 
00277 // estimate of the noise a single spectrum).  If you have specified a 
00278 // plotting device (see <src>setPlotting</src>) then you get to interact with 
00279 // the fitting procedure if you want to.  A return value of <src>False</src> 
00280 // indicates you have set invalid values.  
00281    Bool setSnr(const T& peakSNR, 
00282                const T& stdDeviation);
00283 
00284 // This is the output file name for the smoothed image.   It can be useful
00285 // to have access this to this image when trying to get the pixel
00286 // <src>include</src> or <src>exclude</src> range correct for the smooth-clip
00287 // method.  The default state of the class is to not output the smoothed image. 
00288    Bool setSmoothOutName(const String& smOut);
00289 
00290 // This sets the name of the PGPLOT plotting device, the number of
00291 // subplots in x and y per page and whether each spectrum plot is 
00292 // autoscaled individually (<src>yInd=False</src>) or they are 
00293 // plotted with the same range automatically determined from the image.
00294 // Plotting is not invoked for all states of the class.  It is only
00295 // needed for the interactive methods.  If you ask for a method that
00296 // needs to determine the noise from the image, and you set the
00297 // plotting device, then this will be done interactively.  Similarly,
00298 // if you invoke the automatic window or fit methods, but set the
00299 // plotting device, then you will see plots of the spectra and
00300 // the selected windows and fits, respectively.
00301 //
00302 // The default state of the class is that no plotting characteristics are set.
00303 // However, if you set <src>device</src> but offer a zero length array for
00304 // <src>nxy</src> then the latter is set to [1,1].   A return value
00305 // of <src>False</src> indicates that you gave roo many values in the
00306 // <src>nxy</src> vector.
00307    Bool setPlotting(PGPlotter& device,
00308                     const Vector<Int>& nxy,
00309                     const Bool yInd=False);
00310 
00311 // Set Velocity type.  This is used for moments for which the moment axis is
00312 // a spectral axis for which the coordinate is traditionally presented in
00313 // km/s   You can select the velocity definition. The default state of the
00314 // class is to use the radio definition.
00315    void setVelocityType (MDoppler::Types type);
00316 
00317 // CLose plotter
00318    void closePlotting();
00319 
00320 // Reset argument error condition.  If you specify invalid arguments to
00321 // one of the above functions, an internal flag will be set which will
00322 // prevent the <src>createMoments</src> function, which is defined in its inheritances,
00323 // from doing anything
00324 // (should you have chosen to igmore the Boolean return values of the functions).
00325 // This function allows you to reset that internal state to good.
00326    void resetError () {goodParameterStatus_p = True; error_p = "";};
00327 
00328 // Recover last error message
00329    String errorMessage() const {return error_p;};
00330 
00331 // Get CoordinateSystem
00332    virtual CoordinateSystem coordinates() ;
00333 
00334 // Helper function to convert a string containing a list of desired methods to
00335 // the correct <src>Vector<Int></src> required for the <src>setWinFitMethod</src> function.
00336 // This may be usful if your user interface involves strings rather than integers.
00337 // A new value is added to the output vector (which is resized appropriately) if any of the 
00338 // substrings "window", "fit" or "interactive" (actually "win", "box" and 
00339 // "inter" will do) is present.
00340    static Vector<Int> toMethodTypes (const String& methods);
00341 
00342 
00343    virtual IPosition getShape() { return IPosition() ; } ;
00344 
00345 protected:
00346 
00347    LogIO os_p;
00348    Bool showProgress_p;
00349    Int momentAxisDefault_p;
00350    T peakSNR_p;
00351    T stdDeviation_p;
00352    T yMin_p, yMax_p;
00353    String out_p;
00354    String smoothOut_p;
00355    Bool goodParameterStatus_p;
00356    Bool doWindow_p, doFit_p, doAuto_p, doSmooth_p, noInclude_p, noExclude_p;
00357    Bool fixedYLimits_p;
00358 
00359    Int momentAxis_p;
00360    Int worldMomentAxis_p;
00361    Vector<Int> kernelTypes_p;
00362    Vector<Quantum<Double> > kernelWidths_p;   
00363    Vector<Int> nxy_p;
00364    Vector<Int> moments_p;
00365    Vector<T> selectRange_p;
00366    Vector<Int> smoothAxes_p;
00367    PGPlotter plotter_p;
00368    Bool overWriteOutput_p;
00369    String error_p;
00370    Bool convertToVelocity_p;
00371    MDoppler::Types velocityType_p;
00372 
00373 // Check that the combination of methods that the user has requested is valid
00374 // List a handy dandy table if not.
00375    Bool checkMethod();
00376 
00377 // Plot a histogram                     
00378    static void drawHistogram  (const Vector<T>& values,
00379                                const Vector<T>& counts,
00380                                PGPlotter& plotter);
00381 
00382 // Plot a line 
00383    static void drawLine       (const Vector<T>& x,
00384                                const Vector<T>& y,
00385                                PGPlotter& plotter);
00386                      
00387 // Draw a vertical line of the given length at a given abcissa 
00388    static void drawVertical   (const T& x,
00389                                const T& yMin,
00390                                const T& yMax,
00391                                PGPlotter& plotter);
00392 
00393 // Read the cursor and return its coordinates 
00394    static Bool getLoc (T& x,
00395                        T& y,
00396                        PGPlotter& plotter);
00397 
00398 // Convert a <tt>T</tt> to a <tt>Float</tt> for plotting
00399    static Float convertT (const T value) {return Float(real(value));};
00400 
00401 // Convert a <tt>Float</tt> (from plotting) to a <tt>T</tt> 
00402    static T convertF (const Float value) {return T(value);};
00403 
00404 // Fish out cursor values
00405    static Bool readCursor (PGPlotter& plotter, 
00406                            Float& x,
00407                            Float& y, 
00408                            String& ch);
00409 
00410 // Take the user's data inclusion and exclusion data ranges and
00411 // generate the range and Booleans to say what sort it is
00412    Bool setIncludeExclude (Vector<T>& range,
00413                            Bool& noInclude,
00414                            Bool& noExclude,
00415                            const Vector<T>& include,
00416                            const Vector<T>& exclude,
00417                            ostream& os);
00418 
00419 // Set the output image suffixes and units
00420    Bool setOutThings(String& suffix,
00421                      Unit& momentUnits,
00422                      const Unit& imageUnits,
00423                      const String& momentAxisUnits,
00424                      const Int moment, Bool convertToVelocity);
00425 
00426 // Make output Coordinates
00427    CoordinateSystem makeOutputCoordinates (IPosition& outShape,
00428                                            const CoordinateSystem& cSysIn,
00429                                            const IPosition& inShape,
00430                                            Int momentAxis, Bool removeAxis);
00431 };
00432 
00433 
00434 } //# NAMESPACE CASA - END
00435 
00436 #ifndef CASACORE_NO_AUTO_TEMPLATES
00437 #include <imageanalysis/ImageAnalysis/MomentsBase.tcc>
00438 #endif //# CASACORE_NO_AUTO_TEMPLATES
00439 #endif