00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "TGo4Fitter.h"
00017
00018 #include <stdlib.h>
00019
00020 #include "Riostream.h"
00021 #include "TClass.h"
00022 #include "TMath.h"
00023 #include "TH1.h"
00024 #include "TGraph.h"
00025 #include "TCanvas.h"
00026 #include "TObjArray.h"
00027 #include "TObjString.h"
00028 #include "TROOT.h"
00029 #include "THStack.h"
00030 #include "TArrayD.h"
00031
00032 #include "TGo4FitData.h"
00033 #include "TGo4FitDataHistogram.h"
00034 #include "TGo4FitDataGraph.h"
00035 #include "TGo4FitModel.h"
00036 #include "TGo4FitModelGauss1.h"
00037 #include "TGo4FitModelGauss2.h"
00038 #include "TGo4FitModelPolynom.h"
00039 #include "TGo4FitAmplEstimation.h"
00040 #include "TGo4FitSlot.h"
00041 #include "TGo4FitMinuit.h"
00042
00043 TGo4Fitter::TGo4Fitter() : TGo4FitterAbstract(), fxDatas(), fxModels(), fiFitFunctionType(0), fiMemoryUsage(0),
00044 fxUserFitFunction(0), fxDrawObjs(0) {
00045 }
00046
00047 TGo4Fitter::TGo4Fitter(const char* iName, const char* iTitle) : TGo4FitterAbstract(iName,iTitle),
00048 fxDatas(), fxModels(), fiFitFunctionType(0), fiMemoryUsage(0), fxUserFitFunction(0), fxDrawObjs(0) {
00049 fxDatas.SetOwner(kTRUE);
00050 fxModels.SetOwner(kTRUE);
00051 }
00052
00053 TGo4Fitter::TGo4Fitter(const char* iName, Int_t iFitFunctionType, Bool_t IsAddStandardActions) :
00054 TGo4FitterAbstract(iName,"TGo4Fitter object"),
00055 fxDatas(), fxModels(), fiFitFunctionType(0), fiMemoryUsage(100), fxUserFitFunction(0), fxDrawObjs(0) {
00056 fxDatas.SetOwner(kTRUE);
00057 fxModels.SetOwner(kTRUE);
00058 SetFitFunctionType(iFitFunctionType);
00059 if (IsAddStandardActions) AddStandardActions();
00060 }
00061
00062 TGo4Fitter::~TGo4Fitter() {
00063 CheckDuplicatesOnSlot();
00064 MoveDrawObjectsToROOT();
00065 }
00066
00067 void TGo4Fitter::SetMemoryUsage(Int_t iMemoryUsage)
00068 {
00069 if (iMemoryUsage<0) fiMemoryUsage=0; else
00070 if (iMemoryUsage>100) fiMemoryUsage=100; else
00071 fiMemoryUsage = iMemoryUsage;
00072 }
00073
00074 void TGo4Fitter::CollectAllPars()
00075 {
00076 TGo4FitterAbstract::CollectAllPars();
00077
00078 for(Int_t ndata=0;ndata<GetNumData();ndata++)
00079 GetData(ndata)->CollectParsTo(*this);
00080
00081 for(Int_t nmodel=0;nmodel<GetNumModel();nmodel++) {
00082 TGo4FitModel* model = GetModel(nmodel);
00083 for (Int_t n=0;n<model->NumAssigments();n++)
00084 if (FindData(model->AssignmentName(n))) {
00085 model->CollectParsTo(*this);
00086 break;
00087 }
00088 }
00089 }
00090
00091 void TGo4Fitter::Clear(Option_t* option) {
00092 TGo4FitterAbstract::Clear(option);
00093 DeleteAllData();
00094 DeleteAllModels();
00095 }
00096
00097 TGo4FitData* TGo4Fitter::GetData(Int_t n)
00098 {
00099 return (n>=0) && (n<GetNumData()) ? dynamic_cast<TGo4FitData*> (fxDatas[n]) : 0;
00100 }
00101
00102 const char* TGo4Fitter::GetDataName(Int_t n)
00103 {
00104 return GetData(n) ? GetData(n)->GetName() : 0;
00105 }
00106
00107 TGo4FitData* TGo4Fitter::FindData(const char* DataName)
00108 {
00109 return (DataName==0) ? 0 : dynamic_cast<TGo4FitData*> (fxDatas.FindObject(DataName));
00110 }
00111
00112 TGo4FitData* TGo4Fitter::AddData(TGo4FitData* data)
00113 {
00114 fxDatas.Add(data);
00115 SetParsListChange();
00116 SetUpdateSlotList();
00117 return data;
00118 }
00119
00120 TGo4FitDataHistogram* TGo4Fitter::AddH1(const char* DataName, TH1* histo, Bool_t Owned, Double_t lrange, Double_t rrange) {
00121 TGo4FitDataHistogram *data = new TGo4FitDataHistogram(DataName, histo, Owned);
00122 if ((lrange<rrange) || (rrange!=0.)) data->SetRange(0,lrange,rrange);
00123 AddData(data);
00124 return data;
00125 }
00126
00127 TGo4FitDataHistogram* TGo4Fitter::SetH1(const char* DataName, TH1* histo, Bool_t Owned) {
00128 TGo4FitDataHistogram* data = dynamic_cast<TGo4FitDataHistogram*> (FindData(DataName));
00129 if (data!=0) data->SetHistogram(histo, Owned);
00130 return data;
00131 }
00132
00133
00134 TGo4FitDataGraph* TGo4Fitter::AddGraph(const char* DataName, TGraph* gr, Bool_t Owned, Double_t lrange, Double_t rrange) {
00135 TGo4FitDataGraph *data = new TGo4FitDataGraph(DataName, gr, Owned);
00136 if ((lrange<rrange) || (rrange!=0.)) data->SetRange(0,lrange,rrange);
00137 AddData(data);
00138 return data;
00139 }
00140
00141 TGo4FitDataGraph* TGo4Fitter::SetGraph(const char* DataName, TGraph* gr, Bool_t Owned) {
00142 TGo4FitDataGraph *data = dynamic_cast<TGo4FitDataGraph*> (FindData(DataName));
00143 if (data!=0) data->SetGraph(gr, Owned);
00144 return data;
00145 }
00146
00147
00148
00149 void TGo4Fitter::CheckSlotsBeforeDelete(TGo4FitComponent* comp) {
00150 if (comp)
00151 for (Int_t n=0;n<comp->NumSlots();n++) {
00152 TGo4FitSlot* slot = comp->GetSlot(n);
00153 ClearSlot(slot, kFALSE);
00154 for(Int_t n2=0;n2<NumSlots();n2++) {
00155 TGo4FitSlot* slot2 = GetSlot(n2);
00156 if (slot2->GetConnectedSlot()==slot)
00157 slot2->ClearConnectionToSlot();
00158 }
00159
00160 }
00161 }
00162
00163 TGo4FitData* TGo4Fitter::RemoveData(const char* DataName, Bool_t IsDel) {
00164 TGo4FitData* dat = FindData(DataName);
00165 if (dat) {
00166 SetParsListChange();
00167 SetUpdateSlotList();
00168 fxDatas.Remove(dat);
00169 if(IsDel) { CheckSlotsBeforeDelete(dat); delete dat; dat = 0; }
00170 fxDatas.Compress();
00171 }
00172 return dat;
00173 }
00174
00175 void TGo4Fitter::DeleteAllData()
00176 {
00177 fxDatas.Delete();
00178 fxDatas.Compress();
00179 SetParsListChange();
00180 SetUpdateSlotList();
00181 }
00182
00183 TGo4FitModel* TGo4Fitter::GetModel(Int_t n)
00184 {
00185 return (n>=0) && (n<GetNumModel()) ? dynamic_cast<TGo4FitModel*> (fxModels[n]) : 0;
00186 }
00187
00188 TGo4FitModel* TGo4Fitter::FindModel(const char* ModelName)
00189 {
00190 return (ModelName==0) ? 0 : dynamic_cast<TGo4FitModel*> (fxModels.FindObject(ModelName));
00191 }
00192
00193 TGo4FitModel* TGo4Fitter::AddModel(TGo4FitModel* model)
00194 {
00195 fxModels.Add(model);
00196 SetParsListChange();
00197 SetUpdateSlotList();
00198 return model;
00199 }
00200
00201 TGo4FitModel* TGo4Fitter::AddModel(const char* DataName, TGo4FitModel* model)
00202 {
00203 model->AssignToData(DataName);
00204 fxModels.Add(model);
00205 SetParsListChange();
00206 SetUpdateSlotList();
00207 return model;
00208 }
00209
00210 TGo4FitComponent* TGo4Fitter::GetComp(Int_t n)
00211 {
00212 if(n<GetNumData()) return GetData(n); else return GetModel(n-GetNumData());
00213 }
00214
00215 void TGo4Fitter::AddPolynomX(const char* DataName, const char* NamePrefix, Int_t MaxOrder, Int_t GroupIndex, Double_t lrange, Double_t rrange)
00216 {
00217 if (DataName==0) return;
00218
00219 Bool_t flag = kFALSE;
00220 Int_t NumTry = 0;
00221 Bool_t createmodel = kFALSE;
00222
00223 do {
00224 TString Prefix(NamePrefix);
00225 if (NumTry>0) Prefix+=NumTry;
00226 flag = kFALSE;
00227 Bool_t findsame = kFALSE;
00228
00229 for(Int_t Order=0; Order<=MaxOrder; Order++) {
00230 TString Name(Prefix);
00231 Name += "_";
00232 Name += Order;
00233 findsame = FindModel(Name.Data());
00234 if (findsame && !createmodel) break;
00235
00236 if (createmodel) {
00237 TGo4FitModelPolynom* comp = new TGo4FitModelPolynom(Name, Order);
00238 comp->SetGroupIndex(GroupIndex);
00239 if ((lrange<rrange) || (rrange!=0.)) comp->SetRange(0,lrange,rrange);
00240 AddModel(DataName, comp);
00241 }
00242 }
00243
00244 flag = kTRUE;
00245 if (findsame) { NumTry++; createmodel = kFALSE; } else
00246 if (createmodel) flag = kFALSE;
00247 else createmodel = kTRUE;
00248
00249 } while (flag);
00250 }
00251
00252 void TGo4Fitter::AddPolynomX(const char* DataName, const char* NamePrefix, TArrayD& Coef, Int_t GroupIndex) {
00253 if (DataName==0) return;
00254
00255 Bool_t flag = kFALSE;
00256 Int_t NumTry = 0;
00257 Bool_t createmodel = kFALSE;
00258
00259 do {
00260 Bool_t findsame = kFALSE;
00261
00262 for (Int_t n=0;n<Coef.GetSize();n++) {
00263 TString Name(NamePrefix);
00264 if (NumTry>0) Name+=NumTry;
00265 Name+="_";
00266 Name+=n;
00267 findsame = FindModel(Name.Data());
00268 if (findsame && !createmodel) break;
00269
00270 if (createmodel) {
00271 TGo4FitModelPolynom* model = new TGo4FitModelPolynom(Name, n);
00272 model->SetAmplValue(Coef[n]);
00273 model->SetGroupIndex(GroupIndex);
00274 AddModel(DataName, model);
00275 }
00276 }
00277
00278 flag = kTRUE;
00279 if (findsame) { NumTry++; createmodel = kFALSE; } else
00280 if (createmodel) flag = kFALSE;
00281 else createmodel = kTRUE;
00282
00283 } while(flag);
00284 }
00285
00286 void TGo4Fitter::AddPolynoms(const char* DataName, const char* NamePrefix, Int_t MaxOrder, Int_t NumAxis, Int_t GroupIndex) {
00287 if (DataName==0) return;
00288 TArrayD Orders(NumAxis);
00289 Orders.Reset(0.);
00290
00291 Bool_t flag = kFALSE;
00292 Int_t NumTry = 0;
00293 Bool_t createmodel = kFALSE;
00294
00295 do {
00296
00297 TString Prefix(NamePrefix);
00298 if (NumTry>0) Prefix+=NumTry;
00299 flag = kFALSE;
00300 Bool_t findsame = kFALSE;
00301
00302 do {
00303 TString Name(Prefix);
00304 for(Int_t n=0; n<NumAxis; n++) {
00305 Name+="_";
00306 Name+=Int_t(Orders[n]);
00307 }
00308 findsame = FindModel(Name.Data());
00309 if (findsame && !createmodel) break;
00310
00311 if (createmodel) {
00312 TGo4FitModelPolynom* comp = new TGo4FitModelPolynom(Name, Orders);
00313 comp->SetGroupIndex(GroupIndex);
00314 AddModel(DataName, comp);
00315 }
00316
00317 Int_t nn = 0;
00318 do {
00319 Orders[nn] += 1.;
00320 if (Orders[nn]<=MaxOrder) break;
00321 Orders[nn]=0;
00322 nn++;
00323 } while (nn<NumAxis);
00324 flag = (nn<NumAxis);
00325 } while (flag);
00326
00327 flag = kTRUE;
00328 if (findsame) { NumTry++; createmodel = kFALSE; } else
00329 if (createmodel) flag = kFALSE;
00330 else createmodel = kTRUE;
00331
00332 } while (flag);
00333 }
00334
00335 TGo4FitModelGauss1* TGo4Fitter::AddGauss1(const char* DataName, const char* ModelName, Double_t iPosition, Double_t iWidth, Double_t iAmpl, Int_t Axis)
00336 {
00337 TGo4FitModelGauss1* gauss = new TGo4FitModelGauss1(ModelName, iPosition, iWidth, Axis);
00338 gauss->SetAmplValue(iAmpl);
00339 AddModel(DataName, gauss);
00340 return gauss;
00341 }
00342
00343 TGo4FitModel* TGo4Fitter::CloneModel(const char* ModelName, const char* NewName)
00344 {
00345 TGo4FitModel* mod = FindModel(ModelName);
00346 if (mod==0) return 0;
00347
00348 TString newname;
00349 int cnt = 0;
00350
00351 do {
00352 newname = NewName ? NewName : mod->GetName();
00353 if (cnt>0) {
00354 newname += "_";
00355 newname += cnt;
00356 }
00357 cnt++;
00358 } while (FindModel(newname.Data()));
00359
00360 TGo4FitModel* newmod = (TGo4FitModel*) mod->Clone(newname.Data());
00361
00362 return AddModel(newmod);
00363 }
00364
00365 TGo4FitModel* TGo4Fitter::RemoveModel(const char * ModelName, Bool_t IsDel)
00366 {
00367 TGo4FitModel* mod = FindModel(ModelName);
00368 if (mod) {
00369 SetParsListChange();
00370 SetUpdateSlotList();
00371 fxModels.Remove(mod);
00372 if(IsDel) { CheckSlotsBeforeDelete(mod); delete mod; mod = 0; }
00373 fxModels.Compress();
00374 }
00375 return mod;
00376 }
00377
00378 Int_t TGo4Fitter::NumModelsAssosiatedTo(const char* DataName) {
00379 Int_t res = 0;
00380 for (Int_t n=0;n<GetNumModel();n++)
00381 if (GetModel(n)->IsAssignTo(DataName)) res++;
00382 return res;
00383 }
00384
00385 void TGo4Fitter::DeleteModelsAssosiatedTo(const char* DataName) {
00386 Int_t n=0;
00387 while (n<GetNumModel()) {
00388 TGo4FitModel* model = GetModel(n++);
00389 if (model->IsAssignTo(DataName)){
00390 if (model->NumAssigments()==1) {
00391 SetParsListChange();
00392 SetUpdateSlotList();
00393 fxModels.Remove(model);
00394 delete model;
00395 fxModels.Compress();
00396 n--;
00397 } else model->ClearAssignmentTo(DataName);
00398 }
00399 }
00400 }
00401
00402 void TGo4Fitter::DeleteAllModels() {
00403 fxModels.Delete();
00404 fxModels.Compress();
00405 SetParsListChange();
00406 SetUpdateSlotList();
00407 }
00408
00409 void TGo4Fitter::AssignModelTo(const char* ModelName, const char* DataName, Double_t RatioValue, Bool_t FixRatio)
00410 {
00411 TGo4FitModel* model = FindModel(ModelName);
00412 if (model) {
00413 if (DataName!=0)
00414 model->AssignToData(DataName, RatioValue, FixRatio);
00415 else {
00416 model->ClearAssignments();
00417 for (int n=0; n<GetNumData(); n++)
00418 model->AssignToData(GetData(n)->GetName(), RatioValue, FixRatio);
00419 }
00420 SetParsListChange();
00421 }
00422 }
00423
00424 void TGo4Fitter::ClearModelAssignmentTo(const char* ModelName, const char* DataName)
00425 {
00426 TGo4FitModel* model = FindModel(ModelName);
00427 if (model==0) return;
00428 if (DataName!=0) model->ClearAssignmentTo(DataName);
00429 else model->ClearAssignments();
00430 SetParsListChange();
00431 }
00432
00433 void TGo4Fitter::ChangeDataNameInAssignments(const char* oldname, const char* newname) {
00434 for(Int_t n=0;n<GetNumModel();n++)
00435 GetModel(n)->ChangeDataNameInAssignments(oldname,newname);
00436 }
00437
00438 Bool_t TGo4Fitter::InitFitterData() {
00439
00440 Int_t dbuf = -1, mbuf = -1;
00441 switch (GetMemoryUsage()) {
00442 case 0: dbuf = 0; mbuf = 0; break;
00443 case 1: dbuf = 1; mbuf = 0; break;
00444 case 2: dbuf = 1; mbuf = 1; break;
00445 default: dbuf = -1; mbuf = -1;
00446 }
00447
00448 for(Int_t i1=0;i1<GetNumData();i1++) {
00449
00450 TGo4FitData *data = GetData(i1);
00451 if (!data->Initialize(dbuf)) return kFALSE;
00452 for(Int_t i2=0;i2<GetNumModel();i2++)
00453 GetModel(i2)->ConnectToDataIfAssigned(data);
00454 }
00455
00456 for(Int_t i2=0;i2<GetNumModel();i2++) {
00457 TGo4FitModel *fModel = GetModel(i2);
00458 if (!fModel->Initialize(mbuf)) return kFALSE;
00459 }
00460
00461 if( (fiFitFunctionType == ff_user) && (fxUserFitFunction==0) ) {
00462 cout << " User fit function not set. Switch to least squares " << endl;
00463 fiFitFunctionType = ff_least_squares;
00464 }
00465
00466 return kTRUE;
00467 }
00468
00469 void TGo4Fitter::FinalizeFitterData() {
00470 for(Int_t i=0;i<GetNumData();i++) GetData(i)->Finalize();
00471
00472 for(Int_t i=0;i<GetNumModel();i++) GetModel(i)->Finalize();
00473 }
00474
00475 Double_t TGo4Fitter::PointFitFunction(Int_t FitFunctionType, Double_t value, Double_t modelvalue, Double_t standdev) {
00476 switch (FitFunctionType) {
00477 case ff_least_squares: {
00478 Double_t zn1 = (value-modelvalue);
00479 return zn1*zn1; }
00480 case ff_chi_square: {
00481 if (standdev<=0.) return 0.;
00482 Double_t zn2 = (value-modelvalue);
00483 return zn2*zn2/standdev; }
00484 case ff_chi_Pearson: {
00485 if (modelvalue<=0.) return 0.;
00486 Double_t zn3 = (value-modelvalue);
00487 return zn3*zn3/modelvalue; }
00488 case ff_chi_Neyman: {
00489 Double_t zn4 = (value-modelvalue);
00490 return zn4*zn4/((value<1.) ? 1. : value); }
00491 case ff_chi_gamma: {
00492 if (value<0.) return 0.;
00493 Double_t zn5 = (value+((value<1.) ? 0. : 1.)-modelvalue);
00494 return zn5*zn5/(value+1.); }
00495 case ff_ML_Poisson:
00496 if (modelvalue<=0.) return 0.;
00497 return modelvalue - value*TMath::Log(modelvalue);
00498 case ff_user:
00499 if (fxUserFitFunction==0) return 0;
00500 return fxUserFitFunction(value, modelvalue, standdev);
00501 default:
00502 return (value-modelvalue)*(value-modelvalue);
00503 }
00504 }
00505
00506 Double_t TGo4Fitter::CalculateFCN(Int_t FitFunctionType, TGo4FitData* selectdata) {
00507
00508 if (GetMemoryUsage()>0) RebuildAll();
00509
00510 Double_t fSum = 0.;
00511
00512 for(Int_t n=0;n<GetNumData();n++) {
00513 TGo4FitData* dat = GetData(n);
00514 if (selectdata && (dat!=selectdata)) continue;
00515 Double_t DataAmpl = dat->GetAmplValue();
00516
00517 if (dat->BuffersAllocated()) {
00518 Int_t size = dat->GetBinsSize();
00519 Double_t* values = dat->GetBinsValues();
00520 Double_t* res = dat->GetBinsResult();
00521 Double_t* devs = dat->GetBinsDevs();
00522
00523 for(Int_t nbin=0;nbin<size;nbin++)
00524 fSum += PointFitFunction(FitFunctionType, DataAmpl*values[nbin], res[nbin], DataAmpl*DataAmpl*devs[nbin] );
00525 } else {
00526
00527 TGo4FitDataIter* iter = dat->MakeIter();
00528 if (!iter->Reset()) { delete iter; continue; }
00529
00530 TObjArray Models;
00531
00532 TArrayD Ampls(GetNumModel());
00533 for(Int_t nm=0;nm<GetNumModel();nm++)
00534 if (GetModel(nm)->IsAssignTo(dat->GetName())) {
00535 TGo4FitModel* model = GetModel(nm);
00536 Models.Add(model);
00537 model->BeforeEval(iter->ScalesSize());
00538 Ampls[Models.GetLast()] = model->GetAmplValue() * model->GetRatioValueFor(dat->GetName());
00539 }
00540
00541 do {
00542 Double_t value = DataAmpl * iter->Value();
00543 Double_t deviat = DataAmpl * DataAmpl * iter->StandardDeviation();
00544
00545 Double_t modelvalue = 0.;
00546 for(Int_t nm=0;nm<=Models.GetLast();nm++) {
00547 TGo4FitModel* model = dynamic_cast<TGo4FitModel*> (Models.At(nm));
00548 modelvalue += Ampls[nm] * model->EvaluateAtPoint(iter);
00549 }
00550
00551 fSum += PointFitFunction(FitFunctionType, value, modelvalue, deviat);
00552
00553 } while (iter->Next());
00554
00555 for(Int_t nm=0;nm<=Models.GetLast();nm++)
00556 ((TGo4FitModel*) Models.At(nm))->AfterEval();
00557
00558 delete iter;
00559 }
00560 }
00561
00562 return fSum;
00563 }
00564
00565 Double_t TGo4Fitter::CalculateFitFunction(Double_t* pars, Int_t FitFunctionType, const char* DataName) {
00566
00567 if (FitFunctionType<0) FitFunctionType = GetFitFunctionType();
00568
00569 if (pars) {
00570 ExecuteDependencies(pars);
00571 SetParsValues(pars);
00572 }
00573
00574 return CalculateFCN(FitFunctionType, FindData(DataName));
00575 }
00576
00577 Int_t TGo4Fitter::CalculateNDF(const char* DataName) {
00578 TGo4FitData* selectdata = FindData(DataName);
00579
00580 Int_t NDF = 0;
00581
00582 if (selectdata!=0) {
00583 NDF = selectdata->DefineBinsSize();
00584 for(Int_t nm=0;nm<GetNumModel();nm++) {
00585 TGo4FitModel* model = GetModel(nm);
00586 if (model->IsAssignTo(selectdata->GetName()))
00587 NDF -= model->NumFreePars();
00588 }
00589 } else {
00590 for (Int_t n=0;n<GetNumData();n++)
00591 NDF += GetData(n)->DefineBinsSize();
00592 NDF -= NumFreePars();
00593 }
00594
00595 return NDF;
00596 }
00597
00598 Double_t TGo4Fitter::DoCalculation() {
00599 return CalculateFCN(fiFitFunctionType);
00600 }
00601
00602 Int_t TGo4Fitter::DoNDFCalculation() {
00603 return CalculateNDF(0);
00604 }
00605
00606 void TGo4Fitter::RebuildAll(Bool_t ForceBuild) {
00607 for(Int_t i2=0;i2<GetNumModel();i2++)
00608 GetModel(i2)->RebuildShape(ForceBuild);
00609
00610 for(Int_t i1=0;i1<GetNumData();i1++) {
00611 TGo4FitData* data = GetData(i1);
00612 if (!data->BuffersAllocated()) continue;
00613
00614 Int_t size = data->GetBinsSize();
00615 Double_t* result = data->GetBinsResult();
00616 for (Int_t nbin=0;nbin<size;nbin++) result[nbin] = 0.;
00617
00618 for(Int_t i2=0;i2<GetNumModel();i2++) {
00619 TGo4FitModel *model = GetModel(i2);
00620 if (model->IsAssignTo(data->GetName()))
00621 model->AddModelToDataResult(data);
00622 }
00623 }
00624 }
00625
00626 void TGo4Fitter::EstimateAmplitudes(Int_t NumIters) {
00627 TGo4FitAmplEstimation abc("this",NumIters);
00628 abc.DoAction(this);
00629 }
00630
00631 void TGo4Fitter::AddAmplEstimation(Int_t NumIters) {
00632 AddAction(new TGo4FitAmplEstimation("AmplEstim",NumIters));
00633 }
00634
00635 void TGo4Fitter::AddStandardActions() {
00636 AddAmplEstimation();
00637 AddSimpleMinuit();
00638 }
00639
00640 void TGo4Fitter::FillSlotList(TSeqCollection* list) {
00641 TGo4FitterAbstract::FillSlotList(list);
00642 for(Int_t i=0;i<GetNumComp();i++)
00643 GetComp(i)->FillSlotList(list);
00644 }
00645
00646 Bool_t TGo4Fitter::ModelBuffersAllocated(TGo4FitModel* model) {
00647 return model==0 ? kFALSE : model->BuffersAllocated();
00648 }
00649
00650 Bool_t TGo4Fitter::DataBuffersAllocated(TGo4FitData* data) {
00651 return data==0 ? kFALSE : data->BuffersAllocated();
00652 }
00653
00654 Int_t TGo4Fitter::GetDataBinsSize(TGo4FitData* data) {
00655 return (data==0) ? 0 : data->GetBinsSize();
00656 }
00657
00658 Double_t* TGo4Fitter::GetDataBinsValues(TGo4FitData* data) {
00659 return (data==0) ? 0 : data->GetBinsValues();
00660 }
00661
00662 Double_t* TGo4Fitter::GetDataBinsDevs(TGo4FitData* data) {
00663 return (data==0) ? 0 : data->GetBinsDevs();
00664 }
00665
00666 Double_t* TGo4Fitter::GetDataBinsResult(TGo4FitData* data) {
00667 return (data==0) ? 0 : data->GetBinsResult();
00668 }
00669
00670 Double_t* TGo4Fitter::GetModelBinsValues(TGo4FitModel* model, const char* DataName) {
00671 return (model==0) ? 0 : model->GetModelBins(DataName);
00672 }
00673
00674 void TGo4Fitter::Print(Option_t* option) const {
00675 TString Opt(option);
00676 if (Opt=="Ampls") { PrintAmpls(); return; } else
00677 if (Opt=="Pars") { PrintPars(); return; } else
00678 if (Opt=="Results") { PrintResults(); return; } else
00679 if (Opt=="Lines") { PrintLines(); return; }
00680
00681 TGo4FitterAbstract::Print(option);
00682 cout << "Fitiing function type: ";
00683 switch (fiFitFunctionType) {
00684 case ff_chi_square : cout << "ff_chi_square" << endl; break;
00685 case ff_chi_Pearson : cout << "ff_chi_Pearson" << endl; break;
00686 case ff_chi_Neyman : cout << "ff_chi_Neyman" << endl; break;
00687 case ff_chi_gamma : cout << "ff_chi_gamma" << endl; break;
00688 case ff_ML_Poisson : cout << "ff_ML_Poisson" << endl; break;
00689 case ff_user : cout << "user defined" << endl; break;
00690 default: cout << "ff_least_squares" << endl;
00691 }
00692 cout << endl << " LIST OF DATA OBJECTS" << endl;
00693 fxDatas.Print(option);
00694 cout << endl << " LIST OF MODEL OBJECTS" << endl;
00695 fxModels.Print(option);
00696 }
00697
00698 Bool_t TGo4Fitter::CalculatesMomentums(const char* DataName, Bool_t UseRanges, Bool_t SubstractModels, Double_t& first, Double_t& second) {
00699 TGo4FitData* data = FindData(DataName);
00700 if (data==0) return kFALSE;
00701
00702 TGo4FitDataIter* iter = data->MakeIter();
00703 if (iter==0) return kFALSE;
00704
00705 Int_t size = iter->CountPoints(UseRanges);
00706 if (size==0) { delete iter; return kFALSE; }
00707
00708 TObjArray Models;
00709 if (SubstractModels)
00710 for(Int_t nm=0; nm<GetNumModel(); nm++)
00711 if (GetModel(nm)->IsAssignTo(DataName))
00712 Models.Add(GetModel(nm));
00713
00714 TArrayD Ampls(Models.GetLast()+1);
00715 for(Int_t n=0;n<=Models.GetLast();n++) {
00716 TGo4FitModel* model = (TGo4FitModel*) Models[n];
00717 model->BeforeEval(iter->ScalesSize());
00718 Ampls[n] = model->GetAmplValue() * model->GetRatioValueFor(DataName);
00719 }
00720
00721 TArrayD bins(size), scales(size);
00722
00723 Int_t pnt=0;
00724
00725 if (iter->Reset(UseRanges)) do {
00726 Double_t value = iter->Value();
00727 for(Int_t n=0;n<=Models.GetLast();n++) {
00728 TGo4FitModel* model = (TGo4FitModel*) Models[n];
00729 value -= Ampls[n] * model->EvaluateAtPoint(iter);
00730 }
00731 value = TMath::Abs(value);
00732 bins[pnt] = value;
00733 scales[pnt] = iter->x();
00734 pnt++;
00735 } while (iter->Next(UseRanges));
00736
00737 delete iter;
00738
00739 for(Int_t n=0;n<=Models.GetLast();n++) {
00740 TGo4FitModel* model = (TGo4FitModel*) Models[n];
00741 model->AfterEval();
00742 }
00743
00744 Int_t niter=0;
00745
00746 do {
00747 Double_t sum00=0.;
00748 Double_t sum11=0.;
00749 Double_t sum22=0.;
00750 for (Int_t pnt=0;pnt<size;pnt++)
00751 if ((bins[pnt]>0.) && ((niter==0) || (TMath::Abs(scales[pnt]-first)<second*2.))) {
00752 sum00 += bins[pnt];
00753 sum11 += bins[pnt]*scales[pnt];
00754 sum22 += bins[pnt]*scales[pnt]*scales[pnt];
00755 }
00756
00757 if (sum00>0.) {
00758 Double_t mid = sum11/sum00;
00759 Double_t dev = TMath::Sqrt(sum22/sum00-mid*mid);
00760
00761 if (niter>0)
00762 if ((dev/second>0.8) && (dev/second<1.2)) niter=10;
00763
00764 first = mid; second = dev;
00765
00766 } else niter=10;
00767
00768 } while (niter++<8);
00769
00770 return kTRUE;
00771 }
00772
00773 Double_t TGo4Fitter::CalculatesIntegral(const char* DataName, const char* ModelName, Bool_t onlycounts) {
00774 TGo4FitData* data = FindData(DataName);
00775 if (data==0) return 0.;
00776
00777 TGo4FitModel* model = ModelName!=0 ? FindModel(ModelName) : 0;
00778 if ((ModelName!=0) && (model==0)) return 0.;
00779
00780 TGo4FitDataIter* iter = data->MakeIter();
00781 if (iter==0) return 0.;
00782
00783 double sum = 0.;
00784 double ampl = 1.;
00785
00786 if (!iter->Reset(kTRUE)) {
00787 delete iter;
00788 return 0.;
00789 }
00790
00791 if (model!=0) {
00792 model->BeforeEval(iter->ScalesSize());
00793 ampl = model->GetAmplValue() * model->GetRatioValueFor(DataName);
00794 }
00795
00796 do {
00797 double dx = onlycounts ? 1. : iter->xWidths();
00798 double value = model==0 ? iter->Value() : model->EvaluateAtPoint(iter);
00799 sum += ampl*value*dx;
00800 } while (iter->Next(kTRUE));
00801
00802 if (model!=0)
00803 model->AfterEval();
00804
00805 delete iter;
00806
00807 return sum;
00808 }
00809
00810 Double_t TGo4Fitter::CalculatesModelIntegral(const char* ModelName, Bool_t OnlyCounts) {
00811 TGo4FitModel* model = FindModel(ModelName);
00812 if (model==0) return 0.;
00813 return CalculatesIntegral(model->AssignmentName(0), ModelName, OnlyCounts);
00814 }
00815
00816 TObject* TGo4Fitter::CreateDrawObject(const char* ResName, const char* DataName, Bool_t IsModel, const char* ModelName) {
00817 TGo4FitData* data = FindData(DataName);
00818 if (data==0) return 0;
00819
00820 TObjArray Models;
00821 if (IsModel) {
00822 TGo4FitModel* model = FindModel(ModelName);
00823 if (model) Models.Add(model); else {
00824 Int_t groupindex = -1;
00825
00826 if (ModelName!=0) {
00827 TString modelname(ModelName);
00828 if (modelname=="Background") groupindex = 0; else
00829 if (modelname.Index("Group",0,TString::kExact)==0) {
00830 modelname.Remove(0,5);
00831 char* err = 0;
00832 groupindex = strtol(modelname.Data(),&err,10);
00833 if (err && (*err!=0)) groupindex=-1;
00834 }
00835 }
00836
00837 for(Int_t nm=0; nm<GetNumModel(); nm++) {
00838 TGo4FitModel* model = GetModel(nm);
00839 if (model->IsAssignTo(DataName))
00840 if ((groupindex<0) || (model->GetGroupIndex()==groupindex))
00841 Models.Add(model);
00842 }
00843 }
00844 if (Models.GetLast()<0) return 0;
00845 }
00846
00847 TGo4FitDataIter* iter = data->MakeIter();
00848 if (iter==0) return 0;
00849
00850 if (!iter->Reset(kFALSE)) { delete iter; return 0; }
00851
00852 TH1* histo = 0;
00853 Int_t ndim = 0;
00854 TGraph* gr = 0;
00855 Bool_t UseRanges = kTRUE;
00856
00857
00858 if (iter->HasIndexes() && (iter->IndexesSize()==iter->ScalesSize()) && iter->HasWidths()) {
00859 histo = iter->CreateHistogram(ResName, kFALSE, !IsModel);
00860
00861 if (histo) {
00862 ndim = histo->GetDimension();
00863 UseRanges = Models.GetLast() >= 0;
00864 }
00865 } else {
00866 gr = iter->CreateGraph(ResName, kTRUE, !IsModel);
00867 UseRanges = kTRUE;
00868 }
00869
00870 if (((histo!=0) || (gr!=0)) && IsModel) {
00871 TArrayD Ampls(Models.GetLast()+1);
00872
00873 for(Int_t n=0;n<=Models.GetLast();n++) {
00874 TGo4FitModel* model = (TGo4FitModel*) Models[n];
00875 model->BeforeEval(iter->ScalesSize());
00876 Ampls[n] = model->GetAmplValue() * model->GetRatioValueFor(DataName);
00877 }
00878
00879 if (iter->Reset(UseRanges)) do {
00880 Double_t zn = 0;
00881 for(Int_t n=0;n<=Models.GetLast();n++) {
00882 TGo4FitModel* model = (TGo4FitModel*) Models[n];
00883 zn += Ampls[n] * model->EvaluateAtPoint(iter);
00884 }
00885 if (histo)
00886 switch(ndim) {
00887 case 1: histo->SetBinContent(iter->Indexes()[0]+1,zn); break;
00888 case 2: histo->SetBinContent(iter->Indexes()[0]+1,iter->Indexes()[1]+1,zn); break;
00889 case 3: histo->SetBinContent(iter->Indexes()[0]+1,iter->Indexes()[1]+1,iter->Indexes()[2]+1,zn); break;
00890 }
00891 if(gr) {
00892 (gr->GetX())[iter->Point()] = iter->x();
00893 (gr->GetY())[iter->Point()] = zn;
00894 }
00895
00896 } while (iter->Next(UseRanges));
00897
00898 for(Int_t n=0;n<=Models.GetLast();n++) {
00899 TGo4FitModel* model = (TGo4FitModel*) Models[n];
00900 model->AfterEval();
00901 }
00902 }
00903
00904 delete iter;
00905
00906 if (gr && IsModel)
00907 for(Int_t n1=0;n1<gr->GetN()-1;n1++)
00908 for(Int_t n2=n1+1;n2<gr->GetN();n2++)
00909 if ((gr->GetX())[n1]>(gr->GetX())[n2]) {
00910 Double_t xx = (gr->GetX())[n1];
00911 (gr->GetX())[n1] = (gr->GetX())[n2];
00912 (gr->GetX())[n2] = xx;
00913 Double_t yy = (gr->GetY())[n1];
00914 (gr->GetY())[n1] = (gr->GetY())[n2];
00915 (gr->GetY())[n2] = yy;
00916 }
00917
00918 TNamed* res = 0;
00919 if (histo) res = histo; else res = gr;
00920 if (res) {
00921 TString title;
00922 if (IsModel)
00923 if (ModelName) { title = "Draw of model "; title+=ModelName; }
00924 else { title = "Draw of full model of "; title+=DataName; }
00925 else { title = "Draw of data "; title+=DataName; }
00926 res->SetTitle(title.Data());
00927 }
00928
00929 return res;
00930 }
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 void TGo4Fitter::Draw(Option_t* option) {
00947 TString opt(option);
00948
00949 TCanvas *fCanvas = 0;
00950
00951 if ((opt.Length()>0) && (opt[0]=='#')) {
00952 opt.Remove(0,1);
00953 TString CanvasName;
00954 Int_t n=0;
00955 do {
00956 CanvasName = "Canvas";
00957 CanvasName+=n++;
00958 } while (gROOT->FindObject(CanvasName.Data()));
00959 fCanvas = new TCanvas(CanvasName,TString("Draw of fitter ")+GetName()+" "+opt,3);
00960 fCanvas->cd();
00961 }
00962
00963 Bool_t drawdata = kFALSE;
00964 TGo4FitData *selectdata = 0;
00965 TObjArray selectmodels;
00966 selectmodels.SetOwner(kTRUE);
00967 Bool_t drawcomp = kFALSE;
00968 Bool_t drawmodel = kFALSE;
00969
00970 if (opt=="*") { opt = ""; drawdata = kTRUE; }
00971
00972 while (opt.Length()>0) {
00973 Int_t len = opt.Index(",",0,TString::kExact);
00974
00975 if (len<0) len = opt.Length();
00976 if (len==0) break;
00977
00978 TString optpart(opt.Data(), len);
00979 while ((optpart.Length()>0) && (optpart[0]==' ')) optpart.Remove(0,1);
00980
00981 Bool_t find = kFALSE;
00982
00983 for(Int_t n=0;n<GetNumData();n++)
00984 if (optpart.Index(GetDataName(n),0,TString::kExact)==0) {
00985 selectdata = GetData(n);
00986 drawdata = kTRUE;
00987 drawmodel = kTRUE;
00988 find = kTRUE;
00989 optpart.Remove(0,strlen(GetDataName(n)));
00990 if (optpart=="*") drawcomp = kTRUE; else
00991 if (optpart=="-") drawmodel = kFALSE;
00992 break;
00993 }
00994
00995 if (!find) {
00996 selectmodels.Add(new TObjString(optpart));
00997 TGo4FitModel* model = FindModel(optpart.Data());
00998 if (model && (selectdata==0))
00999 for(Int_t n=0;n<GetNumData();n++)
01000 if (model->IsAssignTo(GetDataName(n)))
01001 selectdata = GetData(n);
01002 }
01003
01004 opt.Remove(0,len);
01005 if (opt.Length()>0) opt.Remove(0,1);
01006 }
01007
01008 if ((selectdata==0) && !drawdata)
01009 if (GetNumData()>0) selectdata = GetData(0);
01010
01011 MoveDrawObjectsToROOT();
01012 fxDrawObjs = new TObjArray();
01013
01014 for(Int_t n=0;n<GetNumData();n++) {
01015 TGo4FitData* data = GetData(n);
01016 if (selectdata && (data!=selectdata)) continue;
01017
01018 if (drawdata) {
01019 TObject* obj = CreateDrawObject(TString(data->GetName())+"_bins", data->GetName(), kFALSE);
01020
01021 TAttLine* line = dynamic_cast<TAttLine*> (obj);
01022 if (line) {
01023 line->SetLineColor(1);
01024 line->SetLineWidth(1);
01025 }
01026 if (obj) fxDrawObjs->Add(obj);
01027 }
01028
01029 if (drawmodel) {
01030 TObject* mobj = CreateDrawObject(TString(data->GetName())+"_fullmodel", data->GetName(), kTRUE);
01031
01032 TAttLine* line = dynamic_cast<TAttLine*> (mobj);
01033 if (line) {
01034 line->SetLineColor(4);
01035 line->SetLineWidth(2);
01036 }
01037 if (mobj) fxDrawObjs->Add(mobj);
01038 }
01039
01040 if (drawcomp)
01041 for(Int_t nmodel=0;nmodel<GetNumModel();nmodel++) {
01042 TGo4FitModel *model = GetModel(nmodel);
01043 if ( !model->IsAssignTo(data->GetName())) continue;
01044
01045 TObject* cobj = CreateDrawObject(TString(data->GetName())+"_"+model->GetName(), data->GetName(), kTRUE, model->GetName());
01046
01047 TAttLine* line = dynamic_cast<TAttLine*> (cobj);
01048 if (line) {
01049 line->SetLineColor(6);
01050 line->SetLineWidth(1);
01051 }
01052 if (cobj) fxDrawObjs->Add(cobj);
01053 }
01054
01055 for (Int_t n=0;n<=selectmodels.GetLast();n++) {
01056 TString name = ((TObjString*) (selectmodels[n]))->String();
01057
01058 TObject* cobj = CreateDrawObject(TString(data->GetName())+"_" +name, data->GetName(), kTRUE, name.Data());
01059
01060 TAttLine* line = dynamic_cast<TAttLine*> (cobj);
01061 if (line) {
01062 line->SetLineColor(6);
01063 line->SetLineWidth(1);
01064 }
01065 if (cobj) fxDrawObjs->Add(cobj);
01066 }
01067 }
01068
01069 if (fxDrawObjs->GetLast()==0) fxDrawObjs->At(0)->Draw(); else
01070 if (fxDrawObjs->GetLast()>0) {
01071 Bool_t allhisto = kTRUE;
01072 for (Int_t n=0;n<=fxDrawObjs->GetLast();n++)
01073 if (!(fxDrawObjs->At(n)->InheritsFrom(TH1::Class()))) allhisto = kFALSE;
01074 if (allhisto) {
01075 THStack* stack = new THStack(TString("Stack")+"_"+fxDrawObjs->At(0)->GetName(),fxDrawObjs->At(0)->GetName());
01076 for (Int_t n=0;n<=fxDrawObjs->GetLast();n++) stack->Add((TH1*)fxDrawObjs->At(n));
01077 fxDrawObjs->Clear();
01078 fxDrawObjs->Add(stack);
01079 stack->Draw("nostack");
01080 } else
01081 for (Int_t n=0;n<=fxDrawObjs->GetLast();n++)
01082 if (n==0) fxDrawObjs->At(n)->Draw("A*");
01083 else fxDrawObjs->At(n)->Draw("L");
01084 }
01085
01086 if (fCanvas!=0) fCanvas->Update();
01087 }
01088
01089 void TGo4Fitter::PrintAmpls() const {
01090 cout << endl << "*** LIST OF AMPLITUDES VALUE ***" << endl;
01091 for(Int_t n=0;n<GetNumComp();n++) {
01092 TGo4FitComponent* comp = ((TGo4Fitter*) this)->GetComp(n);
01093 if (comp->GetAmplPar() != 0)
01094 cout << " " << comp->GetAmplFullName() << " " << comp->GetAmplValue() << " " << comp->GetAmplError() << endl;
01095 }
01096 }
01097
01098 void TGo4Fitter::PrintLines() const {
01099 cout << endl << " *** LIST OF LINES PARAMETERS ***" << endl;
01100
01101 int MaxAxis = 0;
01102 for (Int_t n=0; n<GetNumModel();n++) {
01103 TGo4FitModel* m = ((TGo4Fitter*) this)->GetModel(n);
01104 if (m==0) continue;
01105 Double_t zn;
01106 for (int naxis=0;naxis<3;naxis++)
01107 if (m->GetPosition(naxis,zn) || m->GetWidth(naxis,zn)) MaxAxis = naxis;
01108 }
01109
01110 cout << setw(10) << "Name" << setw(12) << "Ampl";
01111 for(Int_t naxis=0;naxis<=MaxAxis;naxis++)
01112 cout << setw(11) << "Pos" << naxis << setw(11) << "Width" << naxis;
01113 cout << endl;
01114
01115 for (Int_t n=0; n<GetNumModel();n++) {
01116 TGo4FitModel* m = ((TGo4Fitter*) this)->GetModel(n);
01117 if (m==0) continue;
01118 cout << setw(10) << m->GetName() << setw(12) << m->GetAmplValue();
01119
01120 for (int naxis=0;naxis<=MaxAxis;naxis++) {
01121 Double_t pos, width;
01122 cout << setw(12);
01123 if (m->GetPosition(naxis,pos)) cout << pos;
01124 else cout << "---";
01125 cout << setw(12);
01126 if (m->GetWidth(naxis,width)) cout << width;
01127 else cout << "---";
01128 }
01129 cout << endl;
01130 }
01131 }
01132
01133
01134 void TGo4Fitter::ProvideLastDrawObjects(TObjArray& lst) {
01135 if (fxDrawObjs) {
01136 lst.AddAll(fxDrawObjs);
01137 delete fxDrawObjs;
01138 fxDrawObjs = 0;
01139 }
01140 }
01141
01142 void TGo4Fitter::MoveDrawObjectsToROOT() {
01143 if (fxDrawObjs) {
01144 for(Int_t n=0;n<=fxDrawObjs->GetLast();n++)
01145 gROOT->Add(fxDrawObjs->At(n));
01146 delete fxDrawObjs;
01147 fxDrawObjs = 0;
01148 }
01149 }
01150
01151 TString TGo4Fitter::FindNextName(const char* Head, Int_t start, Bool_t isModel) {
01152 TString(name);
01153 Int_t n = start;
01154 do {
01155 name=Head;
01156 name+=n++;
01157 } while (isModel ? FindModel(name.Data())!=0 : FindData(name.Data())!=0 );
01158 return name;
01159 }
01160
01161 void TGo4Fitter::Streamer(TBuffer& b) {
01162 if (b.IsReading()) {
01163 TGo4Fitter::Class()->ReadBuffer(b, this);
01164 CheckDuplicatesOnSlot();
01165 SetParsListChange();
01166 SetUpdateSlotList();
01167 } else {
01168 PrepareSlotsForWriting();
01169 TGo4Fitter::Class()->WriteBuffer(b, this);
01170 }
01171 }
01172
01173