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