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