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

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

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