Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

TGo4Fitter.cxx

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

Generated on Fri Nov 28 12:59:13 2008 for Go4-v3.04-1 by  doxygen 1.4.2