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