00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TGo4FitModelFormula.h"
00017
00018 #include "Riostream.h"
00019
00020 #include "TFormula.h"
00021 #include "TGo4FitParameter.h"
00022
00023 TGo4FitModelFormula::TGo4FitModelFormula() : TGo4FitModel(),
00024 fxExpression(), fxPosIndex(), fxWidthIndex(), fxFormula(0) {
00025 }
00026
00027 TGo4FitModelFormula::TGo4FitModelFormula(const char* iName, const char* iExpressionStr, Int_t iNPars, Bool_t AddAmplitude) :
00028 TGo4FitModel(iName,"based on TFormula line shape",AddAmplitude),
00029 fxExpression(iExpressionStr), fxPosIndex(), fxWidthIndex(), fxFormula(0) {
00030
00031 for (Int_t n=0;n<iNPars;n++)
00032 NewParameter(GetExprParName(n),"formula parameter",0.);
00033 }
00034
00035
00036 TGo4FitModelFormula::~TGo4FitModelFormula() {
00037 CloseFormula();
00038 }
00039
00040 Int_t TGo4FitModelFormula::GetNumberOfExprPar() {
00041 Int_t num = TGo4FitParsList::NumPars();
00042 if (GetAmplPar()) num--;
00043 return num;
00044 }
00045
00046 TGo4FitParameter* TGo4FitModelFormula::GetExprPar(Int_t n) {
00047 if ((n<0) || (n>=GetNumberOfExprPar())) return 0;
00048 if ((GetAmplIndex()>=0) && (n>=GetAmplIndex())) n++;
00049 return GetPar(n);
00050 }
00051
00052 Bool_t TGo4FitModelFormula::SetNumberOfExprPar(Int_t num) {
00053 Int_t oldnum = GetNumberOfExprPar();
00054 if ((num<0) || (oldnum==num)) return kFALSE;
00055 if(num<oldnum) {
00056 for(Int_t n=oldnum-1;n>=num;n--)
00057 RemovePar(GetExprPar(n)->GetName());
00058 } else {
00059 for(Int_t n=oldnum;n<num;n++)
00060 NewParameter(GetExprParName(n),"formula parameter",0.);
00061 }
00062 return kTRUE;
00063 }
00064
00065 void TGo4FitModelFormula::SetPosParIndex(Int_t naxis, Int_t indx) {
00066 if (naxis<0) return;
00067 Int_t oldsize = fxPosIndex.GetSize();
00068 if (naxis>=oldsize) {
00069 fxPosIndex.Set(naxis+1);
00070 for (Int_t n=oldsize;n<fxPosIndex.GetSize();n++) fxPosIndex[n] = -1;
00071 }
00072 fxPosIndex[naxis] = indx;
00073 }
00074
00075 void TGo4FitModelFormula::SetWidthParIndex(Int_t naxis, Int_t indx) {
00076 if (naxis<0) return;
00077 Int_t oldsize = fxWidthIndex.GetSize();
00078 if (naxis>=oldsize) {
00079 fxWidthIndex.Set(naxis+1);
00080 for (Int_t n=oldsize;n<fxWidthIndex.GetSize();n++) fxWidthIndex[n] = -1;
00081 }
00082 fxWidthIndex[naxis] = indx;
00083 }
00084
00085 Int_t TGo4FitModelFormula::GetPosParIndex(Int_t naxis) {
00086 if ((naxis<0) || (naxis>=fxPosIndex.GetSize())) return -1;
00087 return GetParIndex(GetExprPar(fxPosIndex[naxis]));
00088 }
00089
00090 Int_t TGo4FitModelFormula::GetWidthParIndex(Int_t naxis) {
00091 if ((naxis<0) || (naxis>=fxWidthIndex.GetSize())) return -1;
00092 return GetParIndex(GetExprPar(fxWidthIndex[naxis]));
00093 }
00094
00095 TString TGo4FitModelFormula::GetExprParName(Int_t n)
00096 {
00097 TString res;
00098 res.Form("Par%d",n);
00099 return res;
00100 }
00101
00102 Bool_t TGo4FitModelFormula::Initialize(Int_t UseBuffers) {
00103 if (!CompileFormula()) return kFALSE;
00104 CloseFormula();
00105 return TGo4FitModel::Initialize(UseBuffers);
00106 }
00107
00108 Bool_t TGo4FitModelFormula::BeforeEval(Int_t ndim) {
00109 if (!CompileFormula()) return kFALSE;
00110 Par_ndim = ndim;
00111 for(Int_t n=0;n<NumPars();n++)
00112 fxFormula->SetParameter(n, GetPar(n)->GetValue());
00113 return kTRUE;
00114 }
00115
00116 Double_t TGo4FitModelFormula::EvalN(const Double_t* v) {
00117 switch (Par_ndim) {
00118 case 0: return 0.;
00119 case 1: return fxFormula->Eval(v[0]);
00120 case 2: return fxFormula->Eval(v[0],v[1]);
00121 case 3: return fxFormula->Eval(v[0],v[1],v[2]);
00122 default: return fxFormula->EvalPar(v, 0);
00123 }
00124 }
00125
00126 void TGo4FitModelFormula::AfterEval() {
00127 CloseFormula();
00128 }
00129
00130 void TGo4FitModelFormula::Finalize() {
00131 CloseFormula();
00132 TGo4FitModel::Finalize();
00133 }
00134
00135 void TGo4FitModelFormula::Print(Option_t* option) const {
00136 TGo4FitModel::Print(option);
00137 cout << " Expression = " << *fxExpression << endl;
00138 for (Int_t naxis=0;naxis<fxPosIndex.GetSize();naxis++) {
00139 TGo4FitParameter* par = ((TGo4FitModelFormula*) this)->GetExprPar(fxPosIndex[naxis]);
00140 if (par)
00141 cout << " Position on " << naxis << " axis is " << par->GetName() << endl;
00142 }
00143 for (Int_t naxis=0;naxis<fxWidthIndex.GetSize();naxis++) {
00144 TGo4FitParameter* par = ((TGo4FitModelFormula*) this)->GetExprPar(fxWidthIndex[naxis]);
00145 if (par)
00146 cout << " Width on " << naxis << " axis is " << par->GetName() << endl;
00147 }
00148 }
00149
00150 Bool_t TGo4FitModelFormula::CompileFormula() {
00151 CloseFormula();
00152
00153 TString Expr(fxExpression);
00154 for (Int_t n=0;n<NumPars();n++) {
00155 TString str;
00156 str.Form("[%d]",n);
00157 Expr.ReplaceAll(GetParName(n), str);
00158 }
00159
00160 fxFormula = new TFormula("Expression", Expr);
00161
00162 Int_t err = fxFormula->Compile(Expr);
00163 if (err!=0) {
00164 cout << "Error in formula: " << fxExpression.Data() << " code " << err << endl;
00165 CloseFormula();
00166 return kFALSE;
00167 }
00168 return kTRUE;
00169 }
00170
00171 void TGo4FitModelFormula::CloseFormula() {
00172 if (fxFormula) { delete fxFormula; fxFormula = 0; }
00173 }
00174
00175