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
00022
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
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
00163
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
00174 rootfunc->SetParameter(ipar, this->getParameter(ipar) ) ;
00175
00176 rootfunc->SetParError(ipar, this->getParError(ipar) );
00177
00178 rootfunc->SetParName(ipar, this->getParName(ipar) );
00179 if (isFixed(ipar)) rootfunc->SetParLimits(ipar, this->getParameter(ipar), this->getParameter(ipar));
00180 }
00181
00182
00183 rootfunc->SetNDF( this->getNDF() );
00184 rootfunc->SetChisquare( this->getChiSquared() );
00185
00186
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
00200 rootfunc->SetTitle(this->getFormula());
00201 rootfunc->SetName(this->getFormula());
00202 return rootfunc;
00203 }
00204
00205
00206 FitObject& FitObject::operator=(const TF1& rootfunc) throw(LogicError) {
00207
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
00219 }
00220
00221
00222 this->setChiSquared( rootfunc.GetChisquare() );
00223 this->setNDF( rootfunc.GetNDF() );
00224
00225
00226 this->setVarMax(0, rootfunc.GetXmax() );
00227 this->setVarMin(0, rootfunc.GetXmin() );
00228
00229
00230
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 }