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