Logo ROOT   6.12/07
Reference Guide
TTreeFormulaManager.cxx
Go to the documentation of this file.
1 // @(#)root/treeplayer:$Id$
2 // Author: Philippe Canal 20/03/02
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers and al. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TTreeFormulaManager.h"
13 
14 #include "TArrayI.h"
15 #include "TError.h"
16 #include "TLeafElement.h"
17 
19 
20  /** \class TTreeFormulaManager
21  Used to coordinate one or more TTreeFormula objects.
22 
23  In particular it makes sure that the dimensions and size of all the formulas
24  is properly coordinated.
25  */
26 
27  ////////////////////////////////////////////////////////////////////////////////
28  /// Tree FormulaManger default constructor.
29 
31  : TObject()
32 {
33  fMultiplicity = 0;
35  fNeedSync = kFALSE;
36  fNdata = 1;
37 
38  for (Int_t i = 0; i < kMAXFORMDIM + 1; i++) {
39  fVarDims[i] = 0;
40  fCumulUsedSizes[i] = 1;
41  fUsedSizes[i] = 1;
42  fVirtUsedSizes[i] = 1;
43  }
45 }
46 
47 ////////////////////////////////////////////////////////////////////////////////
48 /// Tree FormulaManager default destructor.
49 
51 {
52  for (int l = 0; l < kMAXFORMDIM; l++) {
53  if (fVarDims[l]) delete fVarDims[l];
54  fVarDims[l] = 0;
55  }
57 }
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 /// Remove a formula from this manager
61 
63 {
64  fFormulas.Remove(adding);
65 }
66 
67 ////////////////////////////////////////////////////////////////////////////////
68 /// Add a new formula to the list of formulas managed
69 /// The manager of the formula will be changed and the old one will be deleted
70 /// if it is empty.
71 
73 {
74  TTreeFormulaManager *old = adding->fManager;
75 
76  if (old) {
77  if (old == this) {
78  if (fFormulas.FindObject(adding)) return;
79  } else {
80  old->fFormulas.Remove(adding);
81  if (old->fFormulas.GetLast() == -1) delete adding->fManager;
82  }
83  }
84 
85  if (adding->TestBit(TTreeFormula::kNeedEntries)) {
87  }
88 
89  fFormulas.Add(adding);
90  adding->fManager = this;
91  fNeedSync = kTRUE;
92 }
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 /// Add a variable dimension
96 
98 {
99  if (!fVarDims[virt_dim]) fVarDims[virt_dim] = new TArrayI;
100 }
101 
102 ////////////////////////////////////////////////////////////////////////////////
103 /// Cancel a dimension. This is usually called when an out-of-bounds index
104 /// is used.
105 
107 {
108  fCumulUsedSizes[virt_dim] = 0;
109 }
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 /// Set the manager as handling a formula with multiple variable dimensions
113 
115 {
118 }
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// Return number of available instances in the formulas.
122 
124 {
125  Int_t k;
126 
127  // new version of GetNData:
128  // Possible problem: we only allow one variable dimension so far.
129  if (fMultiplicity == 0) return fNdata;
130 
131  if (fMultiplicity == 2) return fNdata; // CumulUsedSizes[0];
132 
133  // We have at least one leaf with a variable size:
134 
135  // Reset the registers.
136  for (k = 0; k <= kMAXFORMDIM; k++) {
138  if (fVarDims[k]) {
139  for (Int_t i0 = 0; i0 < fVarDims[k]->GetSize(); i0++) {
140  fVarDims[k]->AddAt(0, i0);
141  }
142  }
143  }
144  if (fCumulUsedVarDims) {
145  for (Int_t i0 = 0; i0 < fCumulUsedVarDims->GetSize(); ++i0) {
146  fCumulUsedVarDims->AddAt(0, i0);
147  }
148  }
149 
150  TTreeFormula *current = 0;
151 
152  Int_t size = fFormulas.GetLast() + 1;
153 
154  for (Int_t i = 0; i < size; i++) {
155 
156  current = (TTreeFormula *)fFormulas.UncheckedAt(i);
157  if (current->fMultiplicity != 1 && !current->fHasCast) continue;
158  if (!current->LoadCurrentDim()) {
159  if (forceLoadDim) {
160  for (Int_t j = i + 1; j < size; j++) {
161  current = (TTreeFormula *)fFormulas.UncheckedAt(j);
162  if (current->fMultiplicity != 1 && !current->fHasCast) continue;
163  current->LoadCurrentDim();
164  }
165  }
166  fNdata = 0;
167  return 0;
168  }
169  }
170 
171  if (fMultiplicity == -1) {
172  fNdata = 1;
173  return fCumulUsedSizes[0];
174  }
175 
176  Int_t overall = 1;
177  if (!fMultiVarDim) {
178  for (k = kMAXFORMDIM; (k >= 0); k--) {
179  if (fUsedSizes[k] >= 0) {
180  overall *= fUsedSizes[k];
181  fCumulUsedSizes[k] = overall;
182  } else {
183  Error("GetNdata", "a dimension is still negative!");
184  }
185  }
186  } else {
187  overall = 0; // Since we work with additions in this section
189  for (Int_t i = 0; i < fUsedSizes[0]; i++) {
190  Int_t local_overall = 1;
191  for (k = kMAXFORMDIM; (k > 0); k--) {
192  if (fVarDims[k]) {
193  Int_t index = fVarDims[k]->At(i);
194  if (fCumulUsedVarDims && fCumulUsedVarDims->At(i) == 1 && index) index = 1;
195  if (fUsedSizes[k] == 1 || (index != 1 && index < fUsedSizes[k]))
196  local_overall *= index;
197  else
198  local_overall *= fUsedSizes[k];
199  } else {
200  local_overall *= fUsedSizes[k];
201  }
202  }
203  // a negative value indicates that this value of the primary index
204  // will lead to an invalid index; So we skip it.
205  if (fCumulUsedVarDims->At(i) < 0)
206  fCumulUsedVarDims->AddAt(0, i);
207  else {
208  fCumulUsedVarDims->AddAt(local_overall, i);
209  overall += local_overall;
210  }
211  }
212  }
213  fNdata = overall;
214  return overall;
215 }
216 
217 ////////////////////////////////////////////////////////////////////////////////
218 /// Synchronize all the formulae.
219 
221 {
222  if (!fNeedSync) return true;
223 
224  TTreeFormula *current = 0;
225  Bool_t hasCast = kFALSE;
226 
227  fMultiplicity = 0;
228  // We do not use an intermediary variable because ResetDimensions
229  // might add more formulas (TCutG).
230  for (Int_t i = 0; i < fFormulas.GetLast() + 1; i++) {
231  current = (TTreeFormula *)fFormulas.UncheckedAt(i);
232 
233  hasCast |= current->fHasCast;
234 
235  // We probably need to reset the formula's dimension
236 
237  current->ResetDimensions();
238  switch (current->GetMultiplicity()) {
239  case 0:
240  // nothing to do
241  break;
242  case 1: fMultiplicity = 1; break;
243  case 2:
244  if (fMultiplicity != 1) fMultiplicity = 2;
245  break;
246  default: Error("Sync", "Unexpected case!");
247  }
248 
249  } // end of for each formulas
250 
251  // For now we keep fCumulUsedSizes sign aware.
252  // This will be reset properly (if needed) by GetNdata.
254  for (Int_t k = kMAXFORMDIM; (k > 0); k--) {
255  if (fUsedSizes[k - 1] >= 0) {
256  fCumulUsedSizes[k - 1] = fUsedSizes[k - 1] * fCumulUsedSizes[k];
257  } else {
259  }
260  }
261 
262  // Now that we know the virtual dimension we know if a loop over EvalInstance
263  // is needed or not.
264  if (fCumulUsedSizes[0] == 1 && fMultiplicity > 0) {
265  // Case where even though we have an array. We know that they will always
266  // only be one element.
267  fMultiplicity -= 2;
268  } else if (fCumulUsedSizes[0] < 0 && fMultiplicity == 2) {
269  // Case of a fixed length array that have one of its indices given
270  // by a variable.
271  fMultiplicity = 1;
272  } else if (fMultiplicity == 0 && hasCast) {
273  fMultiplicity = -1;
274  }
275 
276  switch (fMultiplicity) {
277  case 0: fNdata = 1; break;
278  case 2: fNdata = fCumulUsedSizes[0]; break;
279  default: fNdata = 0;
280  }
281  fNeedSync = kFALSE;
282 
283  return true;
284 }
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 /// This function could be called TTreePlayer::UpdateFormulaLeaves, itself
288 /// called by TChain::LoadTree when a new Tree is loaded.
289 /// Because Trees in a TChain may have a different list of leaves, one
290 /// must update the leaves numbers in the TTreeFormula used by the TreePlayer.
291 
293 {
294  // A safer alternative would be to recompile the whole thing .... However
295  // currently compile HAS TO be called from the constructor!
296 
297  Int_t size = fFormulas.GetLast() + 1;
298 
299  for (Int_t i = 0; i < size; i++) {
300 
302  current->UpdateFormulaLeaves();
303  }
304 }
305 
306 ////////////////////////////////////////////////////////////////////////////////
307 /// Reload the array sizes
308 
310 {
311  if (vsize < 0)
312  fVirtUsedSizes[virt_dim] = -1 * TMath::Abs(fVirtUsedSizes[virt_dim]);
313  else if (TMath::Abs(fVirtUsedSizes[virt_dim]) == 1 || (vsize < TMath::Abs(fVirtUsedSizes[virt_dim]))) {
314  // Absolute values represent the min of all real dimensions
315  // that are known. The fact that it is negatif indicates
316  // that one of the leaf has a variable size for this
317  // dimensions.
318  if (fVirtUsedSizes[virt_dim] < 0) {
319  fVirtUsedSizes[virt_dim] = -1 * vsize;
320  } else {
321  fVirtUsedSizes[virt_dim] = vsize;
322  }
323  }
324  fUsedSizes[virt_dim] = fVirtUsedSizes[virt_dim];
325  virt_dim++;
326 }
Int_t fCumulUsedSizes[kMAXFORMDIM+1]
Last value calculated by GetNdata.
const Int_t kMAXFORMDIM
Definition: TTreeFormula.h:43
virtual void Remove(TTreeFormula *)
Remove a formula from this manager.
virtual Bool_t Sync()
Synchronize all the formulae.
virtual void EnableMultiVarDims()
Set the manager as handling a formula with multiple variable dimensions.
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:703
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
TArrayI * fVarDims[kMAXFORMDIM+1]
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual void UpdateFormulaLeaves()
This function could be called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree whe...
Int_t fMultiplicity
Definition: TTreeFormula.h:100
virtual void Add(TTreeFormula *)
Add a new formula to the list of formulas managed The manager of the formula will be changed and the ...
Short_t Abs(Short_t d)
Definition: TMathBase.h:108
Array of integers (32 bits per element).
Definition: TArrayI.h:27
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
Int_t fVirtUsedSizes[kMAXFORMDIM+1]
Bool_t LoadCurrentDim()
Calculate the actual dimension for the current entry.
virtual void CancelDimension(Int_t virt_dim)
Cancel a dimension.
Used to coordinate one or more TTreeFormula objects.
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:414
void ResetDimensions()
Populate the TTreeFormulaManager with the dimension information.
void Set(Int_t n)
Set size of this array to n ints.
Definition: TArrayI.cxx:105
void AddAt(Int_t c, Int_t i)
Add Int_t c at position i. Check for out of bounds.
Definition: TArrayI.cxx:93
~TTreeFormulaManager()
Tree FormulaManager default destructor.
Used to pass a selection expression to the Tree drawing routine.
Definition: TTreeFormula.h:58
virtual Int_t GetMultiplicity() const
Definition: TTreeFormula.h:191
virtual void AddVarDims(Int_t virt_dim)
Add a variable dimension.
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:561
Int_t GetSize() const
Definition: TArray.h:47
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
const Bool_t kFALSE
Definition: RtypesCore.h:88
Bool_t fHasCast
Definition: TTreeFormula.h:99
Int_t fUsedSizes[kMAXFORMDIM+1]
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:89
#define ClassImp(name)
Definition: Rtypes.h:359
Mother of all ROOT objects.
Definition: TObject.h:37
TTreeFormulaManager * fManager
True if we executed one boolean optimization since the last time instance number 0 was evaluated...
Definition: TTreeFormula.h:124
auto * l
Definition: textangle.C:4
void Add(TObject *obj)
Definition: TObjArray.h:73
virtual Int_t GetNdata(Bool_t forceLoadDim=kFALSE)
Return number of available instances in the formulas.
Int_t At(Int_t i) const
Definition: TArrayI.h:79
const Bool_t kTRUE
Definition: RtypesCore.h:87
virtual void UpdateUsedSize(Int_t &virt_dim, Int_t vsize)
Reload the array sizes.
TTreeFormulaManager()
Tree FormulaManger default constructor.