casa
$Rev:20696$
|
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