Logo ROOT   6.08/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 
13 #include "TTreeFormulaManager.h"
14 
15 #include "TArrayI.h"
16 #include "TError.h"
17 #include "TLeafElement.h"
18 
19 
21 
22 
23 /** \class TTreeFormulaManager
24 Used to coordinate one or more TTreeFormula objects.
25 
26 In particular it makes sure that the dimensions and size of all the formulas
27 is properly coordinated.
28 */
29 
30 
31 ////////////////////////////////////////////////////////////////////////////////
32 /// Tree FormulaManger default constructor.
33 
35 {
36  fMultiplicity = 0;
37  fMultiVarDim = kFALSE;
38  fNeedSync = kFALSE;
39  fNdata = 1;
40 
41  for(Int_t i=0; i<kMAXFORMDIM+1; i++) {
42  fVarDims[i] = 0;
43  fCumulUsedSizes[i] = 1;
44  fUsedSizes[i] = 1;
45  fVirtUsedSizes[i] = 1;
46  }
47  fCumulUsedVarDims = 0;
48 }
49 
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// Tree FormulaManager default destructor.
53 
55 {
56  for (int l = 0; l<kMAXFORMDIM; l++) {
57  if (fVarDims[l]) delete fVarDims[l];
58  fVarDims[l] = 0;
59  }
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// Remove a formula from this manager
65 
67 {
68  fFormulas.Remove(adding);
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Add a new formula to the list of formulas managed
73 /// The manager of the formula will be changed and the old one will be deleted
74 /// if it is empty.
75 
77 {
78  TTreeFormulaManager * old = adding->fManager;
79 
80  if (old) {
81  if (old==this) {
82  if (fFormulas.FindObject(adding)) return;
83  } else {
84  old->fFormulas.Remove(adding);
85  if (old->fFormulas.GetLast()==-1) delete adding->fManager;
86  }
87  }
88 
89  if (adding->TestBit(TTreeFormula::kNeedEntries)) {
91  }
92 
93  fFormulas.Add(adding);
94  adding->fManager = this;
95  fNeedSync = kTRUE;
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Add a variable dimension
100 
102 {
103  if (!fVarDims[virt_dim]) fVarDims[virt_dim] = new TArrayI;
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 /// Cancel a dimension. This is usually called when an out-of-bounds index
108 /// is used.
109 
111 {
112  fCumulUsedSizes[virt_dim] = 0;
113 
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 /// Set the manager as handling a formula with multiple variable dimensions
118 
120 {
123 
124 }
125 
126 ////////////////////////////////////////////////////////////////////////////////
127 /// Return number of available instances in the formulas.
128 
130 {
131  Int_t k;
132 
133  // new version of GetNData:
134  // Possible problem: we only allow one variable dimension so far.
135  if (fMultiplicity==0) return fNdata;
136 
137  if (fMultiplicity==2) return fNdata; // CumulUsedSizes[0];
138 
139  // We have at least one leaf with a variable size:
140 
141  // Reset the registers.
142  for(k=0; k<=kMAXFORMDIM; k++) {
144  if (fVarDims[k]) {
145  for(Int_t i0=0;i0<fVarDims[k]->GetSize();i0++) {
146  fVarDims[k]->AddAt(0,i0);
147  }
148  }
149  }
150  if (fCumulUsedVarDims) {
151  for(Int_t i0=0;i0<fCumulUsedVarDims->GetSize();++i0) {
152  fCumulUsedVarDims->AddAt(0,i0);
153  }
154  }
155 
156  TTreeFormula* current = 0;
157 
158  Int_t size = fFormulas.GetLast()+1;
159 
160  for(Int_t i=0; i<size; i++) {
161 
162  current = (TTreeFormula*)fFormulas.UncheckedAt(i);
163  if (current->fMultiplicity!=1 && !current->fHasCast) continue;
164  if (!current->LoadCurrentDim() ) {
165  if (forceLoadDim) {
166  for(Int_t j=i+1; j<size; j++) {
167  current = (TTreeFormula*)fFormulas.UncheckedAt(j);
168  if (current->fMultiplicity!=1 && !current->fHasCast) continue;
169  current->LoadCurrentDim();
170  }
171  }
172  fNdata = 0;
173  return 0;
174  }
175  }
176 
177  if (fMultiplicity==-1) { fNdata = 1; return fCumulUsedSizes[0]; }
178 
179  Int_t overall = 1;
180  if (!fMultiVarDim) {
181  for (k = kMAXFORMDIM; (k >= 0) ; k--) {
182  if (fUsedSizes[k]>=0) {
183  overall *= fUsedSizes[k];
184  fCumulUsedSizes[k] = overall;
185  } else {
186  Error("GetNdata","a dimension is still negative!");
187  }
188  }
189  } else {
190  overall = 0; // Since we work with additions in this section
192  for(Int_t i = 0; i < fUsedSizes[0]; i++) {
193  Int_t local_overall = 1;
194  for (k = kMAXFORMDIM; (k > 0) ; k--) {
195  if (fVarDims[k]) {
196  Int_t index = fVarDims[k]->At(i);
197  if (fCumulUsedVarDims && fCumulUsedVarDims->At(i)==1 && index) index = 1;
198  if (fUsedSizes[k]==1 || (index!=1 && index<fUsedSizes[k]))
199  local_overall *= index;
200  else local_overall *= fUsedSizes[k];
201  } else {
202  local_overall *= fUsedSizes[k];
203  }
204  }
205  // a negative value indicates that this value of the primary index
206  // will lead to an invalid index; So we skip it.
207  if (fCumulUsedVarDims->At(i)<0) fCumulUsedVarDims->AddAt(0,i);
208  else {
209  fCumulUsedVarDims->AddAt(local_overall,i);
210  overall += local_overall;
211  }
212  }
213  }
214  fNdata = overall;
215  return overall;
216 
217 }
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Synchronize all the formulae.
221 
223 {
224  if (!fNeedSync) return true;
225 
226  TTreeFormula* current = 0;
227  Bool_t hasCast = kFALSE;
228 
229  fMultiplicity = 0;
230  // We do not use an intermediary variable because ResetDimensions
231  // might add more formulas (TCutG).
232  for(Int_t i=0; i<fFormulas.GetLast()+1; i++) {
233  current = (TTreeFormula*)fFormulas.UncheckedAt(i);
234 
235  hasCast |= current->fHasCast;
236 
237  // We probably need to reset the formula's dimension
238 
239  current->ResetDimensions();
240  switch (current->GetMultiplicity()) {
241  case 0:
242  // nothing to do
243  break;
244  case 1:
245  fMultiplicity = 1;
246  break;
247  case 2:
248  if (fMultiplicity!=1) fMultiplicity = 2;
249  break;
250  default:
251  Error("Sync","Unexpected case!");
252  }
253 
254 
255  } // end of for each formulas
256 
257  // For now we keep fCumulUsedSizes sign aware.
258  // This will be reset properly (if needed) by GetNdata.
260  for (Int_t k = kMAXFORMDIM; (k > 0) ; k--) {
261  if (fUsedSizes[k-1]>=0) {
262  fCumulUsedSizes[k-1] = fUsedSizes[k-1] * fCumulUsedSizes[k];
263  } else {
265  }
266  }
267 
268  // Now that we know the virtual dimension we know if a loop over EvalInstance
269  // is needed or not.
270  if (fCumulUsedSizes[0]==1 && fMultiplicity>0) {
271  // Case where even though we have an array. We know that they will always
272  // only be one element.
273  fMultiplicity -= 2;
274  } else if (fCumulUsedSizes[0]<0 && fMultiplicity==2) {
275  // Case of a fixed length array that have one of its indices given
276  // by a variable.
277  fMultiplicity = 1;
278  } else if (fMultiplicity==0 && hasCast) {
279  fMultiplicity = -1;
280  }
281 
282  switch(fMultiplicity) {
283  case 0: fNdata = 1; break;
284  case 2: fNdata = fCumulUsedSizes[0]; break;
285  default: fNdata = 0;
286  }
287  fNeedSync = kFALSE;
288 
289  return true;
290 }
291 
292 ////////////////////////////////////////////////////////////////////////////////
293 /// This function could be called TTreePlayer::UpdateFormulaLeaves, itself
294 /// called by TChain::LoadTree when a new Tree is loaded.
295 /// Because Trees in a TChain may have a different list of leaves, one
296 /// must update the leaves numbers in the TTreeFormula used by the TreePlayer.
297 
299 {
300  // A safer alternative would be to recompile the whole thing .... However
301  // currently compile HAS TO be called from the constructor!
302 
303  Int_t size = fFormulas.GetLast()+1;
304 
305  for(Int_t i=0; i<size; i++) {
306 
308  current->UpdateFormulaLeaves();
309 
310  }
311 
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// Reload the array sizes
316 
318 {
319  if (vsize<0)
320  fVirtUsedSizes[virt_dim] = -1 * TMath::Abs(fVirtUsedSizes[virt_dim]);
321  else
322  if ( TMath::Abs(fVirtUsedSizes[virt_dim])==1
323  || (vsize < TMath::Abs(fVirtUsedSizes[virt_dim]) ) ) {
324  // Absolute values represent the min of all real dimensions
325  // that are known. The fact that it is negatif indicates
326  // that one of the leaf has a variable size for this
327  // dimensions.
328  if (fVirtUsedSizes[virt_dim] < 0) {
329  fVirtUsedSizes[virt_dim] = -1 * vsize;
330  } else {
331  fVirtUsedSizes[virt_dim] = vsize;
332  }
333  }
334  fUsedSizes[virt_dim] = fVirtUsedSizes[virt_dim];
335  virt_dim++;
336 
337 }
Int_t fCumulUsedSizes[kMAXFORMDIM+1]
Last value calculated by GetNdata.
const Int_t kMAXFORMDIM
Definition: TTreeFormula.h:49
virtual void Remove(TTreeFormula *)
Remove a formula from this manager.
virtual Bool_t Sync()
Synchronize all the formulae.
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:157
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:653
TArrayI * fVarDims[kMAXFORMDIM+1]
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual void UpdateFormulaLeaves()
This function could be called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree whe...
Int_t fMultiplicity
Definition: TTreeFormula.h:106
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:110
Array of integers (32 bits per element).
Definition: TArrayI.h:29
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:739
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:396
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:64
virtual Int_t GetMultiplicity() const
Definition: TTreeFormula.h:197
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:528
Int_t GetSize() const
Definition: TArray.h:49
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:925
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
TLine * l
Definition: textangle.C:4
Bool_t fHasCast
Definition: TTreeFormula.h:105
Int_t fUsedSizes[kMAXFORMDIM+1]
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:91
#define ClassImp(name)
Definition: Rtypes.h:279
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:130
void Add(TObject *obj)
Definition: TObjArray.h:75
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:81
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void UpdateUsedSize(Int_t &virt_dim, Int_t vsize)
Reload the array sizes.