GSI Object Oriented Online Offline (Go4)  GO4-5.3.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4FitterAbstract.cxx
Go to the documentation of this file.
1 // $Id: TGo4FitterAbstract.cxx 1844 2016-02-12 12:42:48Z adamczew $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum für Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4FitterAbstract.h"
15 
16 #include "Riostream.h"
17 #include "TBuffer.h"
18 #include "TArrayD.h"
19 #include "TArrayI.h"
20 #include "TVectorD.h"
21 #include "TFormula.h"
22 #include "TClass.h"
23 #include "TString.h"
24 #include "TObjString.h"
25 #include "TVirtualPad.h"
26 
27 #include "TGo4FitterConfig.h"
28 #include "TGo4FitDependency.h"
29 #include "TGo4FitterAction.h"
30 #include "TGo4FitterOutput.h"
31 #include "TGo4FitMinuit.h"
32 #include "TGo4FitParameter.h"
33 
34 
37  fxActions(), fxResults(),
38  fxCurrentConfig(0), fbParsChange(kTRUE),
39  fbInitializationDone(kFALSE), fbNeedToFinalize(kFALSE), fbParsAsResults(kFALSE)
40 {
41 }
42 
43 TGo4FitterAbstract::TGo4FitterAbstract(const char * iName, const char * iTitle) :
44  TGo4FitParsList(iName,iTitle,kFALSE), TGo4FitSlotList(),
45  fxActions(), fxResults(),
46  fxCurrentConfig(0), fbParsChange(kTRUE),
47  fbInitializationDone(kFALSE), fbNeedToFinalize(kFALSE), fbParsAsResults(kFALSE)
48 {
49  fxActions.SetOwner(kTRUE);
50 }
51 
53 {
55 }
56 
57 void TGo4FitterAbstract::Clear(Option_t* option)
58 {
59  TGo4FitParsList::Clear(option);
60  DeleteActions();
61 }
62 
64 {
65  ClearPars();
66  if (fxCurrentConfig)
68  fbParsChange = kFALSE;
69 }
70 
72 {
73  if (fitter==0) return;
74  fitter->CollectAllPars();
76 
77  for(Int_t n=0;n<NumPars();n++) {
78  TGo4FitParameter* dest = Get(n);
79  const TGo4FitParameter* src = fitter->FindPar(dest->GetFullName());
80  if (src!=0) dest->SetValue(src->GetValue());
81  }
82 }
83 
84 Bool_t TGo4FitterAbstract::GetParFixed(const char* ParName)
85 {
86  Bool_t fixed = TGo4FitParsList::GetParFixed(ParName);
87  if (fxCurrentConfig && !fixed)
88  fixed = fxCurrentConfig->GetParFixed(ParName);
89  return fixed;
90 }
91 
92 Bool_t TGo4FitterAbstract::GetParRange(const char* ParName, Double_t& RangeMin, Double_t& RangeMax)
93 {
94  Bool_t get = kFALSE;
95  if (fxCurrentConfig)
96  get = fxCurrentConfig->GetParRange(ParName,RangeMin,RangeMax);
97  if (!get) get = TGo4FitParsList::GetParRange(ParName,RangeMin,RangeMax);
98  return get;
99 }
100 
101 Bool_t TGo4FitterAbstract::GetParEpsilon(const char* ParName, Double_t& Epsilon)
102 {
103  Bool_t get = kFALSE;
104  if (fxCurrentConfig)
105  get = fxCurrentConfig->GetParEpsilon(ParName,Epsilon);
106  if (!get) get = TGo4FitParsList::GetParEpsilon(ParName,Epsilon);
107  return get;
108 }
109 
110 
111 Bool_t TGo4FitterAbstract::InitializeDependencies(TObjArray& Dependencies, Bool_t BlockPars, Bool_t DoInit)
112 {
113  for(Int_t i=0;i<=Dependencies.GetLast();i++) {
114  TGo4FitDependency *dep = (TGo4FitDependency*) Dependencies[i];
115 
116  Int_t parindx = 0;
117  TGo4FitParameter* deppar = 0;
118  if (dep->GetParameter().Length()==0) parindx=-1; else {
119  deppar = Find(dep->GetParameter().Data());
120  if (deppar==0) { std::cout << "Error dependence parameter: " << dep->GetParameter().Data() << std::endl; return kFALSE; }
121  parindx = GetParIndex(deppar);
122  }
123 
124  if (dep->GetExpression().Length()>0) {
125  TString formula(dep->GetExpression().Data());
126  for(Int_t n=0;n<NumPars();n++) {
127  if (n == parindx) continue;
128  TString repl("[");
129  repl+=n;
130  repl+="]";
131  formula.ReplaceAll(GetParFullName(n),repl);
132  }
133  TFormula* fx = new TFormula("test",formula.Data());
134  Int_t err = fx->Compile(formula.Data());
135  delete fx;
136  if (err!=0) {
137  std::cout << "Error in dependence: " << formula.Data() << " code " << err << std::endl;
138  return kFALSE;
139  }
140  if (DoInit) dep->Initialize(parindx, formula.Data());
141 
142  } else if (DoInit) dep->Initialize(parindx,0);
143 
144  if (BlockPars) deppar->SetBlocked();
145  }
146  return kTRUE;
147 }
148 
149 void TGo4FitterAbstract::RunDependenciesList(TObjArray& Dependencies, Double_t* pars)
150 {
151  for(Int_t i=0;i<=Dependencies.GetLast();i++)
152  ((TGo4FitDependency*) Dependencies[i]) -> ExecuteDependency(pars);
153 }
154 
155 void TGo4FitterAbstract::FinalizeDependencies(TObjArray& Dependencies)
156 {
157  for(Int_t i=0;i<=Dependencies.GetLast();i++) {
158  TGo4FitDependency *dep = (TGo4FitDependency*) Dependencies[i];
159  dep->Finalize();
160  }
161 }
162 
164 {
165  if ((pars!=0) && (fxCurrentConfig!=0))
167 }
168 
170 {
171  if (Config==0) return kFALSE;
172  Bool_t res = kTRUE;
173  try {
174  fxCurrentConfig=Config;
175  CollectAllPars();
176  res = InitializeDependencies(Config->GetParsInit(), kFALSE,kFALSE);
177  res = res && InitializeDependencies(Config->GetParsDepend(), kFALSE,kFALSE);
178  res = res && InitializeDependencies(Config->GetResults(), kFALSE,kFALSE);
179 
180  fxCurrentConfig=0;
181  CollectAllPars();
182 
183  } catch(...) {
184  fxCurrentConfig=0;
185  CollectAllPars();
186  throw;
187  }
188 
189  return res;
190 }
191 
193 {
194  if (fxCurrentConfig!=0) {
198  }
199 
200  fxCurrentConfig = Config;
201  CollectAllPars();
202 
203  Bool_t res = kTRUE;
204 
205  if (fxCurrentConfig) {
206  res = res && InitializeDependencies(fxCurrentConfig->GetParsInit(), kFALSE, kTRUE);
207  res = res && InitializeDependencies(fxCurrentConfig->GetParsDepend(), kTRUE, kTRUE);
208  res = res && InitializeDependencies(fxCurrentConfig->GetResults(), kFALSE, kTRUE);
209 
210  if (res) {
211  TArrayD pars(NumPars());
212  GetParsValues(pars.GetArray());
213  RunDependenciesList(fxCurrentConfig->GetParsInit(), pars.GetArray() );
214  SetParsValues(pars.GetArray());
215  }
216  }
217 
218  if (!res) {
222  fxCurrentConfig = 0;
223  }
224 
225  return res;
226 }
227 
229 {
230  if (fbNeedToFinalize) Finalize();
231  fbInitializationDone = kFALSE;
232 
233  if (!CheckObjects()) return kFALSE;
234 
235  fbNeedToFinalize = kTRUE;
236 
237  CollectAllPars();
238 
240 
241  if (!InitFitterData()) return kFALSE;
242 
243  fbInitializationDone = kTRUE;
244 
245  return kTRUE;
246 }
247 
249 {
250  if (pars!=0) {
251  ExecuteDependencies(pars);
252  SetParsValues(pars);
253  }
254 
255  return DoCalculation();
256 }
257 
259 {
260  Double_t FF = DoCalculation();
261  Int_t NDF = DoNDFCalculation();
262 
264 
265  if ((fxCurrentConfig!=0) && (fxCurrentConfig->GetResults().GetLast()>=0)) {
266  TArrayD pars(NumPars());
267  GetParsValues(pars.GetArray());
268  fxResults.Set(fxCurrentConfig->GetResults().GetLast()+3);
269 
270  for(Int_t i=0;i<=fxCurrentConfig->GetResults().GetLast();i++) {
272  fxResults[i] = res->ExecuteDependency(pars.GetArray());
273  }
274  } else {
275  fxResults.Set(NumPars()+2);
276  GetParsValues(fxResults.GetArray());
277  }
278 
279  fxResults.SetAt(FF, fxResults.GetSize()-2);
280  fxResults.SetAt(NDF, fxResults.GetSize()-1);
281 
282  if (fxCurrentConfig!=0)
283  ApplyConfig(0);
284 
285  fbNeedToFinalize = kFALSE;
286  fbInitializationDone = kFALSE;
287 }
288 
290 {
291  fxActions.Add(Action);
292 }
293 
295 {
296  fxActions.AddAt(Action, indx);
297 }
298 
300 {
301  if ((num<0) || (num>fxActions.GetLast())) return 0;
302  return dynamic_cast<TGo4FitterAction*> (fxActions[num]);
303 }
304 
306 {
307  if (action==0) return;
308  if (fxActions.IndexOf(action)>=0) {
309  fxActions.Remove(action);
310  fxActions.Compress();
311  }
312  delete action;
313 }
314 
316 {
317  Int_t indx = fxActions.IndexOf(action);
318  if ((action==0) || (indx<0)) return;
319  Int_t newindx = indx+dir;
320  if ((newindx>=0) && (newindx<=fxActions.GetLast()) && (newindx!=indx)) {
321  fxActions[indx] = fxActions[newindx];
322  fxActions[newindx] = action;
323  }
324 }
325 
326 void TGo4FitterAbstract::DoActions(Bool_t AllowFitterChange, TObjArray* Actions)
327 {
328  if (Actions==0) Actions = &fxActions;
329 
330  Bool_t need = kFALSE;
331  for(Int_t n=0;n<=Actions->GetLast();n++) {
332  TGo4FitterAction* action = dynamic_cast<TGo4FitterAction*> (Actions->At(n));
333  if (action)
334  need = need || action->NeedBuffers();
335  }
336 
337  if (need)
338  if (!Initialize()) return;
339 
340  for(Int_t n=0;n<=Actions->GetLast();n++) {
341  TGo4FitterAction* action = dynamic_cast<TGo4FitterAction*> (Actions->At(n));
342  if (action==0) continue;
343  if (!AllowFitterChange && action->CanChangeFitter()) continue;
344 
345  action->DoAction(this);
347  }
348 
349  if (need) Finalize();
350 }
351 
353 {
354  if (Action==0) return;
355 
356  Bool_t need = Action->NeedBuffers();
357 
358  if (need)
359  if (!Initialize()) return;
360 
361  Action->DoAction(this);
362 
363  if (need) Finalize();
364 }
365 
367 {
368  DoAction(GetAction(indx));
369 }
370 
371 TObjArray* TGo4FitterAbstract::ProcessObjects(TObjArray* objs, Bool_t CloneFitter, Bool_t OnlyRequired, TObjArray* rownames, TObjArray* colnames)
372 {
373  if ((objs==0) || (objs->GetLast()<0)) return 0;
374 
375  if (NumSlots()<=0) return 0;
376 
377  TArrayI use(NumSlots()); use.Reset(-1);
378 
379  Int_t numuse = 0;
380  for (Int_t n=0;n<NumSlots();n++) {
381  TGo4FitSlot* slot = GetSlot(n);
382  if (slot==0) return 0;
383  if (slot->GetObject()==0)
384  if (slot->IsRequired() || !OnlyRequired) use[numuse++] = n;
385  }
386 
387  if ((numuse==0) || ((objs->GetLast()+1) % numuse != 0)) return 0;
388 
389  Int_t nuse = 0;
390  for (Int_t nobj=0;nobj<=objs->GetLast();nobj++) {
391  TObject* obj = objs->At(nobj);
392  if (obj==0) {
393  std::cout << "Empty object in list" << std::endl;
394  return 0;
395  }
396  TGo4FitSlot* slot = GetSlot(use[nuse++]);
397  if (nuse==numuse) nuse=0;
398  if (!slot->IsSuitable(obj)) {
399  std::cout << "Object " << obj->GetName() << " of class " << obj->ClassName() <<
400  " noncompatible with " << slot->GetClass()->GetName() << std::endl;
401  return 0;
402  }
403  }
404 
405  TObjArray* res = new TObjArray((objs->GetLast()+1) / numuse);
406  res->SetOwner(kTRUE);
407  TGo4FitterAbstract* resf = 0;
408 
409  if (rownames!=0) { rownames->Clear(); rownames->SetOwner(kTRUE); }
410  if (colnames!=0) { colnames->Clear(); colnames->SetOwner(kTRUE); }
411 
412  if (CloneFitter) {
413 
414  Int_t nobj = 0;
415 
416  do {
417  TGo4FitterAbstract* newfitter = dynamic_cast<TGo4FitterAbstract*> (Clone());
418  if (newfitter==0) break;
419  res->Add(newfitter);
420 
421  if (newfitter->NumSlots()!=NumSlots()) break;
422 
423  nuse = 0;
424  while(nuse<numuse) {
425  TGo4FitSlot* slot = newfitter->GetSlot(use[nuse++]);
426  slot->SetObject(objs->At(nobj), kFALSE);
427  if (nuse==1) newfitter->SetName(objs->At(nobj)->GetName());
428  if ((nuse==1) && (colnames!=0)) colnames->Add(new TObjString(objs->At(nobj)->GetName()));
429  nobj++;
430  }
431 
432  newfitter->DoActions();
433 
434  resf = newfitter;
435 
436  } while (nobj<=objs->GetLast());
437 
438 
439  } else {
440 
441  MemorizePars();
442 
443  Int_t nobj = 0;
444 
445  do {
446 
447  nuse = 0;
448  while(nuse<numuse) {
449  TGo4FitSlot* slot = GetSlot(use[nuse++]);
450  slot->SetObject(objs->At(nobj), kFALSE);
451  if ((nuse==1) && (colnames!=0)) colnames->Add(new TObjString(objs->At(nobj)->GetName()));
452  nobj++;
453  }
454 
455  RememberPars();
456 
457  DoActions();
458 
459  res->Add(new TVectorD(0, GetNumResults()-1, GetResults()->GetArray()));
460 
461  } while (nobj<=objs->GetLast());
462 
463  RememberPars();
464 
465  resf = this;
466  }
467 
468  if ((rownames!=0) && (resf!=0)){
469  if (resf->IsParsAsResults())
470  for(Int_t n=0;n<resf->NumPars();n++) rownames->Add(new TObjString(resf->GetParFullName(n)));
471  else
472  for(Int_t n=0;n<resf->GetNumResults();n++) {
473  TString rname("Result");
474  rname+=n;
475  rownames->Add(new TObjString(rname));
476  }
477  }
478  nuse = 0;
479  while(nuse<numuse) {
480  TGo4FitSlot* slot = GetSlot(use[nuse++]);
481  slot->SetObject(0, kFALSE);
482  }
483 
484  return res;
485 }
486 
488 {
489  TGo4FitMinuit* fMinuit = new TGo4FitMinuit("Minuit");
490  fMinuit->AddCommand("MIGRAD 500 1");
491  AddAction(fMinuit);
492 }
493 
494 TGo4FitterOutput* TGo4FitterAbstract::AddOutputAction(const char* Action, const char* Option)
495 {
496  TGo4FitterOutput* act = new TGo4FitterOutput(Action,Option);
497  AddAction(act);
498  return act;
499 }
500 
502 {
503  for(Int_t n=0;n<=fxActions.GetLast();n++) {
504  TGo4FitterOutput* action = dynamic_cast<TGo4FitterOutput*> (fxActions[n]);
505  if (action) { fxActions.Remove(action); delete action; }
506  }
507  fxActions.Compress();
508 }
509 
511 {
512  Int_t res = 0;
513  for(Int_t n=0;n<GetNumActions(); n++) {
514  TGo4FitterOutput* act = dynamic_cast<TGo4FitterOutput*> (GetAction(n));
515  if (act && act->NeedPad()) res++;
516  }
517  return res;
518 }
519 
520 void TGo4FitterAbstract::SetPad(Int_t indx, TVirtualPad* pad)
521 {
522  Int_t i = 1; // puds numbering starts from 1
523  for(Int_t n=0;n<GetNumActions(); n++) {
524  TGo4FitterOutput* act = dynamic_cast<TGo4FitterOutput*> (GetAction(n));
525  if (act && act->NeedPad()) {
526  if (i==indx) { act->SetPad(pad); return; }
527  i++;
528  }
529  }
530 }
531 
532 Double_t TGo4FitterAbstract::GetResultValue(Int_t n) const
533 {
534  if ((n>=0) && (n<GetNumResults())) return fxResults.At(n);
535  else return 0.;
536 }
537 
539 {
540  if (fxResults.GetSize()<2) return 0;
541  return fxResults.GetArray()[fxResults.GetSize()-1];
542 }
543 
545 {
546  if (fxResults.GetSize()<2) return 0.;
547  return fxResults.GetArray()[fxResults.GetSize()-2];
548 }
549 
551 {
552  std::cout << std::endl << "*** LIST OF RESULT VALUE ***" << std::endl;
553  std::cout << " Fit function = " << GetResultFF() << std::endl;
554  std::cout << " NDF = " << GetResultNDF() << std::endl;
555  for(Int_t n=0;n<GetNumResults();n++)
556  std::cout << " Res " << n << " = " << GetResultValue(n) << std::endl;
557 }
558 
559 void TGo4FitterAbstract::Print(Option_t* option) const
560 {
561  std::cout << std::endl << "********** THIS IS PRINTOUT OF FITTER OBJECT **********" << std::endl;
562  TGo4FitNamed::Print(option);
563  TGo4FitParsList::Print(option);
564  if (fxActions.GetLast()>=0) {
565  std::cout << "Actions list: " << std::endl;
566  fxActions.Print(option);
567  }
568 }
569 
570 void TGo4FitterAbstract::Streamer(TBuffer& b)
571 {
572  if (b.IsReading()) {
573  TGo4FitterAbstract::Class()->ReadBuffer(b, this);
574  } else {
576  TGo4FitterAbstract::Class()->WriteBuffer(b, this);
577  }
578 }
const TString & GetParameter()
virtual Bool_t GetParEpsilon(const char *ParName, Double_t &Epsilon)
virtual void FinalizeFitterData()
virtual void Clear(Option_t *option="")
TObjArray & GetResults()
void DoAction(TGo4FitterAction *Action)
TGo4FitSlot * GetSlot(Int_t nslot)
Int_t GetResultNDF() const
void DeleteAction(TGo4FitterAction *action)
virtual Double_t DoCalculation()
virtual Bool_t GetParEpsilon(const char *ParName, Double_t &Epsilon)
void AddCommand(const char *iCommand)
virtual void MemorizePars()
void AddAction(TGo4FitterAction *Action)
virtual Bool_t GetParEpsilon(const char *ParName, Double_t &Epsilon)
virtual void Print(Option_t *option) const
virtual Bool_t CanChangeFitter() const
const TArrayD * GetResults()
virtual Bool_t InitFitterData()
const char * GetFullName()
void Initialize(Int_t iNumPar, const char *iFormula)
virtual Int_t NumPars()
virtual void DoAction(TGo4FitterAbstract *Fitter)=0
void ReplaceAction(TGo4FitterAction *action, Int_t dir)
void CopyParsValuesFrom(TGo4FitterAbstract *fitter)
virtual Bool_t GetParFixed(const char *ParName)
Int_t GetNumResults() const
void RunDependenciesList(TObjArray &Dependencies, Double_t *pars)
void FinalizeDependencies(TObjArray &Dependencies)
void PrepareSlotsForWriting()
TGo4FitterOutput * AddOutputAction(const char *Action, const char *Option=0)
virtual void Print(Option_t *option) const
Bool_t IsRequired() const
Definition: TGo4FitSlot.h:193
TObjArray & GetParsDepend()
virtual void CollectAllPars()
virtual Bool_t GetParFixed(const char *ParName)
void DoActions(Bool_t AllowFitterChange=kFALSE, TObjArray *Actions=0)
void SetPad(TVirtualPad *iPad)
Bool_t SetObject(TObject *iObject, Bool_t iOwned=kFALSE, Bool_t CheckClass=kTRUE)
void Print(Option_t *option) const
const char * GetParFullName(Int_t n)
TObjArray * ProcessObjects(TObjArray *objs, Bool_t CloneFitter=kTRUE, Bool_t OnlyRequired=kTRUE, TObjArray *rownames=0, TObjArray *colnames=0)
TGo4FitterConfig * fxCurrentConfig
TGo4FitParameter * FindPar(const char *ParName)
TClass * GetClass()
Definition: TGo4FitSlot.h:61
virtual Bool_t GetParRange(const char *ParName, Double_t &RangeMin, Double_t &RangeMax)
virtual TGo4FitParameter * Get(Int_t n)
TGo4FitParameter * Find(const char *ParName)
Bool_t InitializeDependencies(TObjArray &Dependencies, Bool_t BlockPars, Bool_t DoInit)
Bool_t CheckObjects(Bool_t MakeOut=kTRUE)
Double_t GetResultFF() const
Int_t GetParIndex(const TGo4FitParameter *par)
Double_t CalculateFitFunction(Double_t *pars=0)
virtual Bool_t GetParFixed(const char *ParName)
void SetValue(Double_t iValue)
Double_t GetResultValue(Int_t n) const
Double_t GetValue() const
virtual void RememberPars()
virtual Bool_t GetParRange(const char *ParName, Double_t &RangeMin, Double_t &RangeMax)
TGo4FitterAction * GetAction(Int_t num)
virtual Bool_t Initialize()
Bool_t IsSuitable(TObject *obj)
TGo4FitParsList & GetParsNew()
void SetPad(Int_t indx, TVirtualPad *pad)
const TString & GetExpression()
TObject * GetObject() const
void AddActionAt(TGo4FitterAction *Action, Int_t indx)
Double_t ExecuteDependency(Double_t *Params)
Bool_t IsSuitableConfig(TGo4FitterConfig *Config)
void GetParsValues(Double_t *pars)
Bool_t ApplyConfig(TGo4FitterConfig *Config)
virtual Int_t DoNDFCalculation()
virtual void CollectParsTo(TGo4FitParsList &list)
virtual Bool_t NeedBuffers() const
virtual Bool_t GetParRange(const char *ParName, Double_t &RangeMin, Double_t &RangeMax)
TObjArray & GetParsInit()
void ExecuteDependencies(Double_t *pars)
void SetParsValues(Double_t *pars)