Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Related Pages

FitObject.cpp

00001 #include "FitObject.h"
00002 #include "Sct/OutOfRangeError.h"
00003 
00004 #include <TF1.h>
00005 #include <iomanip>
00006 #include <cfloat>
00007 #include <algorithm>
00008 
00009 using namespace std;
00010 
00011 using namespace Sct;
00012 
00013 namespace SctData {
00014 
00015 FitObject::FitObject(string formula, unsigned int nPar, const vector<string>& parNames, unsigned int nDim) : 
00016     m_parameter(nPar, 0), m_parError(nPar, 0), m_parName(parNames), m_parFixed(nPar, false), m_varMax(nDim, DBL_MAX), 
00017     m_varMin(nDim, -DBL_MAX), m_chiSquared(0), m_nDF(0), m_formula(formula) {
00018     
00019 }
00020     
00021 // Create a FitObject from a root TF1 object
00022 // uses FitObject::operator= from below
00023 FitObject::FitObject(string formula, unsigned int nPar, const vector<string>& parNames, const TF1& rootfunc) : 
00024     m_parameter(nPar, 0), m_parError(nPar, 0), m_parName(parNames), m_parFixed(nPar, false), m_varMax(1, DBL_MAX), 
00025     m_varMin(1, -DBL_MAX), m_chiSquared(0), m_nDF(0), m_formula(formula) {
00026     (*this) = rootfunc;
00027 }
00028 
00029 void FitObject::reset() throw() {
00030     //not much to be done here
00031     m_nDF = 0;
00032     m_chiSquared = 0;
00033     fill(m_parameter.begin(), m_parameter.end(), 0);
00034     fill(m_parError.begin(), m_parError.end(), 0);
00035     fill(m_parFixed.begin(), m_parFixed.end(), false);
00036     fill(m_varMax.begin(), m_varMax.end(), DBL_MAX);
00037     fill(m_varMin.begin(), m_varMin.end(), -DBL_MAX);
00038 }
00039 
00040 char* FitObject::getParName(const int ipar) const throw(LogicError) {
00041 #ifndef NDEBUG
00042     if ( ipar<0 || ipar>=this->getNPar() ) {
00043         throw OutOfRangeError<int>("FitObject::getParName ", __FILE__, __LINE__, ipar,0,this->getNPar()-1);
00044     }
00045 #endif
00046     return const_cast <char*> ( (m_parName[ipar]).c_str() ) ;
00047 }
00048 
00049 int FitObject::getParIndex(const string& name) const throw(LogicError) {
00050     for (unsigned int i=0; i<m_parName.size(); ++i) {
00051         if (m_parName[i] == name)
00052             return i;
00053     }
00054     throw InvalidArgumentError("FitObject::getParIndex Didn't find " + name, __FILE__, __LINE__);
00055 }
00056 
00057 
00058 double FitObject::getParameter(const int ipar) const throw(LogicError) {
00059 #ifndef NDEBUG
00060     if ( ipar<0 || ipar>=this->getNPar() ) {
00061         throw OutOfRangeError<int>("FitObject::getParError ",__FILE__, __LINE__, ipar,0,this->getNPar()-1);
00062     }
00063 #endif
00064     return m_parameter[ipar];
00065 }
00066 
00067 double FitObject::getParError(const int ipar) const throw(LogicError) {
00068 #ifndef NDEBUG
00069     if ( ipar<0 || ipar>=this->getNPar() ) {
00070         throw OutOfRangeError<int>("FitObject::getParError ", __FILE__, __LINE__, ipar,0,this->getNPar()-1);
00071     }
00072 #endif
00073     return m_parError[ipar];
00074 }
00075 
00076 void FitObject::setParameter(const int ipar, const double value)
00077 throw(LogicError) {
00078 #ifndef NDEBUG
00079     if ( ipar<0 || ipar>=this->getNPar() ) {
00080         throw OutOfRangeError<int>("FitObject::setParameter", __FILE__, __LINE__, ipar,0,this->getNPar()-1);
00081     }
00082 #endif
00083     m_parameter[ipar]=value;
00084 }
00085 
00086 void FitObject::setParError(const int ipar, const double value)
00087 throw(LogicError) {
00088 #ifndef NDEBUG
00089     if ( ipar<0 || ipar>=this->getNPar() ) {
00090         throw OutOfRangeError<int>("FitObject::setParError", __FILE__, __LINE__, ipar,0,this->getNPar()-1);
00091     }
00092 #endif
00093     m_parError[ipar]=value;
00094 }
00095 
00096 void FitObject::setParName(int ipar, const char* name) throw(LogicError) {
00097 #ifndef NDEBUG
00098     if ( ipar<0 || ipar>=this->getNPar() ) {
00099         throw OutOfRangeError<int>("FitObject::setParName", __FILE__, __LINE__, ipar,0,this->getNPar()-1);
00100     }
00101 #endif
00102     m_parName[ipar]=name;
00103 }
00104 
00105 double FitObject::getVarMax(const int ivar) const throw (LogicError) {
00106 #ifndef NDEBUG
00107     if ( ivar<0||ivar>=this->getNDim() ) {
00108         throw OutOfRangeError<int>("FitObject::getVarMax", __FILE__, __LINE__, ivar,0,this->getNDim()-1);
00109     }
00110 #endif
00111     return m_varMax[ivar];
00112 }
00113 
00114 double FitObject::getVarMin(const int ivar) const throw (LogicError) {
00115 #ifndef NDEBUG
00116     if ( ivar<0||ivar>=this->getNDim() ) {
00117         throw OutOfRangeError<int>("FitObject::getVarMin", __FILE__, __LINE__, ivar,0,this->getNDim()-1);
00118     }
00119 #endif
00120     return m_varMin[ivar];
00121 }
00122 
00123 void FitObject::setVarMax(const int ivar, const double value) throw(LogicError) {
00124 #ifndef NDEBUG
00125     if ( ivar<0||ivar>=this->getNDim() ) {
00126         throw OutOfRangeError<int>("FitObject::setVarMax", __FILE__, __LINE__, ivar,0,this->getNDim()-1);
00127     }
00128 #endif
00129     m_varMax[ivar]=value;
00130 }
00131 
00132 void FitObject::setVarMin(const int ivar, const double value) throw(LogicError) {
00133 #ifndef NDEBUG
00134     if ( ivar<0||ivar>=this->getNDim() ) {
00135         throw OutOfRangeError<int>("FitObject::setVarMin", __FILE__, __LINE__, ivar,0,this->getNDim()-1);
00136     }
00137 #endif
00138     m_varMin[ivar]=value;
00139 }
00140 
00141 void FitObject::fixParameter(int ipar, bool fix) {
00142 #ifndef NDEBUG
00143     if ( ipar<0||ipar>=getNPar() ) {
00144         throw OutOfRangeError<int>("FitObject::isFixed", __FILE__, __LINE__, ipar,0,getNPar()-1);
00145     }
00146 #endif    
00147     m_parFixed[ipar] = fix;
00148 }
00149 
00150 bool FitObject::isFixed(int ipar) const {
00151 #ifndef NDEBUG
00152     if ( ipar<0||ipar>=getNPar() ) {
00153         throw OutOfRangeError<int>("FitObject::isFixed", __FILE__, __LINE__, ipar,0,getNPar()-1);
00154     }
00155 #endif    
00156     return m_parFixed[ipar];
00157 }
00158 
00159 
00160 auto_ptr<TF1> FitObject::makeRootTF1() const throw (LogicError) {
00161 
00162     // Check this is a one-dimensional function, otherwise
00163     // it dosen't make sense
00164 #ifndef NDEBUG
00165     if ( this->getNDim()!=1 ) {
00166         throw OutOfRangeError<int>("FitObject::makeRootTF1 nDim", __FILE__, __LINE__, this->getNDim(),1,1);
00167     }
00168 #endif
00169 
00170     auto_ptr<TF1> rootfunc  = this->makeBasicRootTF1();
00171 
00172     for ( int ipar=0 ; ipar<this->getNPar() ; ipar++ ) {
00173         // set the parameters
00174         rootfunc->SetParameter(ipar, this->getParameter(ipar) ) ;
00175         // set the errors
00176         rootfunc->SetParError(ipar, this->getParError(ipar) );
00177         // set the names
00178         rootfunc->SetParName(ipar, this->getParName(ipar) );
00179     if (isFixed(ipar)) rootfunc->SetParLimits(ipar, this->getParameter(ipar), this->getParameter(ipar));
00180     }
00181 
00182     // set the number of degrees of freedom and the chisquared
00183     rootfunc->SetNDF( this->getNDF() );
00184     rootfunc->SetChisquare( this->getChiSquared() );
00185 
00186     // set the minimum and maximum
00187     if (this->getNDim()==1) {
00188         rootfunc->SetRange ( this->getVarMin(0) , this->getVarMax(0) );
00189     } else if (this->getNDim()==2) {
00190         rootfunc->SetRange ( this->getVarMin(0) ,this->getVarMin(1) , this->getVarMax(0) , this->getVarMax(1) );
00191     } else if (this->getNDim()==3) {
00192         rootfunc->SetRange ( this->getVarMin(0) , this->getVarMin(1) ,this->getVarMin(2) ,
00193                              this->getVarMax(0) , this->getVarMax(1) ,this->getVarMax(3) );
00194     } else {
00195         throw OutOfRangeError<int>("FitObject::makeRootTF1 ", __FILE__, __LINE__, this->getNDim(),1,3);
00196     }
00197 
00198 
00199     //Set title
00200     rootfunc->SetTitle(this->getFormula());
00201     rootfunc->SetName(this->getFormula());
00202     return rootfunc;
00203 }
00204 
00205 // make this FitObject have the same parameter as a ROOT TF1 function
00206 FitObject& FitObject::operator=(const TF1& rootfunc) throw(LogicError) {
00207     // get the number of parameters of the root function
00208     int npar=rootfunc.GetNpar();
00209 #ifndef NDEBUG
00210     if ( this->getNPar()!=npar ) {
00211         throw OutOfRangeError<int>("FitObject::operator=(const TF1& rootfunc) - different numbers of parameters", __FILE__, __LINE__, npar, getNPar(),getNPar());
00212     }
00213 #endif
00214 
00215     for (int ipar=0 ; ipar<getNPar() ; ipar++ ) {
00216         this->setParameter(ipar, rootfunc.GetParameter(ipar) );
00217         this->setParError(ipar, rootfunc.GetParError(ipar) );
00218         // leave parameter names as in constructor.
00219     }
00220 
00221     // Set the chisquared and the number of degrees of freedom:
00222     this->setChiSquared( rootfunc.GetChisquare() );
00223     this->setNDF( rootfunc.GetNDF() );
00224 
00225     // Set the X max and X min
00226     this->setVarMax(0, rootfunc.GetXmax() );
00227     this->setVarMin(0, rootfunc.GetXmin() );
00228 
00229     // Don't set the formula: leave the one created by the constructor!
00230     // this->setFormula(rootfunc.GetTitle() );
00231     return (*this);
00232 }
00233 void FitObject::print() const throw(LogicError) {
00234     cout <<*this;
00235 }
00236 
00237 ostream& operator << (ostream & os, const SctData::FitObject& f) throw (LogicError) {
00238     os <<"========================================"<<endl;
00239     os << "FitObject, " << f.getFormula() << ", (" << f.getNDim() << " dimensional)" << endl;
00240     os << "----variables----------range-----------"<<endl;
00241     for (int idim=0; idim<f.getNDim(); idim++ ) {
00242         os << " var:"<< idim << " : " << setw(10) << f.getVarMin(idim)
00243         << " -> " << setw(10) << f.getVarMax(idim)<<endl;
00244     }
00245     os << "----parameters--------values----errors--"<<endl;
00246     for (int ipar=0; ipar<f.getNPar(); ipar++) {
00247         os << " par:"<<ipar<<" "<< setw(10) << f.getParName(ipar) << " = " << setw(10) << f.getParameter(ipar)
00248         << " +- " << f.getParError(ipar)<<endl;
00249     }
00250     os << " Chisq / NDF    =    " << f.getChiSquared() << " / " << f.getNDF()<<endl;
00251 
00252     return os;
00253 }
00254 
00255 } // end of namespace SctData

Generated on Thu Jul 15 09:50:45 2004 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5