TGo4FitterAbstract.cxx

Go to the documentation of this file.
00001 // $Id: TGo4FitterAbstract.cxx 478 2009-10-29 12:26:09Z linev $
00002 //-----------------------------------------------------------------------
00003 //       The GSI Online Offline Object Oriented (Go4) Project
00004 //         Experiment Data Processing at EE department, GSI
00005 //-----------------------------------------------------------------------
00006 // Copyright (C) 2000- GSI Helmholtzzentrum für Schwerionenforschung GmbH
00007 //                     Planckstr. 1, 64291 Darmstadt, Germany
00008 // Contact:            http://go4.gsi.de
00009 //-----------------------------------------------------------------------
00010 // This software can be used under the license agreements as stated
00011 // in Go4License.txt file which is part of the distribution.
00012 //-----------------------------------------------------------------------
00013 
00014 #include "TGo4FitterAbstract.h"
00015 
00016 #include "Riostream.h"
00017 
00018 #include "TArrayD.h"
00019 #include "TArrayI.h"
00020 #include "TVectorD.h"
00021 #include "TFormula.h"
00022 #include "TClass.h"
00023 #include "TString.h"
00024 #include "TObjString.h"
00025 #include "TVirtualPad.h"
00026 
00027 #include "TGo4FitterConfig.h"
00028 #include "TGo4FitDependency.h"
00029 #include "TGo4FitterAction.h"
00030 #include "TGo4FitterOutput.h"
00031 #include "TGo4FitMinuit.h"
00032 #include "TGo4FitParameter.h"
00033 
00034 
00035 TGo4FitterAbstract::TGo4FitterAbstract() :
00036    TGo4FitParsList(), TGo4FitSlotList(),
00037    fxActions(), fxResults(),
00038    fxCurrentConfig(0), fbParsChange(kTRUE),
00039    fbInitializationDone(kFALSE), fbNeedToFinalize(kFALSE), fbParsAsResults(kFALSE)
00040 {
00041 }
00042 
00043 TGo4FitterAbstract::TGo4FitterAbstract(const char * iName, const char * iTitle) :
00044    TGo4FitParsList(iName,iTitle,kFALSE), TGo4FitSlotList(),
00045    fxActions(), fxResults(),
00046    fxCurrentConfig(0), fbParsChange(kTRUE),
00047    fbInitializationDone(kFALSE), fbNeedToFinalize(kFALSE), fbParsAsResults(kFALSE)
00048 {
00049    fxActions.SetOwner(kTRUE);
00050 }
00051 
00052 TGo4FitterAbstract::~TGo4FitterAbstract()
00053 {
00054    if (fbNeedToFinalize) Finalize();
00055 }
00056 
00057 void TGo4FitterAbstract::Clear(Option_t* option)
00058 {
00059    TGo4FitParsList::Clear(option);
00060    DeleteActions();
00061 }
00062 
00063 void TGo4FitterAbstract::CollectAllPars()
00064 {
00065    ClearPars();
00066    if (fxCurrentConfig)
00067      fxCurrentConfig->GetParsNew().CollectParsTo(*this);
00068    fbParsChange = kFALSE;
00069 }
00070 
00071 void TGo4FitterAbstract::CopyParsValuesFrom(TGo4FitterAbstract* fitter)
00072 {
00073    if (fitter==0) return;
00074    fitter->CollectAllPars();
00075    CollectAllPars();
00076 
00077    for(Int_t n=0;n<NumPars();n++) {
00078       TGo4FitParameter* dest = Get(n);
00079       const TGo4FitParameter* src = fitter->FindPar(dest->GetFullName());
00080       if (src!=0) dest->SetValue(src->GetValue());
00081     }
00082 }
00083 
00084 Bool_t TGo4FitterAbstract::GetParFixed(const char* ParName)
00085 {
00086    Bool_t fixed = TGo4FitParsList::GetParFixed(ParName);
00087    if (fxCurrentConfig && !fixed)
00088       fixed = fxCurrentConfig->GetParFixed(ParName);
00089    return fixed;
00090 }
00091 
00092 Bool_t TGo4FitterAbstract::GetParRange(const char* ParName, Double_t& RangeMin, Double_t& RangeMax)
00093 {
00094    Bool_t get = kFALSE;
00095    if (fxCurrentConfig)
00096       get = fxCurrentConfig->GetParRange(ParName,RangeMin,RangeMax);
00097    if (!get) get = TGo4FitParsList::GetParRange(ParName,RangeMin,RangeMax);
00098    return get;
00099 }
00100 
00101 Bool_t TGo4FitterAbstract::GetParEpsilon(const char* ParName, Double_t& Epsilon)
00102 {
00103    Bool_t get = kFALSE;
00104    if (fxCurrentConfig)
00105       get = fxCurrentConfig->GetParEpsilon(ParName,Epsilon);
00106    if (!get) get = TGo4FitParsList::GetParEpsilon(ParName,Epsilon);
00107    return get;
00108 }
00109 
00110 
00111 Bool_t TGo4FitterAbstract::InitializeDependencies(TObjArray& Dependencies, Bool_t BlockPars, Bool_t DoInit)
00112 {
00113    for(Int_t i=0;i<=Dependencies.GetLast();i++) {
00114       TGo4FitDependency *dep = (TGo4FitDependency*) Dependencies[i];
00115 
00116      Int_t parindx = 0;
00117      TGo4FitParameter* deppar = 0;
00118      if (dep->GetParameter().Length()==0) parindx=-1; else {
00119        deppar = Find(dep->GetParameter().Data());
00120        if (deppar==0) { cout << "Error dependence parameter: " << dep->GetParameter().Data() << endl; return kFALSE; }
00121        parindx = GetParIndex(deppar);
00122      }
00123 
00124      if (dep->GetExpression().Length()>0) {
00125         TString formula(dep->GetExpression().Data());
00126         for(Int_t n=0;n<NumPars();n++) {
00127             if (n == parindx) continue;
00128             TString repl("[");
00129             repl+=n;
00130             repl+="]";
00131             formula.ReplaceAll(GetParFullName(n),repl);
00132         }
00133         TFormula* fx = new TFormula("test",formula.Data());
00134         Int_t err = fx->Compile(formula.Data());
00135         delete fx;
00136         if (err!=0) {
00137            cout << "Error in dependence: " << formula.Data() << "   code " << err << endl;
00138            return kFALSE;
00139         }
00140         if (DoInit) dep->Initialize(parindx, formula.Data());
00141 
00142      } else if (DoInit) dep->Initialize(parindx,0);
00143 
00144      if (BlockPars) deppar->SetBlocked();
00145   }
00146   return kTRUE;
00147 }
00148 
00149 void TGo4FitterAbstract::RunDependenciesList(TObjArray& Dependencies, Double_t* pars)
00150 {
00151    for(Int_t i=0;i<=Dependencies.GetLast();i++)
00152      ((TGo4FitDependency*) Dependencies[i]) -> ExecuteDependency(pars);
00153 }
00154 
00155 void TGo4FitterAbstract::FinalizeDependencies(TObjArray& Dependencies)
00156 {
00157    for(Int_t i=0;i<=Dependencies.GetLast();i++) {
00158      TGo4FitDependency *dep = (TGo4FitDependency*) Dependencies[i];
00159      dep->Finalize();
00160   }
00161 }
00162 
00163 void TGo4FitterAbstract::ExecuteDependencies(Double_t* pars)
00164 {
00165    if ((pars!=0) && (fxCurrentConfig!=0))
00166        RunDependenciesList(fxCurrentConfig->GetParsDepend(), pars );
00167 }
00168 
00169 Bool_t TGo4FitterAbstract::IsSuitableConfig(TGo4FitterConfig* Config)
00170 {
00171    if (Config==0) return kFALSE;
00172    Bool_t res = kTRUE;
00173    try {
00174      fxCurrentConfig=Config;
00175      CollectAllPars();
00176      res = InitializeDependencies(Config->GetParsInit(), kFALSE,kFALSE);
00177      res = res && InitializeDependencies(Config->GetParsDepend(), kFALSE,kFALSE);
00178      res = res && InitializeDependencies(Config->GetResults(), kFALSE,kFALSE);
00179 
00180      fxCurrentConfig=0;
00181      CollectAllPars();
00182 
00183    } catch(...) {
00184       fxCurrentConfig=0;
00185       CollectAllPars();
00186       throw;
00187    }
00188 
00189    return res;
00190 }
00191 
00192 Bool_t TGo4FitterAbstract::ApplyConfig(TGo4FitterConfig* Config)
00193 {
00194    if (fxCurrentConfig!=0) {
00195       FinalizeDependencies(fxCurrentConfig->GetParsInit());
00196       FinalizeDependencies(fxCurrentConfig->GetParsDepend());
00197       FinalizeDependencies(fxCurrentConfig->GetResults());
00198    }
00199 
00200    fxCurrentConfig = Config;
00201    CollectAllPars();
00202 
00203    Bool_t res = kTRUE;
00204 
00205    if (fxCurrentConfig) {
00206       res = res && InitializeDependencies(fxCurrentConfig->GetParsInit(), kFALSE, kTRUE);
00207       res = res && InitializeDependencies(fxCurrentConfig->GetParsDepend(), kTRUE, kTRUE);
00208       res = res && InitializeDependencies(fxCurrentConfig->GetResults(), kFALSE, kTRUE);
00209 
00210       if (res) {
00211          TArrayD pars(NumPars());
00212          GetParsValues(pars.GetArray());
00213          RunDependenciesList(fxCurrentConfig->GetParsInit(), pars.GetArray() );
00214          SetParsValues(pars.GetArray());
00215       }
00216    }
00217 
00218    if (!res) {
00219       FinalizeDependencies(fxCurrentConfig->GetParsInit());
00220       FinalizeDependencies(fxCurrentConfig->GetParsDepend());
00221       FinalizeDependencies(fxCurrentConfig->GetResults());
00222       fxCurrentConfig = 0;
00223    }
00224 
00225    return res;
00226 }
00227 
00228 Bool_t TGo4FitterAbstract::Initialize()
00229 {
00230    if (fbNeedToFinalize) Finalize();
00231    fbInitializationDone=kFALSE;
00232 
00233    if (!CheckObjects()) return kFALSE;
00234 
00235    fbNeedToFinalize = kTRUE;
00236 
00237    CollectAllPars();
00238 
00239    ClearParsBlocking();
00240 
00241    if (!InitFitterData()) return kFALSE;
00242 
00243    fbInitializationDone=kTRUE;
00244 
00245    return kTRUE;
00246 }
00247 
00248 Double_t TGo4FitterAbstract::CalculateFitFunction(Double_t* pars)
00249 {
00250    if (pars!=0) {
00251      ExecuteDependencies(pars);
00252      SetParsValues(pars);
00253    }
00254 
00255    return DoCalculation();
00256 }
00257 
00258 void TGo4FitterAbstract::Finalize()
00259 {
00260    Double_t FF = DoCalculation();
00261    Int_t NDF = DoNDFCalculation();
00262 
00263    FinalizeFitterData();
00264 
00265    if ((fxCurrentConfig!=0) && (fxCurrentConfig->GetResults().GetLast()>=0)) {
00266       TArrayD pars(NumPars());
00267       GetParsValues(pars.GetArray());
00268       fxResults.Set(fxCurrentConfig->GetResults().GetLast()+3);
00269 
00270       for(Int_t i=0;i<=fxCurrentConfig->GetResults().GetLast();i++) {
00271         TGo4FitDependency *res = (TGo4FitDependency*) (fxCurrentConfig->GetResults())[i];
00272         fxResults[i] = res->ExecuteDependency(pars.GetArray());
00273       }
00274    } else {
00275      fxResults.Set(NumPars()+2);
00276      GetParsValues(fxResults.GetArray());
00277    }
00278 
00279    fxResults[fxResults.GetSize()-2] = FF;
00280    fxResults[fxResults.GetSize()-1] = NDF;
00281 
00282    if (fxCurrentConfig!=0)
00283      ApplyConfig(0);
00284 
00285    fbNeedToFinalize = kFALSE;
00286    fbInitializationDone=kFALSE;
00287 }
00288 
00289 void TGo4FitterAbstract::AddAction(TGo4FitterAction* Action)
00290 {
00291    fxActions.Add(Action);
00292 }
00293 
00294 void TGo4FitterAbstract::AddActionAt(TGo4FitterAction* Action, Int_t indx)
00295 {
00296    fxActions.AddAt(Action, indx);
00297 }
00298 
00299 TGo4FitterAction* TGo4FitterAbstract::GetAction(Int_t num)
00300 {
00301   if ((num<0) || (num>fxActions.GetLast())) return 0;
00302   return dynamic_cast<TGo4FitterAction*> (fxActions[num]);
00303 }
00304 
00305 void TGo4FitterAbstract::DeleteAction(TGo4FitterAction* action)
00306 {
00307   if (action==0) return;
00308   if (fxActions.IndexOf(action)>=0) {
00309     fxActions.Remove(action);
00310     fxActions.Compress();
00311   }
00312   delete action;
00313 }
00314 
00315 void TGo4FitterAbstract::ReplaceAction(TGo4FitterAction* action, Int_t dir)
00316 {
00317    Int_t indx = fxActions.IndexOf(action);
00318    if ((action==0) || (indx<0)) return;
00319    Int_t newindx = indx+dir;
00320    if ((newindx>=0) && (newindx<=fxActions.GetLast()) && (newindx!=indx)) {
00321       fxActions[indx] = fxActions[newindx];
00322       fxActions[newindx] = action;
00323    }
00324 }
00325 
00326 void TGo4FitterAbstract::DoActions(Bool_t AllowFitterChange, TObjArray* Actions)
00327 {
00328   if (Actions==0) Actions = &fxActions;
00329 
00330   Bool_t need = kFALSE;
00331   for(Int_t n=0;n<=Actions->GetLast();n++) {
00332      TGo4FitterAction* action = dynamic_cast<TGo4FitterAction*> (Actions->At(n));
00333      if (action)
00334        need = need || action->NeedBuffers();
00335   }
00336   if (need)
00337     if (!Initialize()) return;
00338 
00339   for(Int_t n=0;n<=Actions->GetLast();n++) {
00340      TGo4FitterAction* action = dynamic_cast<TGo4FitterAction*> (Actions->At(n));
00341      if (action==0) continue;
00342      if (!AllowFitterChange && action->CanChangeFitter()) continue;
00343 
00344      action->DoAction(this);
00345      CheckParsListChanging();
00346   }
00347 
00348   if (need) Finalize();
00349 }
00350 
00351 void TGo4FitterAbstract::DoAction(TGo4FitterAction* Action)
00352 {
00353    if (Action==0) return;
00354 
00355    Bool_t need = Action->NeedBuffers();
00356 
00357    if (need)
00358      if (!Initialize()) return;
00359 
00360    Action->DoAction(this);
00361 
00362    if (need) Finalize();
00363 }
00364 
00365 void TGo4FitterAbstract::DoAction(Int_t indx)
00366 {
00367    DoAction(GetAction(indx));
00368 }
00369 
00370 TObjArray* TGo4FitterAbstract::ProcessObjects(TObjArray* objs, Bool_t CloneFitter, Bool_t OnlyRequired, TObjArray* rownames, TObjArray* colnames)
00371 {
00372   if ((objs==0) || (objs->GetLast()<0)) return 0;
00373 
00374   if (NumSlots()<=0) return 0;
00375 
00376   TArrayI use(NumSlots()); use.Reset(-1);
00377 
00378   Int_t numuse = 0;
00379   for (Int_t n=0;n<NumSlots();n++) {
00380      TGo4FitSlot* slot = GetSlot(n);
00381      if (slot==0) return 0;
00382      if (slot->GetObject()==0)
00383        if (slot->IsRequired() || !OnlyRequired) use[numuse++] = n;
00384   }
00385 
00386   if ((numuse==0) || ((objs->GetLast()+1) % numuse != 0)) return 0;
00387 
00388   Int_t nuse = 0;
00389   for (Int_t nobj=0;nobj<=objs->GetLast();nobj++) {
00390      TObject* obj = objs->At(nobj);
00391      if (obj==0) {
00392        cout << "Empty object in list" << endl;
00393        return 0;
00394      }
00395      TGo4FitSlot* slot = GetSlot(use[nuse++]);
00396      if (nuse==numuse) nuse=0;
00397      if (!slot->IsSuitable(obj)) {
00398         cout << "Object " << obj->GetName() << " of class " << obj->ClassName() <<
00399                 " noncompatible with " << slot->GetClass()->GetName() << endl;
00400         return 0;
00401      }
00402   }
00403 
00404   TObjArray* res = new TObjArray((objs->GetLast()+1) / numuse);
00405   res->SetOwner(kTRUE);
00406   TGo4FitterAbstract* resf = 0;
00407 
00408   if (rownames!=0) { rownames->Clear(); rownames->SetOwner(kTRUE); }
00409   if (colnames!=0) { colnames->Clear(); colnames->SetOwner(kTRUE); }
00410 
00411   if (CloneFitter) {
00412 
00413     Int_t nobj = 0;
00414 
00415     do {
00416        TGo4FitterAbstract* newfitter = dynamic_cast<TGo4FitterAbstract*> (Clone());
00417        if (newfitter==0) break;
00418        res->Add(newfitter);
00419 
00420        if (newfitter->NumSlots()!=NumSlots()) break;
00421 
00422        nuse = 0;
00423        while(nuse<numuse) {
00424           TGo4FitSlot* slot = newfitter->GetSlot(use[nuse++]);
00425           slot->SetObject(objs->At(nobj), kFALSE);
00426           if (nuse==1) newfitter->SetName(objs->At(nobj)->GetName());
00427           if ((nuse==1) && (colnames!=0)) colnames->Add(new TObjString(objs->At(nobj)->GetName()));
00428           nobj++;
00429        }
00430 
00431        newfitter->DoActions();
00432 
00433        resf = newfitter;
00434 
00435     } while (nobj<=objs->GetLast());
00436 
00437 
00438   } else {
00439 
00440     MemorizePars();
00441 
00442     Int_t nobj = 0;
00443 
00444     do {
00445 
00446        nuse = 0;
00447        while(nuse<numuse) {
00448          TGo4FitSlot* slot = GetSlot(use[nuse++]);
00449          slot->SetObject(objs->At(nobj), kFALSE);
00450          if ((nuse==1) && (colnames!=0)) colnames->Add(new TObjString(objs->At(nobj)->GetName()));
00451          nobj++;
00452        }
00453 
00454        RememberPars();
00455 
00456        DoActions();
00457 
00458        res->Add(new TVectorD(0, GetNumResults()-1, GetResults()->GetArray()));
00459 
00460     } while (nobj<=objs->GetLast());
00461 
00462     RememberPars();
00463 
00464     resf = this;
00465   }
00466 
00467   if ((rownames!=0) && (resf!=0)){
00468     if (resf->IsParsAsResults())
00469         for(Int_t n=0;n<resf->NumPars();n++) rownames->Add(new TObjString(resf->GetParFullName(n)));
00470     else
00471       for(Int_t n=0;n<resf->GetNumResults();n++) {
00472         TString rname("Result");
00473         rname+=n;
00474         rownames->Add(new TObjString(rname));
00475       }
00476   }
00477   nuse = 0;
00478   while(nuse<numuse) {
00479     TGo4FitSlot* slot = GetSlot(use[nuse++]);
00480     slot->SetObject(0, kFALSE);
00481   }
00482 
00483   return res;
00484 }
00485 
00486 void TGo4FitterAbstract::AddSimpleMinuit()
00487 {
00488    TGo4FitMinuit* fMinuit = new TGo4FitMinuit("Minuit");
00489    fMinuit->AddCommand("MIGRAD 500 1");
00490    AddAction(fMinuit);
00491 }
00492 
00493 TGo4FitterOutput*  TGo4FitterAbstract::AddOutputAction(const char* Action, const char* Option)
00494 {
00495    TGo4FitterOutput* act = new  TGo4FitterOutput(Action,Option);
00496    AddAction(act);
00497    return act;
00498 }
00499 
00500 void TGo4FitterAbstract::DeleteOutputActions()
00501 {
00502    for(Int_t n=0;n<=fxActions.GetLast();n++) {
00503      TGo4FitterOutput* action = dynamic_cast<TGo4FitterOutput*> (fxActions[n]);
00504      if (action) { fxActions.Remove(action); delete action; }
00505    }
00506    fxActions.Compress();
00507 }
00508 
00509 Int_t TGo4FitterAbstract::NeedPadsNumber()
00510 {
00511    Int_t res = 0;
00512    for(Int_t n=0;n<GetNumActions(); n++) {
00513       TGo4FitterOutput* act = dynamic_cast<TGo4FitterOutput*>  (GetAction(n));
00514       if (act && act->NeedPad()) res++;
00515    }
00516    return res;
00517 }
00518 
00519 void TGo4FitterAbstract::SetPad(Int_t indx, TVirtualPad* pad)
00520 {
00521    Int_t i = 1; // puds numbering starts from 1
00522    for(Int_t n=0;n<GetNumActions(); n++) {
00523       TGo4FitterOutput* act = dynamic_cast<TGo4FitterOutput*>  (GetAction(n));
00524       if (act && act->NeedPad())  {
00525          if (i==indx) { act->SetPad(pad); return; }
00526          i++;
00527       }
00528    }
00529 }
00530 
00531 Double_t TGo4FitterAbstract::GetResultValue(Int_t n) const
00532 {
00533   if ((n>=0) && (n<GetNumResults())) return fxResults[n];
00534                                 else return 0.;
00535 }
00536 
00537 Double_t TGo4FitterAbstract::GetResultFF() const
00538 {
00539   if (fxResults.GetSize()>1) return fxResults[fxResults.GetSize()-2];
00540                         else return 0;
00541 }
00542 
00543 Int_t TGo4FitterAbstract::GetResultNDF() const
00544 {
00545   if (fxResults.GetSize()>1) return Int_t(fxResults[fxResults.GetSize()-1]);
00546                         else return 0;
00547 }
00548 
00549 void TGo4FitterAbstract::PrintResults() const
00550 {
00551    cout << endl << "*** LIST OF RESULT VALUE ***" << endl;
00552    cout << "    Fit function = " << GetResultFF() << endl;
00553    cout << "    NDF = " << GetResultNDF() << endl;
00554    for(Int_t n=0;n<GetNumResults();n++)
00555      cout << "    Res " << n << " =  " << GetResultValue(n) << endl;
00556 }
00557 
00558 void TGo4FitterAbstract::Print(Option_t* option) const
00559 {
00560    cout << endl << "********** THIS IS PRINTOUT OF FITTER OBJECT **********" << endl;
00561    TGo4FitNamed::Print(option);
00562    TGo4FitParsList::Print(option);
00563    if (fxActions.GetLast()>=0) {
00564       cout << "Actions list: " << endl;
00565       fxActions.Print(option);
00566    }
00567 }
00568 
00569 void TGo4FitterAbstract::Streamer(TBuffer& b)
00570 {
00571    if (b.IsReading()) {
00572      TGo4FitterAbstract::Class()->ReadBuffer(b, this);
00573    } else {
00574      PrepareSlotsForWriting();
00575      TGo4FitterAbstract::Class()->WriteBuffer(b, this);
00576    }
00577 }

Generated on Thu Oct 28 15:54:12 2010 for Go4-Fitpackagev4.04-2 by  doxygen 1.5.1