Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/Go4Fit/TGo4Fitter.cxx

Go to the documentation of this file.
00001 //---------------------------------------------------------------
00002 //        Go4 Release Package v2.10-5 (build 21005) 
00003 //                      03-Nov-2005
00004 //---------------------------------------------------------------
00005 //       The GSI Online Offline Object Oriented (Go4) Project
00006 //       Experiment Data Processing at DVEE department, GSI
00007 //---------------------------------------------------------------
00008 //
00009 //Copyright (C) 2000- Gesellschaft f. Schwerionenforschung, GSI
00010 //                    Planckstr. 1, 64291 Darmstadt, Germany
00011 //Contact:            http://go4.gsi.de
00012 //----------------------------------------------------------------
00013 //This software can be used under the license agreements as stated
00014 //in Go4License.txt file which is part of the distribution.
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 /*   valid format for draw options
00860 
00861    "" - draw all datas
00862    "*" - draw all data with models
00863    "**" - draw all data with models and all components
00864    "DataName" - draw select data with model
00865    "DataName-" - draw select data without model
00866    "DataName*" - draw select data with model and components
00867    "DataName-, Background" - draw data and sum of components, belongs to background group (index=0)
00868    "DataName-, Group1" - draw data and sum of components, belongs to group 1
00869    "ModelName" - draw model component and correspondent data
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 //----------------------------END OF GO4 SOURCE FILE ---------------------

Generated on Tue Nov 8 10:55:57 2005 for Go4-v2.10-5 by doxygen1.2.15