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
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 {
79 if (old->fFormulas.GetLast() == -1) delete adding->fManager;
80 }
81 }
82
83 if (adding->TestBit(TTreeFormula::kNeedEntries)) {
85 }
86
88 adding->fManager = this;
89 fNeedSync = true;
90}
91
92////////////////////////////////////////////////////////////////////////////////
93/// Add a variable dimension
94
99
100////////////////////////////////////////////////////////////////////////////////
101/// Cancel a dimension. This is usually called when an out-of-bounds index
102/// is used.
103
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) {
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];
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++) {
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]))
195 else
197 } else {
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)
205 else {
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
300 current->UpdateFormulaLeaves();
301 }
302}
303
304////////////////////////////////////////////////////////////////////////////////
305/// Reload the array sizes
306
308{
309 if (vsize < 0)
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) {
318 } else {
320 }
321 }
323 virt_dim++;
324}
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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:84
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:41
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
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...
TLine l
Definition textangle.C:4