casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Fit2D.h
Go to the documentation of this file.
00001 //# Fit2D.h: Class to fit 2-D objects to Lattices or Arrays
00002 //# Copyright (C) 1997,1998,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: Fit2D.h 19779 2006-12-12 23:20:42Z gvandiep $
00027 
00028 #ifndef LATTICES_FIT2D_H
00029 #define LATTICES_FIT2D_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <scimath/Functionals/CompoundFunction.h>
00034 #include <casa/BasicSL/Constants.h>
00035 #include <scimath/Fitting/NonLinearFitLM.h>
00036 #include <casa/Logging/LogIO.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 template<class T> class Array;
00041 template<class T> class Matrix;
00042 template<class T> class Vector;
00043 template<class T> class Lattice;
00044 template<class T> class MaskedLattice;
00045 
00046 
00047 // <summary>
00048 // Fit 2-D objects to 2-D Lattices or Arrays
00049 // </summary>
00050 
00051 // <use visibility=export>
00052 
00053 // <reviewed reviewer="" date="" tests="">
00054 // </reviewed>
00055 
00056 // <prerequisite>
00057 //   <li> <linkto class=Lattice>Lattice</linkto>
00058 // </prerequisite>
00059 
00060 // <synopsis> 
00061 // This class allows you to fit different types of 2-D models
00062 // to either Lattices or Arrays.  These must be 2 dimensional;
00063 // for Lattices, the appropriate 2-D Lattice can be made with
00064 // the SubLattice class.
00065 //
00066 // You may fit more than one model simultaneously to the data.
00067 // Models are added with the addModel method.   With this method,
00068 // you also specify the initial guesses of the parameters of
00069 // the model.    Any parameters involving coordinates are
00070 // expected in zero-relative absolute pixel coordinates (e.g. the centre of
00071 // a model).  Additionally with the addModel method, 
00072 // you may specify which parameters are to be held fixed
00073 // during the fitting process.  This is done with the 
00074 // parameterMask Vector which is in the same order as the
00075 // parameter Vector.  A value of True indicates the parameter
00076 // will be fitted for.  Presently, when you say fix the minor axis,
00077 // you really end up fixing the axial ratio (internals).  I don't
00078 // have a solution for this presently.
00079 // 
00080 // For Gaussians, the parameter Vector (input or output) consists, in order, of
00081 // the peak, x location, y location, FWHM of major axis, FWHM of minor axis, 
00082 // and position angle of the major axis (in radians). The 
00083 // position angle is positive +x to +y 
00084 // in the pixel coordinate system ([0,0] in center of image) and 
00085 // in the range -2pi to 2pi.  When the solution is recovered, the
00086 // position angle will be in the range 0 to pi.
00087 //
00088 // </synopsis> 
00089 // <example>
00090 // <srcblock>
00091 // </srcblock>
00092 // </example>
00093 
00094 // <todo asof="1998/12/11">
00095 //  <li> template it 
00096 //  <li> Speed up some Array calculations indexed with IPositions
00097 //  <li> Don't handle Lattices simply by getting pixels into Arrays
00098 //  <li> make an addModel interface taking functionals
00099 // </todo>
00100 
00101 class Fit2D 
00102 {
00103 public:
00104 
00105     // Enum describing the different models you can fit
00106     enum Types {
00107       GAUSSIAN = 0,
00108       DISK = 1,
00109       LEVEL=2,
00110       PLANE=3,
00111       nTypes
00112     };
00113 
00114     // Enum describing output error conditions
00115     enum ErrorTypes {
00116 // ok
00117       OK = 0,
00118 // Did not converge
00119       NOCONVERGE = 1,
00120 // Solution failed
00121       FAILED = 2,
00122 // There were no unmasked points
00123       NOGOOD = 3,
00124 // No models set
00125       NOMODELS = 4,
00126 // Number of conditions
00127       nErrorTypes
00128     };
00129 
00130     // Constructor
00131     explicit Fit2D(LogIO& logger);
00132 
00133     // Destructor
00134     ~Fit2D();
00135 
00136     // Copy constructor.  Uses copy semantics except for the logger
00137     // for which a reference copy is made
00138     Fit2D(const Fit2D& other);
00139 
00140     // Assignment operator. Uses copy semantics except for the logger
00141     // for which a reference copy is made
00142     Fit2D& operator=(const Fit2D& other);
00143 
00144     // Add a model to the list to be simultaneously fit and 
00145     // return its index.  Specify the initial guesses for
00146     // the model and a mask indicating whether the parameter
00147     // is fixed (False) during the fit or not.  Returns the
00148     // the model number added (0, 1, 2 etc)
00149     //<group>
00150     uInt addModel (Fit2D::Types type,
00151                    const Vector<Double>& parameters,
00152                    const Vector<Bool>& parameterMask);
00153     uInt addModel(Fit2D::Types type,
00154                    const Vector<Double>& parameters);
00155     //</group>
00156 
00157     // Convert mask from a string to a vector.  The string gives the parameters
00158     // to keep fixed in the fit (f (flux), x (x position), y (y position),
00159     // a (FWHM major axis), b (FWHM minor axis), p (position angle)
00160     static Vector<Bool> convertMask (const String fixedmask,
00161                                      Fit2D::Types type);
00162 
00163 
00164     // Set a pixel selection range.  When the fit is done, only
00165     // pixels in the specified range are included/excluded.
00166     // Only the last call of either of these will be active.
00167     //<group>
00168     void setIncludeRange (Double minVal, Double maxVal);
00169     void setExcludeRange (Double minVal, Double maxVal);
00170     void resetRange();
00171     //</group>
00172 
00173     // Return number of parameters for this type of model
00174     static uInt nParameters (Fit2D::Types type);
00175 
00176     // Recover number of models
00177     uInt nModels() const;
00178 
00179     // Determine an initial estimate for the solution of the specified
00180     // model type to the given data - no compound models are allowable
00181     // in this function.   If you have specified an include
00182     // or exclude pixel range to the fitter, that will be honoured.
00183     // This function does not interact with the addModel function.
00184     // Returns a zero length vector if it fails to make an estimate.
00185     //<group>
00186     Vector<Double> estimate(Fit2D::Types type,
00187                             const MaskedLattice<Float>& data);
00188     Vector<Double> estimate(Fit2D::Types type, const Lattice<Float>& data);
00189     Vector<Double> estimate(Fit2D::Types type, const Array<Float>& data);
00190     Vector<Double> estimate(Fit2D::Types type, const Array<Float>& data,
00191                             const Array<Bool>& mask);
00192     //</group>
00193 
00194     // Do the fit.  Returns an enum value to tell you what happened if the fit failed
00195     // for some reasons.  A message can also be found with function errorMessage if 
00196     // the fit was not successful.  For Array(i,j) i is x and j is y
00197     //<group>
00198     Fit2D::ErrorTypes fit(const MaskedLattice<Float>& data, 
00199                           const Lattice<Float>& sigma);
00200     Fit2D::ErrorTypes fit(const Lattice<Float>& data, 
00201                           const Lattice<Float>& sigma);
00202     Fit2D::ErrorTypes fit(const Array<Float>& data, 
00203                           const Array<Float>& sigma);
00204     Fit2D::ErrorTypes fit(const Array<Float>& data,
00205                           const Array<Bool>& mask, 
00206                           const Array<Float>& sigma);
00207     //</group>
00208 
00209     // Find the residuals to the fit.   
00210     //<group>
00211     Fit2D::ErrorTypes residual(Array<Float>& resid, Array<Float>& model,
00212                                const Array<Float>& data);
00213     Fit2D::ErrorTypes residual(Array<Float>& resid, Array<Float>& model,
00214                                const MaskedLattice<Float>& data);
00215     Fit2D::ErrorTypes residual(Array<Float>& resid, Array<Float>& model,
00216                                const Lattice<Float>& data);
00217     //</group>
00218     // If function fit failed, you will find a message here
00219     // saying why it failed
00220     String errorMessage () const;
00221 
00222     // Recover solution for either all model components or
00223     // a specific one.  These functions will return an empty vector
00224     // if there is no valid solution.    All available parameters (fixed and
00225     // adjustable) are included in the solution vectors.  
00226     //<group>
00227     Vector<Double> availableSolution () const;
00228     Vector<Double> availableSolution (uInt which) const;
00229     //</group>
00230 
00231     // The errors. All available parameters (fixed and adjustable) are 
00232     // included in the error vectors.  Unsolved for parameters will 
00233     // have error 0.
00234     //<group>
00235     Vector<Double> availableErrors() const;
00236     Vector<Double> availableErrors(uInt which) const;
00237     //</group>
00238 
00239     // The number of iterations that the fitter finished with
00240     uInt numberIterations() const;
00241 
00242     // The chi squared of the fit.  Returns 0 if fit has been done.
00243     Double chiSquared () const;
00244 
00245     // The number of points used for the last fit
00246     uInt numberPoints () const;
00247 
00248     // Return type as a string
00249     static String type(Fit2D::Types type);
00250 
00251     // Return string type as enum (min match)
00252     static Fit2D::Types type(const String& type);
00253 
00254     // Find type of specific model
00255     Fit2D::Types type(uInt which);
00256 
00257     // Convert p.a. (radians) from positive +x -> +y 
00258     // (Fit2D) to positive +y -> -x (Gaussian2D)
00259     static Double paToGauss2D (Double pa) {return pa - C::pi_2;};
00260 
00261     // Convert p.a. (radians) from positive +y -> -x
00262     // (Gaussian2D) to positive +x -> +y (Fit2D)
00263     static Double paFromGauss2D (Double pa) {return pa + C::pi_2;};
00264 
00265 private:
00266 
00267    mutable LogIO itsLogger;
00268    Bool itsValid, itsValidSolution, itsHasSigma;
00269    Bool itsInclude;
00270    Vector<Float> itsPixelRange;
00271    CompoundFunction<AutoDiff<Double> > itsFunction;
00272    NonLinearFitLM<Double> itsFitter;
00273    Vector<Double> itsSolution;
00274    Vector<Double> itsErrors;
00275    Double itsChiSquared;
00276    String itsErrorMessage;
00277    uInt itsNumberPoints;
00278 //
00279    Vector<uInt> itsTypeList;
00280 //
00281    Fit2D::ErrorTypes fitData(const Vector<Double>& values,
00282                              const Matrix<Double>& pos,
00283                              const Vector<Double>& sigma);
00284 
00285 // Returns available (adjustable + fixed) solution for model of
00286 // interest and tells you where it began in the full solution vector
00287 // Does no axial ratio nor position angle conversions from direct
00288 // fit solution vector
00289 // <group>
00290    Vector<Double> availableSolution (uInt& iStart, uInt which) const;
00291    Vector<Double> availableErrors (uInt& iStart, uInt which) const;
00292 // </group>
00293 
00294    Vector<Double> getParams(uInt which) const;
00295    void setParams(const Vector<Double>& params, uInt which);
00296 
00297    Bool includeIt (Float value, const Vector<Float>& range, 
00298                    Int includeIt) const;
00299 
00300    Bool selectData (Matrix<Double>& pos, Vector<Double>& values,
00301                     Vector<Double>& weights,  const Array<Float>& pixels,
00302                     const Array<Bool>& mask, const Array<Float>& sigma);
00303    void piRange (Double& pa) const;
00304 
00305 };
00306 
00307 inline Bool Fit2D::includeIt (Float value, const Vector<Float>& range, 
00308                               Int includeIt) const
00309 {
00310    if (includeIt==0) return True;
00311 //
00312    if (includeIt==1) {
00313       if (value >= range(0) && value <= range(1)) return True;
00314    } else if (value < range(0) || value > range(1)) {
00315       return True;
00316    }
00317 //
00318    return False;
00319 }
00320 
00321 
00322 
00323 
00324 } //# NAMESPACE CASA - END
00325 
00326 #endif
00327 
00328