ImageProfileFitter.h

Go to the documentation of this file.
00001 //# tSubImage.cc: Test program for class SubImage
00002 //# Copyright (C) 1998,1999,2000,2001,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This program is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU General Public License as published by the Free
00007 //# Software Foundation; either version 2 of the License, or (at your option)
00008 //# any later version.
00009 //#
00010 //# This program 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 General Public License for
00013 //# more details.
00014 //#
00015 //# You should have received a copy of the GNU General Public License along
00016 //# with this program; if not, write to the Free Software Foundation, Inc.,
00017 //# 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: tSubImage.cc 20567 2009-04-09 23:12:39Z gervandiepen $
00027 
00028 #ifndef IMAGES_IMAGEPROFILEFITTER_H
00029 #define IMAGES_IMAGEPROFILEFITTER_H
00030 
00031 #include <imageanalysis/ImageAnalysis/ImageTask.h>
00032 
00033 #include <components/SpectralComponents/GaussianMultipletSpectralElement.h>
00034 #include <imageanalysis/ImageAnalysis/ImageFit1D.h>
00035 #include <images/Images/TempImage.h>
00036 
00037 #include <casa/namespace.h>
00038 
00039 namespace casa {
00040 
00041 class ProfileFitResults;
00042 
00043 class ImageProfileFitter : public ImageTask<Float> {
00044         // <summary>
00045         // Top level interface for one-dimensional profile fits.
00046         // </summary>
00047 
00048         // <reviewed reviewer="" date="" tests="" demos="">
00049         // </reviewed>
00050 
00051         // <prerequisite>
00052         // </prerequisite>
00053 
00054         // <etymology>
00055         // Fits one-dimensional profiles.
00056         // </etymology>
00057 
00058         // <synopsis>
00059         // Top level interface for one-dimensional profile fits.
00060         // </synopsis>
00061 
00062         // <example>
00063         // <srcblock>
00064         // ImageProfileFitter fitter(...)
00065         // fitter.fit()
00066         // </srcblock>
00067         // </example>
00068 
00069 public:
00070         // constructor appropriate for API calls.
00071         // Parameters:
00072         // <src>image</src> - the input image in which to fit the models
00073         // <src>box</src> - A 2-D rectangular box in direction space in which to use pixels for the fitting, eg box=100,120,200,230
00074         // In cases where both box and region are specified, box, not region, is used.
00075         // <src>region</src> - Named region to use for fitting. "" => Don't use a named region
00076         // <src>regPtr</src> - Pointer to a region record. 0 => don't use a region record.
00077         // <src>chans</src> - Zero-based channel range on which to do the fit.
00078         // <src>stokes</src> - Stokes plane on which to do the fit. Only a single Stokes parameter can be
00079         // specified.
00080         // Only a maximum of one of region, regionPtr, or box/stokes/chans should be specified.
00081         // <src>mask</src> - Mask (as LEL) to use as a way to specify which pixels to use </src>
00082         // <src>axis</src> - axis along which to do the fits. If <0, use spectral axis, and if no spectral
00083         // axis, use zeroth axis.
00084         // <src>ngauss</src> number of single gaussians to fit.
00085         // <src>estimatesFilename</src> file containing initial estimates for single gaussians.
00086         // <src>spectralList</src> spectral list containing initial estimates of single gaussians. Do
00087         // not put a polynomial in here; set that with setPolyOrder().
00088 
00089         // Fit only Gaussian singlets and an optional polynomial. In this case, the
00090         // code guestimates initial estimates for the specified number of Gaussian
00091         // singlets. If you only wish to fit a polynomial, you must use this
00092         // constructor and you must set <src>ngauss</src> to zero. After construction,
00093         // you must call setPolyOrder().
00094         ImageProfileFitter(
00095                 const SPCIIF image, const String& region,
00096                 const Record *const &regionPtr, const String& box,
00097                 const String& chans, const String& stokes, const String& mask,
00098                 const Int axis, const uInt ngauss, Bool overwrite=False
00099         );
00100 
00101         // Fit only Gaussian singlets and an optional polynomial. In this case, the number
00102         // of Gaussian singlets is deduced from the specified estimates file.
00103         ImageProfileFitter(
00104                 const SPCIIF image, const String& region,
00105                 const Record *const &regionPtr, const String& box,
00106                 const String& chans, const String& stokes, const String& mask,
00107                 const Int axis, const String& estimatesFilename,
00108                 Bool overwrite=False
00109         );
00110 
00111         // Fit any permitted combination of spectral components and an optional polynomial.
00112         // All components to be fit (except a possible polynomial) must be represented
00113         // with initial estimates in <src>spectralList</src>.
00114         ImageProfileFitter(
00115                 const SPCIIF image, const String& region,
00116                 const Record *const &regionPtr, const String& box,
00117                 const String& chans, const String& stokes, const String& mask,
00118                 const Int axis, const SpectralList& spectralList, Bool overwrite=False
00119         );
00120 
00121         // destructor
00122         ~ImageProfileFitter();
00123 
00124         // Do the fit. If doDetailedResults is False, an empty Record is returned.
00125         Record fit(Bool doDetailedResults=True);
00126 
00127         // get the fit results. If fit was run with doDetailedResults=False, an empty Record is returned
00128         Record getResults() const;
00129 
00130     inline String getClass() const { return _class; };
00131 
00132     // set the order of a polynomial to be simultaneously fit.
00133     void setPolyOrder(Int p);
00134 
00135     // set whether to do a pixel by pixel fit.
00136     inline void setDoMultiFit(const Bool m) { _multiFit = m; }
00137 
00138     // set if results should be written to the logger
00139     inline void setLogResults(const Bool logResults) { _logResults = logResults; }
00140 
00141     // set minimum number of good points required to attempt a fit
00142     inline void setMinGoodPoints(const uInt mgp) {
00143         ThrowIf(mgp == 0, "Number of good points has to be > 0");
00144         _minGoodPoints = mgp;
00145     }
00146 
00147     // <group>
00148     // Solution images. Only written if _multifit is True
00149     // model image name
00150     inline void setModel(const String& model) { _model = model; }
00151     // residual image name
00152     inline void setResidual(const String& residual) { _residual = residual; }
00153     // gaussian amplitude image name
00154     inline void setAmpName(const String& s) { _ampName = s; }
00155     // gaussian amplitude error image name
00156     inline void setAmpErrName(const String& s) { _ampErrName = s; }
00157     // gaussian center image name
00158     inline void setCenterName(const String& s) { _centerName = s; }
00159     // gaussian center error image name
00160     inline void setCenterErrName(const String& s) { _centerErrName = s; }
00161     // gaussian fwhm image name
00162     inline void setFWHMName(const String& s) { _fwhmName = s; }
00163     // gaussian fwhm error image name
00164     inline void setFWHMErrName(const String& s) { _fwhmErrName = s; }
00165     // gaussian integral image name
00166     inline void setIntegralName(const String& s) { _integralName = s; }
00167     // gaussian integral error image name
00168     inline void setIntegralErrName(const String& s) { _integralErrName = s; }
00169     // </group>
00170 
00171     // set the name of the power logarithmic polynomial image.
00172     inline void setPLPName(const String& s) { _plpName = s; }
00173 
00174     // set the name of the power logarithmic polynomial image.
00175     inline void setPLPErrName(const String& s) { _plpErrName = s; }
00176 
00177     // set the name of the logarithmic transformed polynomial image.
00178     inline void setLTPName(const String& s) { _ltpName = s; }
00179 
00180     // set the name of the logarithmic transformed polynomial image.
00181     inline void setLTPErrName(const String& s) { _ltpErrName = s; }
00182 
00183     // set the range over which PFC amplitude solutions are valid
00184     void setGoodAmpRange(const Double min, const Double max);
00185 
00186     // set the range over which PFC center solutions are valid
00187     void setGoodCenterRange(const Double min, const Double max);
00188 
00189     // set the range over which PFC FWHM solutions are valid
00190     void setGoodFWHMRange(const Double min, const Double max);
00191 
00192     // <group>
00193     // set standard deviation image
00194     void setSigma(const Array<Float>& sigma);
00195 
00196     void setSigma(const ImageInterface<Float> *const &sigma);
00197 
00198     inline void setOutputSigmaImage(const String& s) { _sigmaName = s; }
00199     // </group>
00200 
00201     const Array<SHARED_PTR<ProfileFitResults> >& getFitters() const;
00202 
00203     //Converts a pixel value into a world value either in velocity, wavelength, or
00204     //frequency units.  If the tabular index >= 0, it uses the tabular index for conversion
00205     //with the specified MFrequency type, otherwise, it uses the spectral axis for
00206     //conversion.
00207     Double getWorldValue(
00208         Double pixelVal, const IPosition& imPos, const String& units,
00209         Bool velocity, Bool wavelength, Int tabularIndex=-1,
00210         MFrequency::Types type=MFrequency::DEFAULT
00211     ) const;
00212 
00213     void setAbscissaDivisor(Double d);
00214 
00215     void setAbscissaDivisor(const Quantity& q);
00216 
00217     // for backward compatibility with ia.continuumsub. If no residual
00218     // image has been provided, a TempImage is created.
00219     void createResidualImage(Bool b) { _createResid = b; }
00220 
00221     SPIIF getResidual() const {
00222         return _residImage;
00223     }
00224 
00225     // set the planes along the fit axis that are considered good for performing
00226     // the fits. An empty vector implies that all planes are considered "good".
00227     void setGoodPlanes(const std::set<uInt>& planes) { _goodPlanes = planes; }
00228 
00229 protected:
00230 
00231     inline CasacRegionManager::StokesControl _getStokesControl() const {
00232                 return CasacRegionManager::USE_FIRST_STOKES;
00233         }
00234 
00235     inline vector<Coordinate::Type> _getNecessaryCoordinates() const {
00236         return vector<Coordinate::Type>(0);
00237     }
00238 
00239     Bool _hasLogfileSupport() const { return True; }
00240 
00241     inline Bool _supportsMultipleRegions() const {return True;}
00242 
00243 private:
00244         String _residual, _model, _xUnit,
00245                 _centerName, _centerErrName, _fwhmName,
00246                 _fwhmErrName, _ampName, _ampErrName,
00247                 _integralName, _integralErrName, _plpName, _plpErrName,
00248                 _ltpName, _ltpErrName, _sigmaName, _abscissaDivisorForDisplay;
00249         Bool  _multiFit, _logResults, _isSpectralIndex,
00250                 _createResid, _overwrite, _storeFits;
00251         Int _polyOrder, _fitAxis;
00252         uInt _nGaussSinglets, _nGaussMultiplets, _nLorentzSinglets,
00253                 _nPLPCoeffs, _nLTPCoeffs, _minGoodPoints, _nProfiles, _nAttempted,
00254                 _nSucceeded, _nConverged, _nValid;
00255         Array<SHARED_PTR<ProfileFitResults> > _fitters;
00256     // subimage contains the region of the original image
00257         // on which the fit is performed.
00258         SHARED_PTR<const SubImage<Float> > _subImage;
00259         Record _results;
00260         SpectralList _nonPolyEstimates;
00261         PtrHolder<std::pair<Double, Double> > _goodAmpRange, _goodCenterRange, _goodFWHMRange;
00262         Matrix<String> _worldCoords;
00263         SHARED_PTR<TempImage<Float> > _sigma;
00264         Double _abscissaDivisor;
00265         SPIIF _modelImage, _residImage;
00266         // planes along _fitAxis to use in fits, empty => use all planes
00267         // originally used to support continuum subtraction
00268         std::set<uInt> _goodPlanes;
00269 
00270         const static String _class;
00271 
00272         mutable Bool _haveWarnedAboutGuessingGaussians = False;
00273 
00274     std::vector<OutputDestinationChecker::OutputStruct> _getOutputStruct();
00275 
00276     void _checkNGaussAndPolyOrder() const;
00277 
00278     void _finishConstruction();
00279 
00280     // moved from ImageAnalysis
00281     void _fitallprofiles();
00282 
00283     // Fit all profiles in image.  The output images must be already
00284     // created; if the pointer is 0, that image won't be filled.
00285     // The mask from the input image is transferred to the output
00286     // images.    If the weights image is pointer is non-zero, the
00287     // values from it will be used to weight the data points in the
00288     // fit.  You can fit some combination of gaussians and a polynomial
00289     // (-1 means no polynomial).  Initial estimates are not required.
00290     // Fits are done in image space to provide astronomer friendly results,
00291     // but pixel space is better for the fitter when fitting polynomials.
00292     // Thus, atm, callers should be aware that fitting polynomials may
00293     // fail even when the data lie exactly on a polynomial curve.
00294     // This will probably be fixed in the future by doing the fits
00295     // in pixel space here and requiring the caller to deal with converting
00296     // to something astronomer friendly if it so desires.
00297 
00298     void _fitProfiles(const Bool showProgress);
00299 
00300     //Bool _inVelocitySpace() const;
00301 
00302     void _flagFitterIfNecessary(ImageFit1D<Float>& fitter) const;
00303 
00304     Bool _isPCFSolutionOK(const PCFSpectralElement *const &pcf) const;
00305 
00306     void _loopOverFits(
00307         SPCIIF fitData, Bool showProgress,
00308         SHARED_PTR<ProgressMeter> progressMeter, Bool checkMinPts,
00309         const Array<Bool>& fitMask, ImageFit1D<Float>::AbcissaType abcissaType,
00310         const IPosition& fitterShape, const IPosition& sliceShape,
00311         const std::set<uInt> goodPlanes
00312     );
00313 
00314     void _setAbscissaDivisorIfNecessary(const Vector<Double>& abscissaValues);
00315 
00316     Bool _setFitterElements(
00317         ImageFit1D<Float>& fitter, SpectralList& newEstimates,
00318         const PtrHolder<const PolynomialSpectralElement>& polyEl,
00319         const vector<IPosition>& goodPos,
00320         const IPosition& fitterShape, const IPosition& curPos,
00321         uInt nOrigComps
00322     ) const;
00323 
00324     void _updateModelAndResidual(
00325         Bool fitOK,     const ImageFit1D<Float>& fitter,
00326         const IPosition& sliceShape, const IPosition& curPos,
00327         Lattice<Bool>* const &pFitMask, Lattice<Bool>* const &pResidMask
00328     ) const;
00329 
00330     // only implemented for the simplest cases so far
00331     uInt _nUnknowns() const;
00332 
00333 };
00334 }
00335 
00336 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1