GSI Object Oriented Online Offline (Go4)  GO4-6.3.0
TGo4FitComponent.cxx
Go to the documentation of this file.
1 // $Id$
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 fuer 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 "TGo4FitComponent.h"
15 
16 #include <iostream>
17 
18 #include "TCutG.h"
19 
20 #include "TGo4FitParameter.h"
21 
22 const UInt_t kExcludeCut = 0x00100000;
23 
25  : TGo4FitParsList(), TGo4FitSlotList(), fxRangeAxis(), fxRangeValue(), fxCuts(), fiAmplIndex(-1),
26  fbUseBuffers(kFALSE)
27 {
28 }
29 
30 TGo4FitComponent::TGo4FitComponent(const char *iName, const char *iTitle)
31  : TGo4FitParsList(iName, iTitle, kTRUE), TGo4FitSlotList(), fxRangeAxis(), fxRangeValue(), fxCuts(), fiAmplIndex(-1),
32  fbUseBuffers(kFALSE)
33 {
34  fxCuts.SetOwner(kTRUE);
35 }
36 
38 
40 TGo4FitComponent::NewParameter(const char *Name, const char *Title, Double_t iValue, Bool_t Fixed, Int_t AtIndx)
41 {
42  TGo4FitParameter *par = new TGo4FitParameter(Name, Title, iValue);
43  if (AtIndx < 0)
44  AddPar(par);
45  else
46  InsertPar(par, AtIndx);
47  if (Fixed)
48  par->SetFixed(kTRUE);
49  return par;
50 }
51 
52 TGo4FitParameter *TGo4FitComponent::NewAmplitude(const char *Name, Double_t iValue, Bool_t IsFixed, Int_t AtIndx)
53 {
54  TGo4FitParameter *par = new TGo4FitParameter(Name ? Name : "Ampl", "Amplitude", iValue);
55  if (AtIndx < 0) {
56  AddPar(par);
57  AtIndx = NumPars() - 1;
58  } else {
59  InsertPar(par, AtIndx);
60  }
61  SetAmplIndex(AtIndx);
62  if (IsFixed)
63  par->SetFixed(kTRUE);
64  return par;
65 }
66 
68 {
69  return fiAmplIndex < 0 ? nullptr : GetPar(fiAmplIndex);
70 }
71 
73 {
74  return GetAmplPar() ? GetAmplPar()->GetName() : nullptr;
75 }
76 
78 {
79  return GetAmplPar() ? GetAmplPar()->GetFullName() : nullptr;
80 }
82 {
83  return GetAmplPar() ? GetAmplPar()->GetValue() : 1.0;
84 }
85 
86 void TGo4FitComponent::SetAmplValue(Double_t iAmpl)
87 {
88  if (GetAmplPar())
89  Get(fiAmplIndex)->SetValue(iAmpl);
90 }
91 
93 {
94  return GetAmplPar() ? GetAmplPar()->GetError() : 0.0;
95 }
96 
97 void TGo4FitComponent::SetAmplError(Double_t iError)
98 {
99  if (GetAmplPar())
100  Get(fiAmplIndex)->SetError(iError);
101 }
102 
103 Bool_t TGo4FitComponent::MakeAmpl(Bool_t isFixed)
104 {
105  if (GetAmplPar())
106  return kFALSE;
107  NewAmplitude();
108  if (isFixed)
109  GetAmplPar()->SetFixed(kTRUE);
110  return kTRUE;
111 }
112 
114 {
115  if (!GetAmplPar())
116  return kFALSE;
118  SetAmplIndex(-1);
119  return kTRUE;
120 }
121 
122 void TGo4FitComponent::GetRangeCondition(Int_t n, Int_t &typ, Int_t &naxis, Double_t &left, Double_t &right) const
123 {
124  if ((n >= 0) && (n < GetNumRangeCondition())) {
125  Int_t naxis1 = fxRangeAxis[n * 2];
126  Int_t naxis2 = fxRangeAxis[n * 2 + 1];
127  Double_t value1 = fxRangeValue[n * 2];
128  Double_t value2 = fxRangeValue[n * 2 + 1];
129 
130  if ((naxis1 < 0) && (naxis2 > 0)) {
131  typ = 0;
132  naxis = -naxis1 - 1;
133  left = value1;
134  right = value2;
135  } else if ((naxis1 > 0) && (naxis2 < 0)) {
136  typ = 1;
137  naxis = naxis1 - 1;
138  left = value1;
139  right = value2;
140  } else if (naxis1 < 0) {
141  typ = 2;
142  naxis = -naxis1 - 1;
143  left = value1;
144  right = 0.;
145  } else if (naxis1 > 0) {
146  typ = 3;
147  naxis = naxis1 - 1;
148  left = 0.;
149  right = value1;
150  }
151  }
152 }
153 
154 void TGo4FitComponent::SetRangeCondition(Int_t n, Int_t typ, Int_t naxis, Double_t left, Double_t right)
155 {
156  if ((n >= 0) && (n < GetNumRangeCondition())) {
157  Int_t naxis1, naxis2;
158  Double_t value1, value2;
159 
160  switch (typ) {
161  case 0:
162  naxis1 = -(naxis + 1);
163  value1 = left;
164  naxis2 = +(naxis + 1);
165  value2 = right;
166  break;
167  case 1:
168  naxis1 = +(naxis + 1);
169  value1 = left;
170  naxis2 = -(naxis + 1);
171  value2 = right;
172  break;
173  case 2:
174  naxis1 = -(naxis + 1);
175  value1 = left;
176  naxis2 = 0;
177  value2 = 0.;
178  break;
179  case 3:
180  naxis1 = +(naxis + 1);
181  value1 = right;
182  naxis2 = 0;
183  value2 = 0.;
184  break;
185  default: return;
186  }
187 
188  fxRangeAxis[n * 2] = naxis1;
189  fxRangeAxis[n * 2 + 1] = naxis2;
190  fxRangeValue[n * 2] = value1;
191  fxRangeValue[n * 2 + 1] = value2;
192  }
193 }
194 
195 void TGo4FitComponent::AddRangeCondition(Int_t typ, Int_t naxis, Double_t left, Double_t right)
196 {
197  Int_t sz = fxRangeValue.GetSize() + 2;
198  fxRangeAxis.Set(sz);
199  fxRangeValue.Set(sz);
200  SetRangeCondition(sz / 2 - 1, typ, naxis, left, right);
201 }
202 
204 {
205  if ((n < 0) || (n >= GetNumRangeCondition()))
206  return;
207 
208  Int_t indx = n * 2;
209  while (indx < fxRangeAxis.GetSize() - 2) {
210  fxRangeAxis[indx] = fxRangeAxis[indx + 2];
211  fxRangeValue[indx] = fxRangeValue[indx + 2];
212  indx += 1;
213  }
214  fxRangeAxis.Set(indx);
215  fxRangeValue.Set(indx);
216 }
217 
218 void TGo4FitComponent::SetRange(Int_t naxis, Double_t min, Double_t max)
219 {
220  AddRangeCondition(0, naxis, min, max);
221 }
222 
223 void TGo4FitComponent::ExcludeRange(Int_t naxis, Double_t min, Double_t max)
224 {
225  AddRangeCondition(1, naxis, min, max);
226 }
227 
228 void TGo4FitComponent::SetRangeMin(Int_t naxis, Double_t value)
229 {
230  AddRangeCondition(2, naxis, value, 0.);
231 }
232 
233 void TGo4FitComponent::SetRangeMax(Int_t naxis, Double_t value)
234 {
235  AddRangeCondition(3, naxis, 0., value);
236 }
237 
239 {
240  if (naxis < 0) {
241  fxRangeAxis.Set(0);
242  fxRangeValue.Set(0);
243  fxCuts.Delete();
244  } else {
245  Int_t indx = 0, dindx = 0;
246  while (indx < fxRangeAxis.GetSize()) {
247  if (TMath::Abs(fxRangeAxis[indx]) != (naxis + 1)) {
248  fxRangeAxis[dindx] = fxRangeAxis[indx];
249  fxRangeAxis[dindx + 1] = fxRangeAxis[indx + 1];
250  fxRangeValue[dindx] = fxRangeValue[indx];
251  fxRangeValue[dindx + 1] = fxRangeValue[indx + 1];
252  dindx += 2;
253  }
254  indx += 2;
255  }
256  fxRangeAxis.Set(dindx);
257  fxRangeValue.Set(dindx);
258  if ((naxis == 0) || (naxis == 1))
259  fxCuts.Delete();
260  }
261 }
262 
264 {
265  return (GetNumRangeCondition() > 0) || (GetNumRangeCut() > 0);
266 }
267 
268 void TGo4FitComponent::AddRangeCut(TCutG *cut, Bool_t exclude)
269 {
270  cut->SetBit(kExcludeCut, exclude);
271  fxCuts.Add(cut);
272 }
273 
275 {
276  return fxCuts.GetLast() + 1;
277 }
278 
279 TCutG *TGo4FitComponent::GetRangeCut(Int_t n) const
280 {
281  return (n >= 0) && (n <= fxCuts.GetLast()) ? dynamic_cast<TCutG *>(fxCuts.At(n)) : nullptr;
282 }
283 
285 {
286  TCutG *cut = GetRangeCut(n);
287  return !cut ? kFALSE : cut->TestBit(kExcludeCut);
288 }
289 
290 void TGo4FitComponent::SetRangeCutExcluding(Int_t n, Bool_t exclude)
291 {
292  TCutG *cut = GetRangeCut(n);
293  if (cut)
294  cut->SetBit(kExcludeCut, exclude);
295 }
296 
298 {
299  TCutG *cut = GetRangeCut(n);
300  if (cut) {
301  fxCuts.Remove(cut);
302  delete cut;
303  fxCuts.Compress();
304  }
305 }
306 
307 Bool_t TGo4FitComponent::GetRangeMin(Int_t naxis, Double_t &value) const
308 {
309  Bool_t isany = kFALSE;
310  for (Int_t indx = 0; indx < fxRangeAxis.GetSize(); indx += 2)
311  if (fxRangeAxis[indx] == -(naxis + 1)) {
312  Double_t zn = fxRangeValue[indx];
313  if ((!isany) || (zn < value))
314  value = zn;
315  isany = kTRUE;
316  }
317  if (naxis < 2)
318  for (Int_t ncut = 0; ncut < GetNumRangeCut(); ncut++) {
319  TCutG *cut = GetRangeCut(ncut);
320  if (cut->TestBit(kExcludeCut))
321  continue;
322  Double_t *arr = (naxis == 0) ? cut->GetX() : cut->GetY();
323  Double_t zn = arr[0];
324  for (Int_t i = 1; i < cut->GetN(); i++)
325  if (arr[i] < zn)
326  zn = arr[i];
327  if ((!isany) || (zn < value))
328  value = zn;
329  isany = kTRUE;
330  }
331 
332  return isany;
333 }
334 
335 Bool_t TGo4FitComponent::GetRangeMax(Int_t naxis, Double_t &value) const
336 {
337  Bool_t isany = kFALSE;
338  Double_t zn;
339  for (Int_t indx = 0; indx < fxRangeAxis.GetSize(); indx += 2) {
340  if ((fxRangeAxis[indx] == -(naxis + 1)) && (fxRangeAxis[indx + 1] == +(naxis + 1)))
341  zn = fxRangeValue[indx + 1];
342  else if ((fxRangeAxis[indx] == +(naxis + 1)) && (fxRangeAxis[indx + 1] == 0))
343  zn = fxRangeValue[indx];
344  else
345  continue;
346  if ((!isany) || (zn > value))
347  value = zn;
348  isany = kTRUE;
349  }
350  if (naxis < 2)
351  for (Int_t ncut = 0; ncut < GetNumRangeCut(); ncut++) {
352  TCutG *cut = GetRangeCut(ncut);
353  if (cut->TestBit(kExcludeCut))
354  continue;
355  Double_t *arr = naxis == 0 ? cut->GetX() : cut->GetY();
356  zn = arr[0];
357  for (Int_t i = 1; i < cut->GetN(); i++)
358  if (arr[i] > zn)
359  zn = arr[i];
360  if ((!isany) || (zn > value))
361  value = zn;
362  isany = kTRUE;
363  }
364 
365  return isany;
366 }
367 
368 Bool_t TGo4FitComponent::CheckRangeConditions(const Double_t *values, Int_t numaxis)
369 {
370  Int_t condsize = GetNumRangeCondition();
371 
372  if ((condsize == 0) && (GetNumRangeCut() == 0))
373  return kTRUE;
374 
375  Bool_t res1 = kTRUE, res2 = kTRUE;
376 
377  Bool_t isanycond = kFALSE;
378 
379  for (Int_t naxis = 0; naxis < numaxis; naxis++) {
380  Char_t resaxis1 = kTRUE, resaxis2 = kFALSE;
381  Bool_t isany = kFALSE;
382  for (Int_t ncond = 0; ncond < condsize; ncond++) {
383 
384  Int_t typ, axisnumber;
385  Double_t left, right;
386  GetRangeCondition(ncond, typ, axisnumber, left, right);
387 
388  if (axisnumber != naxis)
389  continue;
390 
391  switch (typ) {
392  case 0:
393  isany = kTRUE; // include range
394  if ((values[naxis] >= left) && (values[naxis] <= right))
395  resaxis2 = kTRUE;
396  break;
397  case 1: // exclude range
398  if ((values[naxis] >= left) && (values[naxis] <= right))
399  resaxis1 = kFALSE;
400  break;
401  case 2:
402  if (values[naxis] < left)
403  resaxis1 = kFALSE;
404  break; // set left bound
405  case 3:
406  if (values[naxis] > right)
407  resaxis1 = kFALSE;
408  break; // set right bound
409  }
410  }
411 
412  res1 = res1 && resaxis1;
413  if (!isany)
414  resaxis2 = kTRUE;
415  res2 = res2 && resaxis2;
416  isanycond = isanycond || isany;
417  if (!res1)
418  break;
419  }
420 
421  if (res1 && !(isanycond && res2) && (numaxis > 1) && (GetNumRangeCut() > 0)) {
422  res2 = kFALSE;
423  for (Int_t n = 0; n < GetNumRangeCut(); n++) {
424  TCutG *cut = GetRangeCut(n);
425  if (cut->IsInside(values[0], values[1])) {
426  if (cut->TestBit(kExcludeCut)) {
427  res1 = kFALSE;
428  break;
429  } else {
430  res2 = kTRUE;
431  break;
432  }
433  }
434  }
435  }
436 
437  return res1 && res2;
438 }
439 
441 {
443  for (Int_t n = 0; n < NumSlots(); n++) {
444  TGo4FitSlot *slot = GetSlot(n);
445  if (slot && slot->GetOwned()) {
446  TGo4FitParsList *pars = dynamic_cast<TGo4FitParsList *>(slot->GetObject());
447  if (pars)
448  pars->CollectParsTo(list);
449  }
450  }
451 }
452 
453 void TGo4FitComponent::Print(Option_t *option) const
454 {
455  std::cout << "***************************************************************************" << std::endl;
456  TGo4FitNamed::Print(option);
457  TGo4FitParsList::Print(option);
458  std::cout << " Amplitude index: " << fiAmplIndex << std::endl;
459 
460  for (Int_t ncond = 0; ncond < GetNumRangeCondition(); ncond++) {
461  if (ncond == 0)
462  std::cout << " Range selection: " << std::endl;
463  Int_t typ, naxis;
464  Double_t left, right;
465  GetRangeCondition(ncond, typ, naxis, left, right);
466 
467  std::cout << " axis " << naxis << " ";
468 
469  switch (typ) {
470  case 0: std::cout << " select range from " << left << " to " << right; break;
471  case 1: std::cout << " exclude range from " << left << " to " << right; break;
472  case 2: std::cout << " set left bound to " << left; break;
473  case 3: std::cout << " set right bound to " << right; break;
474  }
475 
476  std::cout << std::endl;
477  }
478 
479  for (Int_t n = 0; n < GetNumRangeCut(); n++) {
480  TCutG *cut = GetRangeCut(n);
481  if (cut->TestBit(kExcludeCut))
482  std::cout << " Exclude";
483  else
484  std::cout << " Include";
485  std::cout << " axes ranges, using TCutG object " << std::endl;
486  cut->Print(option);
487  }
488 }
Double_t GetValue() const
void Print(Option_t *option="") const override
void CollectParsTo(TGo4FitParsList &list) override
TGo4FitParameter * InsertPar(TGo4FitParameter *par, Int_t indx)
Bool_t CheckRangeConditions(const Double_t *values, Int_t numaxis)
TCutG * GetRangeCut(Int_t n) const
TGo4FitSlot * GetSlot(Int_t nslot)
void ClearRanges(Int_t naxis=-1)
void SetRangeCondition(Int_t n, Int_t typ, Int_t naxis, Double_t left, Double_t right)
Int_t GetNumRangeCut() const
const char * GetAmplFullName()
void SetRangeCutExcluding(Int_t n, Bool_t exclude=kTRUE)
void SetRangeMin(Int_t naxis, Double_t value)
TGo4FitParameter * GetPar(Int_t n)
void SetAmplError(Double_t iError)
Int_t GetAmplIndex() const
TGo4FitParameter * NewAmplitude(const char *Name=nullptr, Double_t iValue=0., Bool_t IsFixed=kFALSE, Int_t AtIndx=0)
Int_t GetNumRangeCondition() const
TGo4FitParameter * NewParameter(const char *Name, const char *Title, Double_t iValue=0., Bool_t Fixed=kFALSE, Int_t AtIndx=-1)
const char * GetFullName()
void SetAmplValue(Double_t iAmpl)
void SetAmplIndex(Int_t iAmplIndex=-1)
void GetRangeCondition(Int_t n, Int_t &typ, Int_t &naxis, Double_t &left, Double_t &right) const
Double_t GetError() const
Bool_t GetRangeMax(Int_t naxis, Double_t &value) const
virtual Int_t NumPars()
void SetRange(Int_t naxis, Double_t min, Double_t max)
Bool_t IsAnyRangeLimits() const
void AddRangeCut(TCutG *cut, Bool_t exclude=kFALSE)
Bool_t IsRangeCutExcluding(Int_t n) const
void SetRangeMax(Int_t naxis, Double_t value)
const UInt_t kExcludeCut
Bool_t RemoveParByIndex(Int_t indx)
void Print(Option_t *option="") const override
void SetValue(Double_t iValue)
void RemoveRangeCut(Int_t n)
void RemoveRangeCondition(Int_t n)
void AddRangeCondition(Int_t typ, Int_t naxis, Double_t left, Double_t right)
Bool_t MakeAmpl(Bool_t isFixed=kFALSE)
const char * GetAmplName()
TObject * GetObject() const
virtual TGo4FitParameter * Get(Int_t n)
Bool_t GetOwned() const
Definition: TGo4FitSlot.h:160
void ExcludeRange(Int_t naxis, Double_t min, Double_t max)
void Print(Option_t *option="") const override
void SetFixed(Bool_t iFixed)
Bool_t GetRangeMin(Int_t naxis, Double_t &value) const
virtual void CollectParsTo(TGo4FitParsList &list)
TGo4FitParameter * AddPar(TGo4FitParameter *par)
virtual ~TGo4FitComponent()
void SetError(Double_t iError)
TGo4FitParameter * GetAmplPar()