Logo ROOT   6.18/05
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;
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
87 }
88
89 fFormulas.Add(adding);
90 adding->fManager = this;
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)
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 }
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 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