casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MomentCalculator.h
Go to the documentation of this file.
00001 //# MomentCalculator.h: 
00002 //# Copyright (C) 1997,1999,2000,2001,2002
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: MomentCalculator.h 20299 2008-04-03 05:56:44Z gervandiepen $
00027 
00028 #ifndef IMAGES_MOMENTCALCULATOR_H
00029 #define IMAGES_MOMENTCALCULATOR_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <coordinates/Coordinates/CoordinateSystem.h>
00034 #include <coordinates/Coordinates/SpectralCoordinate.h>
00035 #include <lattices/Lattices/LineCollapser.h>
00036 #include <scimath/Functionals/Gaussian1D.h>
00037 #include <scimath/Mathematics/NumericTraits.h>
00038 #include <casa/System/PGPlotter.h>
00039 #include <casa/Arrays/Vector.h>
00040 #include <casa/Logging/LogIO.h>
00041 
00042 namespace casa { //# NAMESPACE CASA - BEGIN
00043 
00044 //# Forward Declarations
00045 template <class T> class MomentsBase;
00046 template <class T> class ImageMoments;
00047 template <class T> class MSMoments;
00048 
00049 // <summary>
00050 // Abstract base class for moment calculator classes
00051 // </summary>
00052 // <use visibility=export>
00053 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00054 // </reviewed>
00055 //
00056 // <prerequisite>
00057 //   <li> <linkto class="MomentsBase">MomentsBase</linkto>
00058 //   <li> <linkto class="ImageMoments">ImageMoments</linkto>
00059 //   <li> <linkto class="MSMoments">MSMoments</linkto>
00060 //   <li> <linkto class="LatticeApply">LatticeApply</linkto>
00061 //   <li> <linkto class="LineCollapser">LineCollapser</linkto>
00062 // </prerequisite>
00063 //
00064 // <synopsis>
00065 //  This class, its concrete derived classes, and the classes LineCollapser,
00066 //  ImageMoments, MSMoments, and LatticeApply are connected as follows.   LatticeApply offers 
00067 //  functions so that the application programmer does not need to worry about how 
00068 //  to optimally iterate through a Lattice; it deals with tiling and to a 
00069 //  lesser extent memory.    LatticeApply functions are used by offering a class 
00070 //  object to them that has a member function with a name and signature 
00071 //  specified by an abstract base class that LatticeApply uses and the 
00072 //  offered class inherits from.   Specifically, in this case, MomentCalcBase
00073 //  inherits from LineCollapser and LatticeApply uses objects and methods of this
00074 //  class (but does not inherit from it).  This defines the functions
00075 //  <src>collapse</src> and <src>multiProcess</src> which operate on a vector
00076 //  extracted from a Lattice.  The former returns one number, the latter a vector
00077 //  of numbers from that profile.  MomentCalcBase is a base class for
00078 //  for moment calculation and the <src>multiProcess</src>
00079 //  functions are used to compute moments  (e.g., mean, sum, sum squared, 
00080 //  intensity weighted velocity etc).
00081 //
00082 //  It is actually the concrete classes derived from MomentCalcBase (call them,
00083 //  as a group, the MomentCalculator classes) that implement the <src>multiProcess</src> 
00084 //  functions.  These derived classes allow different 
00085 //  algorithms to be written with which moments of the vector can be computed. 
00086 //
00087 //  Now, so far, we have a LatticeApply function which iterates through Lattices,
00088 //  extracts vectors, and offers them up to functions implemented in the derived 
00089 //  MomentCalculator classes to compute the moments.   As well as that, we need some
00090 //  class to actually construct the MomentCalculator classes and to feed them to 
00091 //  LatticeApply.   This is the role of the ImageMoments or MSMoments classes.  
00092 //  They are a high level 
00093 //  class which takes control information from users specifying which moments they 
00094 //  would like to calculate and how. They also provide the ancilliary masking lattice to 
00095 //  the MomentCalculator constructors. The actual computational work is done by the 
00096 //  MomentCalculator classes. So MomentsBase, MomentCalcBase and their derived 
00097 //  MomentCalculator classes are really one unit; none of them are useful without 
00098 //  the others.  The separation of functionality is caused by having the
00099 //  LatticeApply class that knows all about optimally iterating through Lattices.
00100 //
00101 //  The coupling between these classes is done partly by the "friendship".   MomentsBase and 
00102 //  its inheritances 
00103 //  grant friendship to MomentCalcBase so that the latter has access to the private data and 
00104 //  private functions of the formers.  MomentCalcBase then operates as an interface between 
00105 //  its derived MomentCalculator classes and ImageMoments or MSMoments. It retrieves private data 
00106 //  from these classes, and also activates private functions in these classes, on behalf 
00107 //  of the MomentCalculator classes. The rest of the coupling is done via the constructors 
00108 //  of the derived MomentCalculator classes.  
00109 //
00110 //  Finally, MomentCalcBase also has a number of protected functions that are common to its
00111 //  derived classes (e.g. plotting, fitting, accumulating sums etc).  It also has protected 
00112 //  data that is common to all the MomentCalculator classes.  This protected data is accessed 
00113 //  directly by name rather than with interface functions as there is too much of it.  Of 
00114 //  course, since MomentCalcBase is an abstract base class, it is up to the MomentCalculator 
00115 //  classes to give the MomentCalcBase protected data objects values.
00116 //
00117 //  For discussion about different moments and algorithms to compute them see the 
00118 //  discussion in <linkto class="MomentsBase">MomentsBase</linkto>, 
00119 //  <linkto class="ImageMoments">ImageMoments</linkto>, 
00120 //  <linkto class="MSMoments">MSMoments</linkto> and also in
00121 //  the derived classes documentation.
00122 // </synopsis>
00123 //
00124 // <example>
00125 //  Since MomentCalcBase is an abstract class, we defer code examples to
00126 //  the derived classes.
00127 // </example>
00128 //
00129 // <motivation>
00130 // We were desirous of writing functions to optimally iterate through Lattices
00131 // so that the application programmer did not have to know anything about tiling
00132 // or memory if possible.   These are the LatticeApply functions. To incorporate 
00133 // MomentsBase and its inheritances into this scheme required some of it to be shifted into 
00134 // MomentCalcBase and its derived classes.
00135 // </motivation>
00136 //
00137 // <note role=tip>
00138 // Note that there are is assignment operator or copy constructor.
00139 // Do not use the ones the system would generate either.
00140 // </note>
00141 //
00142 // <todo asof="yyyy/mm/dd">
00143 //  <li> Derive more classes !
00144 // </todo>
00145 
00146 
00147 template <class T> class MomentCalcBase : public LineCollapser<T,T>
00148 {
00149 public:
00150    virtual ~MomentCalcBase();
00151 
00152 // Returns the number of failed fits if doing fitting
00153    virtual uInt nFailedFits() const;
00154 
00155 protected:
00156 
00157 // A number of private data members are kept here in the base class
00158 // as they are common to the derived classes.  Since this class
00159 // is abstract, they have to be filled by the derived classes.
00160 
00161 // CoordinateSystem
00162    CoordinateSystem cSys_p;
00163 
00164 // This vector is a container for all the possible moments that
00165 // can be calculated.  They are in the order given by the MomentsBase
00166 // enum MomentTypes
00167    Vector<T> calcMoments_p;
00168    Vector<Bool> calcMomentsMask_p;
00169 
00170 // This vector tells us which elements of the calcMoments_p vector
00171 // we wish to select
00172    Vector<Int> selectMoments_p;
00173 
00174 // Although the general philosophy of these classes is to compute
00175 // all the posisble moments and then select the ones we want,
00176 // some of them are too expensive to calculate unless they are
00177 // really wanted.  These are the median moments and those that
00178 // require a second pass.  These control Bools tell us whether
00179 // we really want to compute the expensive ones.
00180    Bool doMedianI_p, doMedianV_p, doAbsDev_p;
00181 
00182 // These vectors are used to transform coordinates between pixel and world
00183    Vector<Double> pixelIn_p, worldOut_p;
00184 
00185 // All computations involving Coordinate conversions are relatively expensive
00186 // These Bools signifies whether we need coordinate calculations or not for
00187 // the full profile, and for some occaisional calculations
00188    Bool doCoordProfile_p, doCoordRandom_p;
00189 
00190 // This vector houses the world coordinate values for the profile if it
00191 // was from a separable axis. This means this vector can be pre computed 
00192 // just once, instead of working out the coordinates for each profile 
00193 // (expensive).  It should only be filled if doCoordCalc_p is True
00194    Vector<Double> sepWorldCoord_p;
00195 
00196 // This gives the plotter name.  If no plotting, it won't be attached
00197    PGPlotter plotter_p;
00198 
00199 // This Bool tells us whether we want to see all profiles plotted with the 
00200 // Y range or whether they are to be scaled individually
00201    Bool fixedYLimits_p;
00202 
00203 // When we are plotting, if we have asked to all profiles with the same 
00204 // Y min and max, these are the values to use
00205    T yMinAuto_p, yMaxAuto_p;
00206 
00207 // This vector is used to hold the abcissa values when plotting profiles
00208    Vector<T> abcissa_p;
00209 
00210 // This string tells us the name of the moment axis (VELO or FREQ etc)
00211    String momAxisType_p;
00212 
00213 // This is the number of Gaussian fits that failed.
00214    uInt nFailed_p;
00215 
00216 // This scale factor is the increment along the moment axis
00217 // applied so that units for the Integrated moment are like
00218 // Jy/beam.km/s (or whatever is needed for the moment axis units)
00219 // For non-linear velocities (e.g. optical) this is approximate
00220 // only and is computed at the reference pixel
00221    Double integratedScaleFactor_p;
00222 
00223 // Accumulate statistical sums from a vector
00224    void accumSums(typename NumericTraits<T>::PrecisionType& s0,
00225                   typename NumericTraits<T>::PrecisionType& s0Sq,
00226                   typename NumericTraits<T>::PrecisionType& s1,
00227                   typename NumericTraits<T>::PrecisionType& s2,
00228                   Int& iMin,
00229                   Int& iMax,
00230                   T& dMin,
00231                   T& dMax,   
00232                   const Int i,  
00233                   const T datum,
00234                   const Double coord) const;
00235 
00236 // Determine if the spectrum is pure noise 
00237    uInt allNoise(T& dMean,
00238                  const Vector<T>& data,
00239                  const Vector<Bool>& mask,
00240                  const T peakSNR,
00241                  const T stdDeviation) const;
00242 
00243 // Check validity of constructor inputs
00244    void constructorCheck(Vector<T>& calcMoments,
00245                          Vector<Bool>& calcMomentsMask,
00246                          const Vector<Int>& selectMoments,
00247                          const uInt nLatticeOut) const;
00248 
00249 // Convert from <tt>T</tt> to <tt>Float</tt> for plotting
00250    static Float convertT(const T value);
00251 
00252 // Convert from <tt>Float</tt> (from plotting) to a <tt>T</tt> 
00253    static T convertF(const Float value);
00254 
00255 // Find out from the selectMoments array whether we want
00256 // to compute the more expensive moments
00257    void costlyMoments(MomentsBase<T>& iMom,
00258                       Bool& doMedianI,  
00259                       Bool& doMedianV,
00260                       Bool& doAbsDev) const;
00261 
00262 // Return reference plotting device from ImageMoments or MSMoments object
00263    PGPlotter& device(MomentsBase<T>& iMom) const;
00264 
00265 // Return automatic/interactive switch from the ImageMoments or MSMoments object
00266    Bool doAuto(const MomentsBase<T>& iMom) const;
00267 
00268 // Return the Bool saying whether we need to compute coordinates
00269 // or not for the requested moments
00270    void doCoordCalc(Bool& doCoordProfile,
00271                     Bool& doCoordRandom,
00272                     const MomentsBase<T>& iMom) const;
00273 
00274 // Return the Bool from the ImageMoments or MSMoments object saying whether we 
00275 // are going to fit Gaussians to the profiles or not.
00276    Bool doFit(const MomentsBase<T>& iMom) const;
00277 
00278 // Draw a horizontal line across the full x range of the plot
00279    void drawHorizontal(const T& y,
00280                        PGPlotter& plotter) const;
00281 
00282 // Draw a spectrum on the current panel with the box already drawn on
00283    void drawLine (const Vector<T>& x,
00284                   const Vector<T>& y,
00285                   PGPlotter& plotter) const;
00286 
00287 // Draw and label a spectrum on the current or next panel
00288    Bool drawSpectrum (const Vector<T>& x,
00289                       const Vector<T>& y,
00290                       const Vector<Bool>& mask,
00291                       const Bool fixedYLimits,
00292                       const T yMinAuto,
00293                       const T yMaxAuto,
00294                       const String xLabel, 
00295                       const String yLabel, 
00296                       const String title,
00297                       const Bool advancePanel,
00298                       PGPlotter& plotter) const;
00299 
00300 // Draw on lines marking the mean and +/- sigma
00301    void drawMeanSigma  (const T dMean,
00302                         const T dSigma,
00303                         PGPlotter& plotter) const;
00304 
00305 // Draw a vertical line of the given length at a given abcissa
00306    void drawVertical(const T x,
00307                      const T yMin,
00308                      const T yMax,
00309                      PGPlotter& plotter) const;
00310 
00311 // Find the next masked or unmasked point in a vector
00312    Bool findNextDatum     (uInt& iFound,
00313                            const uInt& n,
00314                            const Vector<Bool>& mask,
00315                            const uInt& iStart,
00316                            const Bool& findGood) const;
00317    
00318 // Fit a Gaussian to x and y arrays given guesses for the gaussian parameters
00319    Bool fitGaussian (uInt& nFailed,
00320                      T& peak,
00321                      T& pos,
00322                      T& width,
00323                      T& level,
00324                      const Vector<T>& x,
00325                      const Vector<T>& y,
00326                      const Vector<Bool>& mask,
00327                      const T peakGuess,
00328                      const T posGuess,
00329                      const T widthGuess,
00330                      const T levelGuess) const;
00331                         
00332 // Return the fixed Y-plotting limits switch from the
00333 // ImageMoments or MSMoments object
00334    Bool fixedYLimits(const MomentsBase<T>& iMom) const;
00335 
00336 // Automatically fit a Gaussian to a spectrum, including finding the
00337 // starting guesses.
00338    Bool getAutoGaussianFit(uInt& nFailed,
00339                            Vector<T>& gaussPars,
00340                            const Vector<T>& x,
00341                            const Vector<T>& y,
00342                            const Vector<Bool>& mask,
00343                            const T peakSNR,
00344                            const T stdDeviation,
00345                            PGPlotter& plotter,
00346                            const Bool fixedYLimits,
00347                            const T yMinAuto,
00348                            const T yMaxAuto,
00349                            const String xLabel,
00350                            const String yLabel,
00351                            const String title) const;
00352 
00353 // Automatically work out a guess for the Gaussian parameters
00354 // Returns False if all pixels masked.
00355    Bool getAutoGaussianGuess(T& peakGuess,    
00356                              T& posGuess,
00357                              T& widthGuess,
00358                              T& levelGuess,
00359                              const Vector<T>& x,
00360                              const Vector<T>& y,
00361                              const Vector<Bool>& mask) const;
00362 
00363 // Read the cursor button
00364    void getButton(Bool& reject,
00365                   Bool& redo,
00366                   PGPlotter& plotter) const;
00367 
00368 
00369 // Interactively define a guess for a Gaussian fit, and then
00370 // do the fit.  Do this repeatedly  until the user is content.
00371    Bool getInterGaussianFit(uInt& nFailed,
00372                             Vector<T>& gaussPars,
00373                             LogIO& os,
00374                             const Vector<T>& x,
00375                             const Vector<T>& y,  
00376                             const Vector<Bool>& mask,
00377                             const Bool fixedYLimits,
00378                             const T yMinAuto,
00379                             const T yMaxAuto,
00380                             const String xLabel,
00381                             const String yLabel,
00382                             const String title,
00383                             PGPlotter& plotter) const;
00384 
00385 // Interactively define a guess for the Gaussian parameters
00386    void getInterGaussianGuess(T& peakGuess,
00387                               T& posGuess,
00388                               T& widthGuess,
00389                               Vector<Int>& window,
00390                               Bool& reject,
00391                               LogIO& os,
00392                               const Int nPts,
00393                               PGPlotter& plotter) const;
00394 
00395 // Read the cursor and return its coordinates if not off the plot.
00396 // Also interpret which button was pressed
00397    Bool getLoc(T& x,
00398                Bool& allSubsequent,
00399                Bool& ditch,
00400                Bool& redo,
00401                const Bool final,
00402                PGPlotter& plotter) const;
00403                         
00404 // Compute the world coordinate for the given moment axis pixel   
00405    Double getMomentCoord(MomentsBase<T>& iMom,
00406                          Vector<Double>& pixelIn,
00407                          Vector<Double>& worldOut,
00408                          const Double momentPixel) const;
00409 
00410 // Examine a mask and determine how many segments of unmasked points
00411 // it consists of.    
00412    void lineSegments (uInt& nSeg,
00413                       Vector<uInt>& start,
00414                       Vector<uInt>& nPts,
00415                       const Vector<Bool>& mask) const;
00416 
00417 // Resize an abcissa vector for plotting
00418    void makeAbcissa(Vector<T>& x,
00419                     const Int& n) const;
00420 
00421 // Return the moment axis from the ImageMoments or MSMoments object
00422    Int& momentAxis(MomentsBase<T>& iMom) const;
00423 
00424 // Return the name of the moment/profile axis
00425    String momentAxisName(const CoordinateSystem&,
00426                          const MomentsBase<T>& iMom) const;
00427 
00428 // Return the number of moments that the ImageMoments or MSMoments class can calculate
00429    uInt nMaxMoments() const;
00430 
00431 // Return the peak SNR for determination of all noise spectra from
00432 // the ImageMoments or MSMoments object
00433    T& peakSNR(MomentsBase<T>& iMom) const;
00434 
00435 // Return the selected pixel intensity range from the ImageMoments or MSMoments
00436 // object and the Bools describing whether it is inclusion or exclusion
00437    void selectRange(Vector<T>& pixelRange,                
00438                     Bool& doInclude,
00439                     Bool& doExlude,
00440                     MomentsBase<T>& iMom) const;
00441 
00442 // The MomentCalculators compute a vector of all possible moments.
00443 // This function returns a vector which selects the desired moments from that
00444 // "all moment" vector.
00445    Vector<Int> selectMoments(MomentsBase<T>& iMom) const;
00446 
00447 // Fill the ouput moments array
00448    void setCalcMoments (MomentsBase<T>& iMom,
00449                         Vector<T>& calcMoments,
00450                         Vector<Bool>& calcMomentsMask,
00451                         Vector<Double>& pixelIn,
00452                         Vector<Double>& worldOut,
00453                         Bool doCoord,
00454                         Double integratedScaleFactor,
00455                         T dMedian,
00456                         T vMedian,
00457                         Int nPts,
00458                         typename NumericTraits<T>::PrecisionType s0,
00459                         typename NumericTraits<T>::PrecisionType s1,
00460                         typename NumericTraits<T>::PrecisionType s2,
00461                         typename NumericTraits<T>::PrecisionType s0Sq,
00462                         typename NumericTraits<T>::PrecisionType sumAbsDev,
00463                         T dMin,
00464                         T dMax,
00465                         Int iMin,
00466                         Int iMax) const;
00467 
00468 // Fill a string with the position of the cursor
00469    void setPosLabel(String& title,
00470                     const IPosition& pos) const;
00471 
00472 // Install CoordinateSystem and SpectralCoordinate
00473 // in protected data members
00474    void setCoordinateSystem (CoordinateSystem& cSys,
00475                              MomentsBase<T>& iMom);
00476 
00477 // Set up separable moment axis coordinate vector and
00478 // conversion vectors if not separable
00479    void setUpCoords (MomentsBase<T>& iMom,
00480                      Vector<Double>& pixelIn,
00481                      Vector<Double>& worldOut,
00482                      Vector<Double>& sepWorldCoord,
00483                      LogIO& os,
00484                      Double& integratedScaleFactor,
00485                      const CoordinateSystem& cSys,
00486                      Bool doCoordProfile, Bool doCoordRandom) const;
00487 
00488 // Plot the Gaussian fit
00489    void showGaussFit(const T peak,
00490                      const T pos,    
00491                      const T width,
00492                      const T level,
00493                      const Vector<T>& x,
00494                      const Vector<T>& y,
00495                      const Vector<Bool>& mask,
00496                      PGPlotter& plotter) const;
00497 
00498 // Find some statistics from teh masked vector.
00499 // Returns False if no unmasked points.
00500    Bool stats(T& dMin, T& dMax, 
00501               uInt& minPos, uInt& maxPos,
00502               T& mean,
00503               const Vector<T>& profile,
00504               const Vector<Bool>& mask) const;
00505                  
00506 // Return standard deviation of image from ImageMoments or MSMoments object
00507    T& stdDeviation(MomentsBase<T>& iMom) const;
00508  
00509 // Return the auto y min and max from the ImageMoments or MSMoments object
00510    void yAutoMinMax(T& yMin, 
00511                     T& yMax, 
00512                     MomentsBase<T>& iMom) const;
00513 
00514 protected:
00515 // Check if #pixels is indeed 1.
00516    virtual void init (uInt nOutPixelsPerCollapse);
00517 };
00518 
00519                                                  
00520 
00521 // <summary> Computes simple clipped, and masked moments</summary>
00522 // <use visibility=export>
00523 // 
00524 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00525 // </reviewed>
00526 // 
00527 // <prerequisite>
00528 //   <li> <linkto class="MomentsBase">MomentsBase</linkto>
00529 //   <li> <linkto class="ImageMoments">ImageMoments</linkto>
00530 //   <li> <linkto class="MSMoments">MSMoments</linkto>
00531 //   <li> <linkto class="LatticeApply">LatticeApply</linkto>
00532 //   <li> <linkto class="MomentCalcBase">MomentCalcBase</linkto>
00533 //   <li> <linkto class="LineCollapser">LineCollapser</linkto>
00534 // </prerequisite>
00535 //
00536 // <synopsis>
00537 //  This concrete class is derived from the abstract base class MomentCalcBase
00538 //  which provides an interface layer to the ImageMoments or MSMoments driver class.
00539 //  ImageMoments or MSMoments creates a MomentClip object and passes it to the LatticeApply
00540 //  function, lineMultiApply. This function iterates through a given lattice, 
00541 //  and invokes the <src>multiProcess</src> member function of MomentClip on each vector 
00542 //  of pixels that it extracts from the input lattice.  The <src>multiProcess</src>
00543 //  function returns a vector of moments which are inserted into the output 
00544 //  lattices also supplied to the LatticeApply function.
00545 //
00546 //  MomentClip computes moments directly from a vector of pixel intensities 
00547 //  extracted from the primary lattice.  An optional pixel intensity inclusion 
00548 //  or exclusion range can be applied.   It can also compute a mask based on the 
00549 //  inclusion or exclusion ranges applied to an ancilliary lattice (the ancilliary 
00550 //  vector corresponding to the primary vector is extracted).  This mask is then 
00551 //  applied to the primary vector for moment computation (ImageMoments or MSMoments offers
00552 //  a smoothed version of the primary lattice as the ancilliary lattice)
00553 //
00554 //  The constructor takes an MomentsBase object that is actually an ImageMoments or 
00555 //  an MSMoments object; the one that is constructing
00556 //  the MomentClip object of course.   There is much control information embodied  
00557 //  in the state of the ImageMoments or MSMoments object.  This information is extracted by the 
00558 //  MomentCalcBase class and passed on to MomentClip for consumption.
00559 //
00560 //  Note that the ancilliary lattice is only accessed if the ImageMoments or MSMoments 
00561 //  object indicates that a pixel inclusion or exclusion range has been 
00562 //  given as well as the pointer to the lattice having a non-zero value.
00563 //
00564 //  See the <linkto class="MomentsBase">MomentsBase</linkto>, 
00565 //  <linkto class="ImageMoments">ImageMoments</linkto>, and 
00566 //  <linkto class="MSMoments">MSMoments</linkto>
00567 //  for discussion about the moments that are available for computation.
00568 //
00569 // </synopsis>
00570 //
00571 // <example>
00572 // This example comes from ImageMoments.   outPt is a pointer block holding
00573 // pointers to the output lattices.  The ancilliary masking lattice is
00574 // just a smoothed version of the input lattice.
00575 //
00576 // <srcBlock>
00577 // 
00580 //
00581 //   MomentCalcBase<T>* pMomentCalculator = 0;
00582 //   if (clipMethod || smoothClipMethod) {
00583 //      pMomentCalculator = new MomentClip<T>(pSmoothedImage, *this, os_p, outPt.nelements());
00584 //   } else if (windowMethod) {
00585 //      pMomentCalculator = new MomentWindow<T>(pSmoothedImage, *this, os_p, outPt.nelements());
00586 //   } else if (fitMethod) {
00587 //      pMomentCalculator = new MomentFit<T>(*this, os_p, outPt.nelements());
00588 //   }
00589 //
00591 //
00592 //   LatticeApply<T>::lineMultiApply(outPt, *pInImage_p, *pMomentCalculator,   
00593 //                                   momentAxis_p, pProgressMeter);
00594 //   delete pMomentCalculator;
00595 //
00596 // </srcBlock>
00597 // </example>
00598 //
00599 // <note role=tip>
00600 // Note that there are is assignment operator or copy constructor.
00601 // Do not use the ones the system would generate either.
00602 // </note>
00603 //
00604 // <todo asof="yyyy/mm/dd">
00605 // </todo>
00606 
00607 
00608 
00609 template <class T> class MomentClip : public MomentCalcBase<T>
00610 {
00611 public:
00612 
00613 // Constructor.  The pointer is to an ancilliary  lattice used as a mask.
00614 // If no masking lattice is desired, the pointer value must be zero.  We also 
00615 // need the ImageMoments or MSMoments object which is calling us, its
00616 // logger, and the number of output lattices it has created.
00617    MomentClip(Lattice<T>* pAncilliaryLattice,
00618               MomentsBase<T>& iMom,
00619               LogIO& os,
00620               const uInt nLatticeOut);
00621 
00622 // Destructor (does nothing).
00623   ~MomentClip();
00624 
00625 // This function is not implemented and throws an exception.
00626    virtual void process(T& out,
00627                         Bool& outMask,
00628                         const Vector<T>& in,
00629                         const Vector<Bool>& inMask,
00630                         const IPosition& pos);
00631 
00632 // This function returns a vector of numbers from each input vector.
00633 // the output vector contains the moments known to the ImageMoments
00634 // or MSMoments object passed into the constructor.
00635    virtual void multiProcess(Vector<T>& out,
00636                              Vector<Bool>& outMask,
00637                              const Vector<T>& in,
00638                              const Vector<Bool>& inMask,
00639                              const IPosition& pos);
00640 
00641 // Can handle null mask
00642    virtual Bool canHandleNullMask() const {return True;};
00643 
00644 private:
00645 
00646    Lattice<T>* pAncilliaryLattice_p; 
00647    MomentsBase<T>& iMom_p;
00648    LogIO os_p;
00649 
00650    const Vector<T>* pProfileSelect_p;
00651    Vector<T> ancilliarySliceRef_p;
00652    Vector<T> selectedData_p;
00653    Vector<Int> selectedDataIndex_p;
00654    Bool doInclude_p, doExclude_p;
00655    Vector<T> range_p;
00656    IPosition sliceShape_p;
00657 
00658 
00659   //# Make members of parent class known.
00660 protected:
00661   using MomentCalcBase<T>::constructorCheck;
00662   using MomentCalcBase<T>::setPosLabel;
00663   using MomentCalcBase<T>::selectMoments_p;
00664   using MomentCalcBase<T>::calcMoments_p;
00665   using MomentCalcBase<T>::calcMomentsMask_p;
00666   using MomentCalcBase<T>::fixedYLimits_p;
00667   using MomentCalcBase<T>::yMinAuto_p;
00668   using MomentCalcBase<T>::yMaxAuto_p;
00669   using MomentCalcBase<T>::doMedianI_p;
00670   using MomentCalcBase<T>::doMedianV_p;
00671   using MomentCalcBase<T>::doAbsDev_p;
00672   using MomentCalcBase<T>::plotter_p;
00673   using MomentCalcBase<T>::cSys_p;
00674   using MomentCalcBase<T>::doCoordProfile_p;
00675   using MomentCalcBase<T>::doCoordRandom_p;
00676   using MomentCalcBase<T>::pixelIn_p;
00677   using MomentCalcBase<T>::worldOut_p;
00678   using MomentCalcBase<T>::sepWorldCoord_p;
00679   using MomentCalcBase<T>::integratedScaleFactor_p;
00680   using MomentCalcBase<T>::momAxisType_p;
00681   using MomentCalcBase<T>::nFailed_p;
00682   using MomentCalcBase<T>::abcissa_p;
00683 };
00684 
00685 
00686 
00687 // <summary> Computes moments from a windowed profile </summary>
00688 // <use visibility=export>
00689 // 
00690 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00691 // </reviewed>
00692 // 
00693 // <prerequisite>
00694 //   <li> <linkto class="MomentsBase">MomentsBase</linkto>
00695 //   <li> <linkto class="ImageMoments">ImageMoments</linkto>
00696 //   <li> <linkto class="MSMoments">MSMoments</linkto>
00697 //   <li> <linkto class="LatticeApply">LatticeApply</linkto>
00698 //   <li> <linkto class="MomentCalcBase">MomentCalcBase</linkto>
00699 //   <li> <linkto class="LineCollapser">LineCollapser</linkto>
00700 // </prerequisite>
00701 //
00702 // <synopsis>
00703 //  This concrete class is derived from the abstract base class MomentCalcBase
00704 //  which provides an interface layer to the ImageMoments or MSMoments driver class.
00705 //  ImageMoments or MSMoments creates a MomentWindow object and passes it to the LatticeApply
00706 //  function lineMultiApply.  This function iterates through a given lattice, 
00707 //  and invokes the <src>multiProcess</src> member function of MomentWindow on each profile
00708 //  of pixels that it extracts from the input lattice.  The <src>multiProcess</src> function 
00709 //  returns a vector of moments which are inserted into the output lattices also
00710 //  supplied to the LatticeApply function.
00711 //
00712 //  MomentWindow computes moments from a subset of the pixels selected from  the
00713 //  input profile.  This subset is a simple index range, or window.  The window is
00714 //  selected, for each profile, that is thought to surround the spectral feature 
00715 //  of interest.  This window can be found from the primary lattice, or from an 
00716 //  ancilliary lattice (ImageMoments or MSMoments offers a smoothed version of the primary 
00717 //  lattice as the ancilliary lattice).  The moments are always computed from 
00718 //  primary lattice data.   
00719 //
00720 //  For each profile, the window can be found either interactively or automatically.
00721 //  There are two interactive methods.  Either you just mark the window with the
00722 //  cursor, or you interactively fit a Gaussian to the profile and the +/- 3-sigma
00723 //  window is returned.  There are two automatic methods.  Either Bosma's converging
00724 //  mean algorithm is used, or an automatically  fit Gaussian +/- 3-sigma window
00725 //  is returned.
00726 // 
00727 //  The constructor takes an MomentsBase object that is actually an ImageMoments or 
00728 //  an MSMoments object; the one that is constructing
00729 //  the MomentWindow object of course.   There is much control information embodied  
00730 //  in the state  of the ImageMoments or MSMoments object.  This information is extracted by the
00731 //  MomentCalcBase class and passed on to MomentWindow for consumption.
00732 //
00733 //  Note that the ancilliary lattice is only accessed if the pointer to it
00734 //  is non zero.
00735 //  
00736 //  See the <linkto class="MomentsBase">MomentsBase</linkto>, 
00737 //  <linkto class="ImageMoments">ImageMoments</linkto>, and 
00738 //  <linkto class="MSMoments">MSMoments</linkto>
00739 //  for discussion about the moments that are available for computation.
00740 //  
00741 // </synopsis>
00742 //
00743 // <example>
00744 // This example comes from ImageMoments.   outPt is a pointer block holding
00745 // pointers to the output lattices.  The ancilliary masking lattice is
00746 // just a smoothed version of the input lattice.  os_P is a LogIO object.
00747 //   
00748 // <srcBlock>
00749 // 
00752 //  
00753 //   MomentCalcBase<T>* pMomentCalculator = 0;
00754 //   if (clipMethod || smoothClipMethod) {
00755 //      pMomentCalculator = new MomentClip<T>(pSmoothedImage, *this, os_p, outPt.nelements());
00756 //   } else if (windowMethod) {
00757 //      pMomentCalculator = new MomentWindow<T>(pSmoothedImage, *this, os_p, outPt.nelements());
00758 //   } else if (fitMethod) {
00759 //      pMomentCalculator = new MomentFit<T>(*this, os_p, outPt.nelements());
00760 //   }
00761 //  
00763 //  
00764 //   LatticeApply<T>::lineMultiApply(outPt, *pInImage_p, *pMomentCalculator,   
00765 //                                   momentAxis_p, pProgressMeter);
00766 //   delete pMomentCalculator;
00767 //  
00768 // </srcBlock>
00769 // </example>
00770 //
00771 // <motivation>
00772 // </motivation>
00773 //
00774 // <note role=tip>
00775 // Note that there are is assignment operator or copy constructor.
00776 // Do not use the ones the system would generate either.
00777 // </note>
00778 //
00779 // <todo asof="yyyy/mm/dd">
00780 // </todo>
00781 
00782 
00783 template <class T> class MomentWindow : public MomentCalcBase<T>
00784 {
00785 public:
00786 
00787 // Constructor.  The pointer is to a lattice containing the masking
00788 // lattice (created by ImageMoments or MSMoments).   We also need the 
00789 // ImageMoments or MSMoments object which is calling us, its logger,
00790 // and the number of output lattices it has created.
00791    MomentWindow(Lattice<T>* pAncilliaryLattice,
00792                 MomentsBase<T>& iMom,
00793                 LogIO& os,
00794                 const uInt nLatticeOut);
00795 
00796 // Destructor (does nothing).
00797   ~MomentWindow();
00798 
00799 // This function is not implemented and throws an exception.
00800    virtual void process(T& out,
00801                         Bool& outMask,
00802                         const Vector<T>& in,
00803                         const Vector<Bool>& inMask,
00804                         const IPosition& pos);
00805 
00806 // This function returns a vector of numbers from each input vector.
00807 // the output vector contains the moments known to the ImageMoments
00808 // or MSMoments object passed into the constructor.
00809    virtual void multiProcess(Vector<T>& out,
00810                              Vector<Bool>& outMask,
00811                              const Vector<T>& in,
00812                              const Vector<Bool>& inMask,
00813                              const IPosition& pos);
00814 
00815                              
00816 private:
00817 
00818    Lattice<T>* pAncilliaryLattice_p; 
00819    MomentsBase<T>& iMom_p;
00820    LogIO os_p;
00821 
00822    const Vector<T>* pProfileSelect_p;
00823    Vector<T> ancilliarySliceRef_p;
00824    Vector<T> selectedData_p;
00825    T stdDeviation_p, peakSNR_p;
00826    Bool doAuto_p, doFit_p;
00827    IPosition sliceShape_p;
00828 
00829 
00830 // Draw two vertical lines marking a spectral window
00831    void drawWindow(const Vector<Int>& window,
00832                    PGPlotter& plotter) const;
00833 
00834 
00835 // Automatically determine the spectral window
00836    Bool getAutoWindow(uInt& nFailed,
00837                       Vector<Int>& window,
00838                       const Vector<T>& x,
00839                       const Vector<T>& y,
00840                       const Vector<Bool>& mask,
00841                       const T peakSNR,
00842                       const T stdDeviation,
00843                       const Bool doFit,
00844                       PGPlotter& plotter,
00845                       const Bool fixedYLimits,                 
00846                       const T yMinAuto,                 
00847                       const T yMaxAuto,                 
00848                       const String xLabel,
00849                       const String yLabel,
00850                       const String title) const;
00851 
00852 // Automatically determine the spectral window via Bosma's algorithm
00853    Bool getBosmaWindow (Vector<Int>& window,
00854                         const Vector<T>& x,
00855                         const Vector<T>& y,
00856                         const Vector<Bool>& mask,
00857                         const T peakSNR,
00858                         const T stdDeviation,
00859                         PGPlotter& plotter,
00860                         const Bool fixedYLimits,
00861                         const T yMinAuto,
00862                         const T yMaxAuto,
00863                         const String xLabel,
00864                         const String yLabel,
00865                         const String title) const;
00866 
00867 // Interactively specify the spectral window with the cursor
00868    Bool getInterDirectWindow(Bool& allSubsequent,
00869                              LogIO& os,
00870                              Vector<Int>& window,
00871                              const Vector<T>& x,
00872                              const Vector<T>& y,
00873                              const Vector<Bool>& mask,
00874                              const Bool fixedYLimits,   
00875                              const T yMinAuto,   
00876                              const T yMaxAuto,
00877                              const String xLabel,
00878                              const String yLabel,
00879                              const String title,
00880                              PGPlotter& plotter) const;
00881 
00882 // Interactively define the spectral window
00883 // Returns false if can't define window.
00884    Bool getInterWindow (uInt& nFailed,
00885                         Bool& allSubsequent,
00886                         LogIO& os,
00887                         Vector<Int>& window,
00888                         const Bool doFit,
00889                         const Vector<T>& x,
00890                         const Vector<T>& y,
00891                         const Vector<Bool>& mask,
00892                         const Bool fixedYLimits,
00893                         const T yMinAuto,
00894                         const T yMaxAuto,
00895                         const String xLabel,
00896                         const String yLabel,
00897                         const String title,
00898                         PGPlotter& plotter) const;
00899 
00900 // Take the fitted Gaussian parameters and set an N-sigma window.
00901 // If the window is too small return a Fail condition.
00902    Bool setNSigmaWindow(Vector<Int>& window,  
00903                         const T pos,
00904                         const T width,
00905                         const Int nPts,
00906                         const Int N) const;
00907 
00908 
00909   //# Make members of parent class known.
00910 protected:
00911   using MomentCalcBase<T>::constructorCheck;
00912   using MomentCalcBase<T>::setPosLabel;
00913   using MomentCalcBase<T>::convertF;
00914   using MomentCalcBase<T>::selectMoments_p;
00915   using MomentCalcBase<T>::calcMoments_p;
00916   using MomentCalcBase<T>::calcMomentsMask_p;
00917   using MomentCalcBase<T>::fixedYLimits_p;
00918   using MomentCalcBase<T>::yMinAuto_p;
00919   using MomentCalcBase<T>::yMaxAuto_p;
00920   using MomentCalcBase<T>::doMedianI_p;
00921   using MomentCalcBase<T>::doMedianV_p;
00922   using MomentCalcBase<T>::doAbsDev_p;
00923   using MomentCalcBase<T>::plotter_p;
00924   using MomentCalcBase<T>::cSys_p;
00925   using MomentCalcBase<T>::doCoordProfile_p;
00926   using MomentCalcBase<T>::doCoordRandom_p;
00927   using MomentCalcBase<T>::pixelIn_p;
00928   using MomentCalcBase<T>::worldOut_p;
00929   using MomentCalcBase<T>::sepWorldCoord_p;
00930   using MomentCalcBase<T>::integratedScaleFactor_p;
00931   using MomentCalcBase<T>::momAxisType_p;
00932   using MomentCalcBase<T>::nFailed_p;
00933   using MomentCalcBase<T>::abcissa_p;
00934 };
00935 
00936 
00937 
00938 // <summary> Compute moments from a Gaussian fitted to a profile</summary>
00939 // <use visibility=export>
00940 // 
00941 // <reviewed reviewer="" date="yyyy/mm/dd" tests="" demos="">
00942 // </reviewed>
00943 // 
00944 // <prerequisite>
00945 //   <li> <linkto class="MomentsBase">MomentsBase</linkto>
00946 //   <li> <linkto class="ImageMoments">ImageMoments</linkto>
00947 //   <li> <linkto class="MSMoments">MSMoments</linkto>
00948 //   <li> <linkto class="LatticeApply">LatticeApply</linkto>
00949 //   <li> <linkto class="MomentCalcBase">MomentCalcBase</linkto>
00950 //   <li> <linkto class="LineCollapser">LineCollapser</linkto>
00951 // </prerequisite>
00952 //
00953 // <synopsis>
00954 //  This concrete class is derived from the abstract base class MomentCalcBase
00955 //  which provides an interface layer to the ImageMoments or MSMoments driver class.  
00956 //  ImageMoments or MSMoments creates a MomentFit object and passes it to the LatticeApply
00957 //  function, lineMultiApply. This function iterates through a given lattice,
00958 //  and invokes the <src>multiProcess</src> member function of MomentFit on each vector
00959 //  of pixels that it extracts from the input lattice.  The <src>multiProcess</src>
00960 //  function returns a vector of moments which are inserted into the output
00961 //  lattices also supplied to the LatticeApply function.
00962 // 
00963 //  MomentFit computes moments by fitting a Gaussian to each profile.  The
00964 //  moments are then computed from that fit.   The fitting can be done either
00965 //  interactively or automatically.
00966 // 
00967 //  The constructor takes MomentsBase object that is actually an ImageMoments or 
00968 //  an MSMoments object; the one that is constructing
00969 //  the MomentFit object of course.   There is much control information embodied
00970 //  in the state of the ImageMoments object.  This information is extracted by the
00971 //  MomentCalcBase class and passed on to MomentFit for consumption.
00972 //   
00973 //  See the <linkto class="MomentsBase">MomentsBase</linkto>, 
00974 //  <linkto class="ImageMoments">ImageMoments</linkto>, and 
00975 //  <linkto class="MSMoments">MSMoments</linkto>
00976 //  for discussion about the moments that are available for computation.
00977 //  
00978 // </synopsis>
00979 //
00980 // <example>
00981 // This example comes from ImageMoments.   outPt is a pointer block holding
00982 // pointers to the output lattices.   os_P is a LogIO object.
00983 //                                     
00984 // <srcBlock>
00985 // 
00988 //
00989 //   MomentCalcBase<T>* pMomentCalculator = 0;
00990 //   if (clipMethod || smoothClipMethod) {
00991 //      pMomentCalculator = new MomentClip<T>(pSmoothedImage, *this, os_p, outPt.nelements());
00992 //   } else if (windowMethod) {
00993 //      pMomentCalculator = new MomentWindow<T>(pSmoothedImage, *this, os_p, outPt.nelements());
00994 //   } else if (fitMethod) {
00995 //      pMomentCalculator = new MomentFit<T>(*this, os_p, outPt.nelements());
00996 //   }
00997 //
00999 //
01000 //   LatticeApply<T>::lineMultiApply(outPt, *pInImage_p, *pMomentCalculator,   
01001 //                                   momentAxis_p, pProgressMeter);
01002 //   delete pMomentCalculator;
01003 // </srcBlock>
01004 // </example>
01005 //
01006 // <motivation>
01007 // </motivation>
01008 //
01009 // <note role=tip>
01010 // Note that there are is assignment operator or copy constructor.
01011 // Do not use the ones the system would generate either.
01012 // </note>
01013 //
01014 // <todo asof="yyyy/mm/dd">
01015 // </todo>
01016 
01017 
01018 template <class T> class MomentFit : public MomentCalcBase<T>
01019 {
01020 public:
01021 
01022 // Constructor.  We need the ImageMoments or MSMoments object which is calling us, 
01023 // its logger, and the number of output lattices it has created.
01024    MomentFit(MomentsBase<T>& iMom,
01025              LogIO& os,
01026              const uInt nLatticeOut);
01027 
01028 // Destructor (does nothing).
01029   ~MomentFit();
01030 
01031 // This function is not implemented and throws an exception.
01032    virtual void process(T& out,
01033                         Bool& outMask,
01034                         const Vector<T>& in,
01035                         const Vector<Bool>& inMask,
01036                         const IPosition& pos);
01037 
01038 // This function returns a vector of numbers from each input vector.
01039 // the output vector contains the moments known to the ImageMoments
01040 // or MSMoments object passed into the constructor.
01041    virtual void multiProcess(Vector<T>& out,
01042                              Vector<Bool>& outMask,
01043                              const Vector<T>& in,
01044                              const Vector<Bool>& inMask,
01045                              const IPosition& pos);
01046 
01047 private:
01048    MomentsBase<T>& iMom_p;
01049    LogIO os_p;
01050    T stdDeviation_p, peakSNR_p;
01051    Bool doAuto_p, doFit_p;
01052    Gaussian1D<T> gauss_p;
01053 
01054 
01055   //# Make members of parent class known.
01056 protected:
01057   using MomentCalcBase<T>::constructorCheck;
01058   using MomentCalcBase<T>::setPosLabel;
01059   using MomentCalcBase<T>::convertF;
01060   using MomentCalcBase<T>::selectMoments_p;
01061   using MomentCalcBase<T>::calcMoments_p;
01062   using MomentCalcBase<T>::calcMomentsMask_p;
01063   using MomentCalcBase<T>::fixedYLimits_p;
01064   using MomentCalcBase<T>::yMinAuto_p;
01065   using MomentCalcBase<T>::yMaxAuto_p;
01066   using MomentCalcBase<T>::doMedianI_p;
01067   using MomentCalcBase<T>::doMedianV_p;
01068   using MomentCalcBase<T>::doAbsDev_p;
01069   using MomentCalcBase<T>::plotter_p;
01070   using MomentCalcBase<T>::cSys_p;
01071   using MomentCalcBase<T>::doCoordProfile_p;
01072   using MomentCalcBase<T>::doCoordRandom_p;
01073   using MomentCalcBase<T>::pixelIn_p;
01074   using MomentCalcBase<T>::worldOut_p;
01075   using MomentCalcBase<T>::sepWorldCoord_p;
01076   using MomentCalcBase<T>::integratedScaleFactor_p;
01077   using MomentCalcBase<T>::momAxisType_p;
01078   using MomentCalcBase<T>::nFailed_p;
01079   using MomentCalcBase<T>::abcissa_p;
01080 };
01081 
01082 
01083 
01084 template<class T>
01085 inline uInt MomentCalcBase<T>::nFailedFits() const
01086 {
01087   return nFailed_p;
01088 }
01089 
01090 // Accumulate statistical sums from a vector
01091 template<class T>
01092 inline void MomentCalcBase<T>::accumSums
01093                  (typename NumericTraits<T>::PrecisionType& s0,
01094                   typename NumericTraits<T>::PrecisionType& s0Sq,
01095                   typename NumericTraits<T>::PrecisionType& s1,
01096                   typename NumericTraits<T>::PrecisionType& s2,
01097                   Int& iMin,
01098                   Int& iMax,
01099                   T& dMin,
01100                   T& dMax,   
01101                   const Int i,  
01102                   const T datum,
01103                   const Double coord) const
01104 //
01105 // Accumulate statistical sums from this datum
01106 //
01107 // Input:
01108 //  i              Index
01109 //  datum          Pixel value
01110 //  coord          Coordinate value on moment axis
01111 // Input/output:  
01112 //  iMin,max       index of dMin and dMax
01113 //  dMin,dMax      minimum and maximum value
01114 // Output:
01115 //  s0             sum (I)
01116 //  s0Sq           sum (I*I)
01117 //  s1             sum (I*v)
01118 //  s2             sum (I*v*v)
01119 {
01120    typename NumericTraits<T>::PrecisionType dDatum = datum;
01121    s0 += dDatum;
01122    s0Sq += dDatum*dDatum;
01123    s1 += dDatum*coord;
01124    s2 += dDatum*coord*coord;
01125    if (datum < dMin) {
01126      iMin = i;
01127      dMin = datum;
01128    }
01129    if (datum > dMax) {
01130      iMax = i;
01131      dMax = datum;
01132    }
01133 }
01134 
01135 template<class T>
01136 inline Float MomentCalcBase<T>::convertT(const T value)
01137 {
01138   return MomentsBase<T>::convertT(value);
01139 }
01140 
01141 template<class T>
01142 inline T MomentCalcBase<T>::convertF(const Float value)
01143 {
01144   return MomentsBase<T>::convertF(value);
01145 }
01146 
01147 // Compute the world coordinate for the given moment axis pixel   
01148 template<class T>
01149 inline Double MomentCalcBase<T>::getMomentCoord(MomentsBase<T>& iMom,
01150                                                 Vector<Double>& pixelIn,
01151                                                 Vector<Double>& worldOut,
01152                                                 const Double momentPixel) const
01153 // 
01154 // Find the value of the world coordinate on the moment axis
01155 // for the given moment axis pixel value. 
01156 //
01157 // Input
01158 //   momentPixel   is the index in the profile extracted from the data
01159 // Input/output
01160 //   pixelIn       Pixels to convert.  Must all be filled in except for
01161 //                 pixelIn(momentPixel).
01162 //   worldOut      Vector to hold result
01163 //
01164 // Should really return a Fallible as I don't check and see
01165 // if the coordinate transformation fails or not
01166 //
01167 {
01168    pixelIn(iMom.momentAxis_p) = momentPixel;
01169 // 
01170 // Should really check the result is True, but for speed ...
01171 //
01172    cSys_p.toWorld(worldOut, pixelIn);
01173    return worldOut(iMom.worldMomentAxis_p);
01174 }
01175 
01176 } //# NAMESPACE CASA - END
01177 
01178 #ifndef CASACORE_NO_AUTO_TEMPLATES
01179 #include <imageanalysis/ImageAnalysis/MomentCalculator.tcc>
01180 #endif //# CASACORE_NO_AUTO_TEMPLATES
01181 #endif