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

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

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