00001 #include "FitObject.h"
00002 #include "Sct/OutOfRangeError.h"
00003
00004 #include <iomanip>
00005 #include <cfloat>
00006
00007 using namespace std;
00008
00009 using namespace Sct;
00010
00011 namespace SctData {
00012
00013 FitObject::FitObject() throw() {}
00014
00015
00016
00017 FitObject::FitObject(const TF1& rootfunc ) throw (LogicError) {
00018 (*this) = rootfunc;
00019 }
00020
00021 void FitObject::reset() throw() {
00022
00023 this->setNDF(0);
00024 this->setChiSquared(0.) ;
00025 for (int ipar=0; ipar<this->getNPar(); ipar++) {
00026 this->setParameter(ipar,0.);
00027 this->setParError(ipar,0.);
00028 this->fixParameter(ipar, false);
00029 }
00030 }
00031
00032 char* FitObject::getParName(const int ipar) const throw(LogicError) {
00033 #ifndef NDEBUG
00034 if ( ipar<0 || ipar>=this->getNPar() ) {
00035 throw OutOfRangeError<int>("FitObject::getParName ", __FILE__, __LINE__, ipar,0,this->getNPar()-1);
00036 }
00037 #endif
00038 return const_cast <char*> ( (m_parName[ipar]).c_str() ) ;
00039 }
00040
00041 int FitObject::getParIndex(const string& name) const throw(LogicError) {
00042 for (unsigned int i=0; i<m_parName.size(); ++i) {
00043 if (m_parName[i] == name)
00044 return i;
00045 }
00046 throw InvalidArgumentError("FitObject::getParIndex Didn't find " + name, __FILE__, __LINE__);
00047 }
00048
00049
00050 double FitObject::getParameter(const int ipar) const throw(LogicError) {
00051 #ifndef NDEBUG
00052 if ( ipar<0 || ipar>=this->getNPar() ) {
00053 throw OutOfRangeError<int>("FitObject::getParError ",__FILE__, __LINE__, ipar,0,this->getNPar()-1);
00054 }
00055 #endif
00056 return m_parameter[ipar];
00057 }
00058
00059 double FitObject::getParError(const int ipar) const throw(LogicError) {
00060 #ifndef NDEBUG
00061 if ( ipar<0 || ipar>=this->getNPar() ) {
00062 throw OutOfRangeError<int>("FitObject::getParError ", __FILE__, __LINE__, ipar,0,this->getNPar()-1);
00063 }
00064 #endif
00065 return m_parError[ipar];
00066 }
00067
00068 void FitObject::setNPar(unsigned int npar) throw() {
00069
00070 m_parameter.resize( npar ) ;
00071 m_parError.resize( npar ) ;
00072 m_parName.resize( npar ) ;
00073 m_parFixed.resize(npar);
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 void FitObject::setNDim(unsigned int n) throw() {
00106 m_varMax.resize( n, DBL_MAX ) ;
00107 m_varMin.resize( n, -DBL_MAX ) ;
00108 }
00109
00110 double FitObject::getVarMax(const int ivar) const throw (LogicError) {
00111 #ifndef NDEBUG
00112 if ( ivar<0||ivar>=this->getNDim() ) {
00113 throw OutOfRangeError<int>("FitObject::getVarMax", __FILE__, __LINE__, ivar,0,this->getNDim()-1);
00114 }
00115 #endif
00116 return m_varMax[ivar];
00117 }
00118
00119 double FitObject::getVarMin(const int ivar) const throw (LogicError) {
00120 #ifndef NDEBUG
00121 if ( ivar<0||ivar>=this->getNDim() ) {
00122 throw OutOfRangeError<int>("FitObject::getVarMin", __FILE__, __LINE__, ivar,0,this->getNDim()-1);
00123 }
00124 #endif
00125 return m_varMin[ivar];
00126 }
00127
00128 void FitObject::setVarMax(const int ivar, const double value) throw(LogicError) {
00129 #ifndef NDEBUG
00130 if ( ivar<0||ivar>=this->getNDim() ) {
00131 throw OutOfRangeError<int>("FitObject::setVarMax", __FILE__, __LINE__, ivar,0,this->getNDim()-1);
00132 }
00133 #endif
00134 m_varMax[ivar]=value;
00135 }
00136
00137 void FitObject::setVarMin(const int ivar, const double value) throw(LogicError) {
00138 #ifndef NDEBUG
00139 if ( ivar<0||ivar>=this->getNDim() ) {
00140 throw OutOfRangeError<int>("FitObject::setVarMin", __FILE__, __LINE__, ivar,0,this->getNDim()-1);
00141 }
00142 #endif
00143 m_varMin[ivar]=value;
00144 }
00145
00146 void FitObject::fixParameter(int ipar, bool fix) {
00147 #ifndef NDEBUG
00148 if ( ipar<0||ipar>=getNPar() ) {
00149 throw OutOfRangeError<int>("FitObject::isFixed", __FILE__, __LINE__, ipar,0,getNPar()-1);
00150 }
00151 #endif
00152 m_parFixed[ipar] = fix;
00153 }
00154
00155 bool FitObject::isFixed(int ipar) const {
00156 #ifndef NDEBUG
00157 if ( ipar<0||ipar>=getNPar() ) {
00158 throw OutOfRangeError<int>("FitObject::isFixed", __FILE__, __LINE__, ipar,0,getNPar()-1);
00159 }
00160 #endif
00161 return m_parFixed[ipar];
00162 }
00163
00164
00165 auto_ptr<TF1> FitObject::makeRootTF1() const throw (LogicError) {
00166
00167
00168
00169 #ifndef NDEBUG
00170 if ( this->getNDim()!=1 )
00171 {
00172 throw OutOfRangeError<int>("FitObject::makeRootTF1 nDim", __FILE__, __LINE__, this->getNDim(),1,1);
00173 }
00174 #endif
00175
00176 auto_ptr<TF1> rootfunc = this->makeBasicRootTF1();
00177
00178 for ( int ipar=0 ; ipar<this->getNPar() ; ipar++ ) {
00179
00180 rootfunc->SetParameter(ipar, this->getParameter(ipar) ) ;
00181
00182 rootfunc->SetParError(ipar, this->getParError(ipar) );
00183
00184 rootfunc->SetParName(ipar, this->getParName(ipar) );
00185 if (isFixed(ipar)) rootfunc->SetParLimits(ipar, this->getParameter(ipar), this->getParameter(ipar));
00186 }
00187
00188
00189 rootfunc->SetNDF( this->getNDF() );
00190 rootfunc->SetChisquare( this->getChiSquared() );
00191
00192
00193 if (this->getNDim()==1) {
00194 rootfunc->SetRange ( this->getVarMin(0) , this->getVarMax(0) );
00195 } else if (this->getNDim()==2) {
00196 rootfunc->SetRange ( this->getVarMin(0) ,this->getVarMin(1) , this->getVarMax(0) , this->getVarMax(1) );
00197 } else if (this->getNDim()==3) {
00198 rootfunc->SetRange ( this->getVarMin(0) , this->getVarMin(1) ,this->getVarMin(2) ,
00199 this->getVarMax(0) , this->getVarMax(1) ,this->getVarMax(3) );
00200 } else {
00201 throw OutOfRangeError<int>("FitObject::makeRootTF1 ", __FILE__, __LINE__, this->getNDim(),1,3);
00202 }
00203
00204
00205
00206 rootfunc->SetTitle(this->getFormula());
00207 rootfunc->SetName(this->getFormula());
00208 return rootfunc;
00209 }
00210
00211
00212 FitObject& FitObject::operator=(const TF1& rootfunc) throw(LogicError) {
00213
00214 int npar=rootfunc.GetNpar();
00215 this->setNPar(npar);
00216
00217 for (int ipar=0 ; ipar<npar ; ipar++ ) {
00218 this->setParameter(ipar, rootfunc.GetParameter(ipar) );
00219 this->setParError(ipar, rootfunc.GetParError(ipar) );
00220
00221 }
00222
00223
00224 this->setChiSquared( rootfunc.GetChisquare() );
00225 this->setNDF( rootfunc.GetNDF() );
00226
00227
00228 this->setNDim( 1 );
00229
00230
00231 this->setVarMax(0, rootfunc.GetXmax() );
00232 this->setVarMin(0, rootfunc.GetXmin() );
00233
00234
00235
00236 return (*this);
00237 }
00238 void FitObject::print() const throw(LogicError) {
00239 cout <<*this;
00240 }
00241
00242 ostream& operator << (ostream & os, const SctData::FitObject& f) throw (LogicError) {
00243 os <<"========================================"<<endl;
00244 os << "FitObject, " << f.getFormula() << ", (" << f.getNDim() << " dimensional)" << endl;
00245 os << "----variables----------range-----------"<<endl;
00246 for (int idim=0; idim<f.getNDim(); idim++ ) {
00247 os << " var:"<< idim << " : " << setw(10) << f.getVarMin(idim)
00248 << " -> " << setw(10) << f.getVarMax(idim)<<endl;
00249 }
00250 os << "----parameters--------values----errors--"<<endl;
00251 for (int ipar=0; ipar<f.getNPar(); ipar++) {
00252 os << " par:"<<ipar<<" "<< setw(10) << f.getParName(ipar) << " = " << setw(10) << f.getParameter(ipar)
00253 << " +- " << f.getParError(ipar)<<endl;
00254 }
00255 os << " Chisq / NDF = " << f.getChiSquared() << " / " << f.getNDF()<<endl;
00256
00257 return os;
00258 }
00259
00260 }