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