Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
18#include <cmath>
19
20
21 /** \class TTreeFormulaManager
22 Used to coordinate one or more TTreeFormula objects.
23
24 In particular it makes sure that the dimensions and size of all the formulas
25 is properly coordinated.
26 */
27
28 ////////////////////////////////////////////////////////////////////////////////
29 /// Tree FormulaManger default constructor.
30
32{
33 fMultiplicity = 0;
34 fMultiVarDim = false;
35 fNeedSync = false;
36 fNdata = 1;
37
38 for (Int_t i = 0; i < kMAXFORMDIM + 1; i++) {
39 fVarDims[i] = nullptr;
40 fCumulUsedSizes[i] = 1;
41 fUsedSizes[i] = 1;
42 fVirtUsedSizes[i] = 1;
43 }
44 fCumulUsedVarDims = nullptr;
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] = nullptr;
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;
91 fNeedSync = true;
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
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++) {
137 fUsedSizes[k] = std::abs(fVirtUsedSizes[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 = nullptr;
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 = nullptr;
225 bool hasCast = false;
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 {
258 fCumulUsedSizes[k - 1] = -std::abs(fCumulUsedSizes[k]);
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 = false;
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 * std::abs(fVirtUsedSizes[virt_dim]);
313 else if (std::abs(fVirtUsedSizes[virt_dim]) == 1 || (vsize < std::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}
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
const Int_t kMAXFORMDIM
Array of integers (32 bits per element).
Definition TArrayI.h:27
void Set(Int_t n) override
Set size of this array to n ints.
Definition TArrayI.cxx:104
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:92
Int_t GetSize() const
Definition TArray.h:47
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:90
TObject * Remove(TObject *obj) override
Remove object from array.
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
Int_t GetLast() const override
Return index of last object in array.
void Add(TObject *obj) override
Definition TObjArray.h:68
Mother of all ROOT objects.
Definition TObject.h:42
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
Used to coordinate one or more TTreeFormula objects.
bool fMultiVarDim
True if one of the variable has 2 variable size dimensions.
virtual void UpdateUsedSize(Int_t &virt_dim, Int_t vsize)
Reload the array sizes.
Int_t fVirtUsedSizes[kMAXFORMDIM+1]
Virtual size of lower dimensions as seen for this formula.
Int_t fNdata
! Last value calculated by GetNdata
virtual void UpdateFormulaLeaves()
This function could be called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree whe...
TArrayI * fCumulUsedVarDims
fCumulUsedSizes(1) for multi variable dimensions case
TArrayI * fVarDims[kMAXFORMDIM+1]
List of variable sizes dimensions.
virtual void EnableMultiVarDims()
Set the manager as handling a formula with multiple variable dimensions.
Int_t fMultiplicity
Indicator of the variability of the formula.
~TTreeFormulaManager() override
Tree FormulaManager default destructor.
virtual void CancelDimension(Int_t virt_dim)
Cancel a dimension.
Int_t fCumulUsedSizes[kMAXFORMDIM+1]
Accumulated size of lower dimensions as seen for this entry.
Int_t fUsedSizes[kMAXFORMDIM+1]
Actual size of the dimensions as seen for this entry.
virtual Int_t GetNdata(bool forceLoadDim=false)
Return number of available instances in the formulas.
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 bool Sync()
Synchronize all the formulae.
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.
bool LoadCurrentDim()
Calculate the actual dimension for the current entry.
bool fHasCast
Record whether the formula contain a cast operation or not.
Int_t fMultiplicity
Indicator of the variability of the formula.
virtual Int_t GetMultiplicity() const
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...
TTreeFormulaManager * fManager
! The dimension coordinator.
TLine l
Definition textangle.C:4