casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
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 ImageProfileFitter : public ImageTask {
00042         // <summary>
00043         // Top level interface for one-dimensional profile fits.
00044         // </summary>
00045 
00046         // <reviewed reviewer="" date="" tests="" demos="">
00047         // </reviewed>
00048 
00049         // <prerequisite>
00050         // </prerequisite>
00051 
00052         // <etymology>
00053         // Fits one-dimensional profiles.
00054         // </etymology>
00055 
00056         // <synopsis>
00057         // Top level interface for one-dimensional profile fits.
00058         // </synopsis>
00059 
00060         // <example>
00061         // <srcblock>
00062         // ImageProfileFitter fitter(...)
00063         // fitter.fit()
00064         // </srcblock>
00065         // </example>
00066 
00067 public:
00068         // constructor appropriate for API calls.
00069         // Parameters:
00070         // <src>image</src> - the input image in which to fit the models
00071         // <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
00072         // In cases where both box and region are specified, box, not region, is used.
00073         // <src>region</src> - Named region to use for fitting
00074         // <src>chans</src> - Zero-based channel range on which to do the fit.
00075         // <src>stokes</src> - Stokes plane on which to do the fit. Only a single Stokes parameter can be
00076         // specified.
00077         // <src>mask</src> - Mask (as LEL) to use as a way to specify which pixels to use </src>
00078         // <src>axis</src> - axis along which to do the fits. If <0, use spectral axis, and if no spectral
00079         // axis, use zeroth axis.
00080         // <src>ngauss</src> number of single gaussians to fit. Not used if <src>estimatesFile</src> or
00081         // <src>spectralList</src> is specified.
00082         // <src>estimatesFilename</src> file containing initial estimates for single gaussians.
00083         // <src>spectralList</src> spectral list containing initial estimates of single gaussians. Do
00084         // not put a polynomial in here; set that with setPolyOrder(). Only one of a non-empty <src>estimatesFilename</src>
00085         // or a non-empty <src>spectralList</src> can be specified.
00086 
00087         ImageProfileFitter(
00088                 const ImageInterface<Float> *const &image, const String& region,
00089                 const Record *const &regionPtr, const String& box,
00090                 const String& chans, const String& stokes, const String& mask,
00091                 const Int axis, const uInt ngauss, const String& estimatesFilename,
00092                 const SpectralList& spectralList
00093         );
00094 
00095         // destructor
00096         ~ImageProfileFitter();
00097 
00098         // Do the fit.
00099         Record fit();
00100 
00101         // get the fit results
00102         Record getResults() const;
00103 
00104     inline String getClass() const { return _class; };
00105 
00106         inline CasacRegionManager::StokesControl _getStokesControl() const {
00107                 return CasacRegionManager::USE_FIRST_STOKES;
00108         }
00109 
00110     inline vector<Coordinate::Type> _getNecessaryCoordinates() const {
00111         return vector<Coordinate::Type>(0);
00112     }
00113 
00114     // set the order of a polynomial to be simultaneously fit.
00115     inline void setPolyOrder(const Int p) { _polyOrder = p;}
00116 
00117     // set whether to do a pixel by pixel fit.
00118     inline void setDoMultiFit(const Bool m) { _multiFit = m; }
00119 
00120     // set if results should be written to the logger
00121     inline void setLogResults(const Bool logResults) { _logResults = logResults; }
00122 
00123     // set minimum number of good points required to attempt a fit
00124     inline void setMinGoodPoints(const uInt mgp) { _minGoodPoints = mgp; }
00125 
00126     // <group>
00127     // Solution images. Only written if _multifit is True
00128     // model image name
00129     inline void setModel(const String& model) { _model = model; }
00130     // residual image name
00131     inline void setResidual(const String& residual) { _residual = residual; }
00132     // gaussian amplitude image name
00133     inline void setAmpName(const String& s) { _ampName = s; }
00134     // gaussian amplitude error image name
00135     inline void setAmpErrName(const String& s) { _ampErrName = s; }
00136     // gaussian center image name
00137     inline void setCenterName(const String& s) { _centerName = s; }
00138     // gaussian center error image name
00139     inline void setCenterErrName(const String& s) { _centerErrName = s; }
00140     // gaussian fwhm image name
00141     inline void setFWHMName(const String& s) { _fwhmName = s; }
00142     // gaussian fwhm error image name
00143     inline void setFWHMErrName(const String& s) { _fwhmErrName = s; }
00144     // gaussian integral image name
00145     inline void setIntegralName(const String& s) { _integralName = s; }
00146     // gaussian integral error image name
00147     inline void setIntegralErrName(const String& s) { _integralErrName = s; }
00148     // </group>
00149 
00150     void setGoodAmpRange(const Double min, const Double max);
00151 
00152     void setGoodCenterRange(const Double min, const Double max);
00153 
00154     void setGoodFWHMRange(const Double min, const Double max);
00155 
00156     // <group>
00157     // set standard deviation image
00158     void setSigma(const Array<Float>& sigma);
00159 
00160     void setSigma(const ImageInterface<Float> *const &sigma);
00161 
00162     inline void setOutputSigmaImage(const String& s) { _sigmaName = s; }
00163     // </group>
00164 
00165 
00166     const static String _CONVERGED;
00167     const static String _SUCCEEDED;
00168     const static String _VALID;
00169 
00170     const Array<ImageFit1D<Float> >& getFitters() const;
00171     // Returns the center, in pixels of the indexth fit.
00172     const Vector<Double> getPixelCenter( uint index ) const;
00173     //Converts a pixel value into a world value either in velocity, wavelength, or
00174     //frequency units.
00175     Double getWorldValue( double pixelVal, const IPosition& imPos, const String& units,
00176         bool velocity, bool wavelength) const;
00177 
00178 private:
00179 
00180         String _residual, _model, _regionString, _xUnit,
00181                 _centerName, _centerErrName, _fwhmName,
00182                 _fwhmErrName, _ampName, _ampErrName,
00183                 _integralName, _integralErrName, _sigmaName;
00184         Bool _logfileAppend, _fitConverged, _fitDone, _multiFit,
00185                 _deleteImageOnDestruct, _logResults;
00186         Int _polyOrder, _fitAxis;
00187         uInt _nGaussSinglets, _nGaussMultiplets, _nLorentzSinglets,
00188                 _minGoodPoints;
00189         Array<ImageFit1D<Float> > _fitters;
00190     // subimage contains the region of the original image
00191         // on which the fit is performed.
00192         SubImage<Float> _subImage;
00193         Record _results;
00194         SpectralList _nonPolyEstimates;
00195         Vector<Double> _goodAmpRange, _goodCenterRange, _goodFWHMRange;
00196 
00197         std::auto_ptr<TempImage<Float> > _sigma;
00198 
00199         const static String _class;
00200 
00201         const static uInt _nOthers;
00202         const static uInt _gsPlane;
00203         const static uInt _lsPlane;
00204 
00205 
00206         enum gaussSols {
00207             AMP, CENTER, FWHM, INTEGRAL, AMPERR, CENTERERR,
00208             FWHMERR, INTEGRALERR, NGSOLMATRICES
00209         };
00210 
00211     void _getOutputStruct(
00212         vector<ImageInputProcessor::OutputStruct>& outputs
00213     );
00214 
00215     void _checkNGaussAndPolyOrder() const;
00216 
00217     void _finishConstruction();
00218 
00219     void _setResults();
00220 
00221     String _radToRa(const Float ras) const;
00222 
00223     void _resultsToLog();
00224 
00225     String _getTag(const uInt i) const;
00226 
00227     String _elementToString(
00228         const Double value, const Double error,
00229         const String& unit
00230     ) const;
00231 
00232     String _pcfToString(
00233         const PCFSpectralElement *const &pcf, const CoordinateSystem& csys,
00234         const Vector<Double> world, const IPosition imPos, const Bool showTypeString=True,
00235         const String& indent=""
00236     ) const;
00237 
00238     String _gaussianMultipletToString(
00239         const GaussianMultipletSpectralElement& gm,
00240         const CoordinateSystem& csys, const Vector<Double> world,
00241         const IPosition imPos
00242     ) const;
00243 
00244     String _polynomialToString(
00245         const PolynomialSpectralElement& poly, const CoordinateSystem& csys,
00246         const Vector<Double> imPix, const Vector<Double> world
00247     ) const;
00248 
00249     static void _makeSolutionImage(
00250         const String& name, const CoordinateSystem& csys,
00251         const Array<Double>& values, const String& unit,
00252         const Array<Bool>& mask
00253     );
00254 
00255     void _insertPCF(
00256         vector<vector<Matrix<Double> > >& pcfMatrices, /* Bool& isSolutionSane,*/
00257         const uInt idx, const PCFSpectralElement& pcf,
00258         const uInt row, const uInt col, const IPosition& pos,
00259         const Double increment/*, const uInt npix*/
00260     ) const;
00261 
00262     void _writeImages(
00263         const CoordinateSystem& csys,
00264         const Array<Bool>& mask, const String& yUnit
00265     ) const;
00266 
00267     /*
00268     // moved from ImageAnalysis
00269     void _fitProfile(
00270         const Bool fitIt=True
00271     );
00272     */
00273 
00274     // moved from ImageAnalysis
00275     void _fitallprofiles();
00276 
00277     // Fit all profiles in image.  The output images must be already
00278     // created; if the pointer is 0, that image won't be filled.
00279     // The mask from the input image is transferred to the output
00280     // images.    If the weights image is pointer is non-zero, the
00281     // values from it will be used to weight the data points in the
00282     // fit.  You can fit some combination of gaussians and a polynomial
00283     // (-1 means no polynomial).  Initial estimates are not required.
00284     // Fits are done in image space to provide astronomer friendly results,
00285     // but pixel space is better for the fitter when fitting polynomials.
00286     // Thus, atm, callers should be aware that fitting polynomials may
00287     // fail even when the data lie exactly on a polynomial curve.
00288     // This will probably be fixed in the future by doing the fits
00289     // in pixel space here and requiring the caller to deal with converting
00290     // to something astronomer friendly if it so desires.
00291 
00292     void _fitProfiles(
00293         std::auto_ptr<ImageInterface<Float> >& pFit,
00294         std::auto_ptr<ImageInterface<Float> >& pResid,
00295         const Bool showProgress=False
00296     );
00297 
00298     Double _fitAxisIncrement() const;
00299 
00300     Double _centerWorld(
00301         const PCFSpectralElement& solution, const IPosition& imPos
00302     ) const;
00303 
00304     Bool _inVelocitySpace() const;
00305 
00306     void _flagFitterIfNecessary(ImageFit1D<Float>& fitter) const;
00307 
00308     Bool _isPCFSolutionOK(const PCFSpectralElement *const &pcf) const;
00309 
00310     Vector< Vector<Double> > _pixelPositions;
00311 };
00312 }
00313 
00314 #endif