Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TChainIndex.cxx
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Marek Biskup 07/06/2005
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
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/** \class TChainIndex
13A Chain Index.
14A Chain Index with majorname and minorname.
15It uses tree indices of all the trees in the chain instead of building
16a new index.
17The index values from the first tree should be less then
18all the index values from the second tree, and so on.
19If a tree in the chain doesn't have an index the index will be created
20and kept inside this chain index.
21*/
22
23#include "TChainIndex.h"
24#include "TChain.h"
25#include "TTreeFormula.h"
26#include "TTreeIndex.h"
27#include "TFile.h"
28#include "TError.h"
29
30////////////////////////////////////////////////////////////////////////////////
31/// \class TChainIndex::TChainIndexEntry
32/// Holds a description of indices of trees in the chain.
33
35{
36 fMinIndexValue = index->GetIndexValues()[0];
37 fMinIndexValMinor = index->GetIndexValuesMinor()[0];
38 fMaxIndexValue = index->GetIndexValues()[index->GetN() - 1];
39 fMaxIndexValMinor = index->GetIndexValuesMinor()[index->GetN() - 1];
40}
41
43
44////////////////////////////////////////////////////////////////////////////////
45/// Default constructor for TChainIndex
46
48{
49 fTree = 0;
51}
52
53////////////////////////////////////////////////////////////////////////////////
54/// Normal constructor for TChainIndex. See TTreeIndex::TTreeIndex for the description of the
55/// parameters.
56/// The tree must be a TChain.
57/// All the index values in the first tree of the chain must be
58/// less then any index value in the second one, and so on.
59/// If any of those requirements isn't met the object becomes a zombie.
60/// If some subtrees don't have indices the indices are created and stored inside this
61/// TChainIndex.
62
63TChainIndex::TChainIndex(const TTree *T, const char *majorname, const char *minorname)
65{
66 fTree = 0;
68
69 TChain *chain = dynamic_cast<TChain*>(const_cast<TTree*>(T));
70 if (!chain) {
71 MakeZombie();
72 Error("TChainIndex", "Cannot create a TChainIndex."
73 " The Tree passed as an argument is not a TChain");
74 return;
75 }
76
77 fTree = (TTree*)T;
78 fMajorName = majorname;
79 fMinorName = minorname;
80 Int_t i = 0;
81
82 // Go through all the trees and check if they have indeces. If not then build them.
83 for (i = 0; i < chain->GetNtrees(); i++) {
84 chain->LoadTree((chain->GetTreeOffset())[i]);
86
87 TChainIndexEntry entry;
88 entry.fTreeIndex = 0;
89
90 //if an index already exists, we must check if major/minorname correspond
91 //to the major/minor names in this function call
92 if (index) {
93 if (strcmp(majorname,index->GetMajorName()) || strcmp(minorname,index->GetMinorName())) {
94 MakeZombie();
95 Error("TChainIndex","Tree in file %s has an index built with majorname=%s and minorname=%s",chain->GetTree()->GetCurrentFile()->GetName(),index->GetMajorName(),index->GetMinorName());
96 return;
97 }
98 }
99 if (!index) {
100 chain->GetTree()->BuildIndex(majorname, minorname);
101 index = chain->GetTree()->GetTreeIndex();
102 chain->GetTree()->SetTreeIndex(0);
103 entry.fTreeIndex = index;
104 }
105 if (!index || index->IsZombie() || index->GetN() == 0) {
107 MakeZombie();
108 Error("TChainIndex", "Error creating a tree index on a tree in the chain");
109 return;
110 }
111
112 TTreeIndex *ti_index = dynamic_cast<TTreeIndex*>(index);
113 if (ti_index == 0) {
114 Error("TChainIndex", "The underlying TTree must have a TTreeIndex but has a %s.",
115 index->IsA()->GetName());
116 return;
117 }
118
119 entry.SetMinMaxFrom(ti_index);
120 fEntries.push_back(entry);
121 }
122
123 // Check if the indices of different trees are in order. If not then return an error.
124 for (i = 0; i < Int_t(fEntries.size() - 1); i++) {
125 if( fEntries[i].GetMaxIndexValPair() > fEntries[i+1].GetMinIndexValPair() ) {
127 MakeZombie();
128 Error("TChainIndex", "The indices in files of this chain aren't sorted.");
129 }
130 }
131}
132
133////////////////////////////////////////////////////////////////////////////////
134/// Add an index to this chain.
135/// if delaySort is kFALSE (default) check if the indices of different trees are in order.
136
138{
139 if (index) {
140 const TTreeIndex *ti_index = dynamic_cast<const TTreeIndex*>(index);
141 if (ti_index == 0) {
142 Error("Append", "The given index is not a TTreeIndex but a %s",
143 index->IsA()->GetName());
144 }
145
146 TChainIndexEntry entry;
147 entry.fTreeIndex = 0;
148 entry.SetMinMaxFrom(ti_index);
149 fEntries.push_back(entry);
150 }
151
152 if (!delaySort) {
153 // Check if the indices of different trees are in order. If not then return an error.
154 for (Int_t i = 0; i < Int_t(fEntries.size() - 1); i++) {
155 if( fEntries[i].GetMaxIndexValPair() > fEntries[i+1].GetMinIndexValPair() ) {
157 MakeZombie();
158 Error("Append", "The indices in files of this chain aren't sorted.");
159 }
160 }
161 }
162}
163
164////////////////////////////////////////////////////////////////////////////////
165/// Delete all the indices which were built by this object.
166
168{
169 for (unsigned int i = 0; i < fEntries.size(); i++) {
170 if (fEntries[i].fTreeIndex) {
171 if (fTree->GetTree() && fTree->GetTree()->GetTreeIndex() == fEntries[i].fTreeIndex) {
173 SafeDelete(fEntries[i].fTreeIndex);
174 }
175 SafeDelete(fEntries[i].fTreeIndex);
176 }
177 }
178}
179
180////////////////////////////////////////////////////////////////////////////////
181/// The destructor.
182
184{
185 if (fTree) {
187 if (fTree->GetTreeIndex() == this)
188 fTree->SetTreeIndex(nullptr);
189 }
190}
191
192////////////////////////////////////////////////////////////////////////////////
193/// Returns a TVirtualIndex for a tree which holds the entry with the specified
194/// major and minor values and the number of that tree.
195/// If the index for that tree was created by this object it's set to the tree.
196/// The tree index should be later released using ReleaseSubTreeIndex();
197
198std::pair<TVirtualIndex*, Int_t> TChainIndex::GetSubTreeIndex(Long64_t major, Long64_t minor) const
199{
200 using namespace std;
201 if (fEntries.size() == 0) {
202 Warning("GetSubTreeIndex", "No subindices in the chain. The chain is probably empty");
203 return make_pair(static_cast<TVirtualIndex*>(0), 0);
204 }
205
206 const TChainIndexEntry::IndexValPair_t indexValue(major, minor);
207
208 if( indexValue < fEntries[0].GetMinIndexValPair() ) {
209 Warning("GetSubTreeIndex", "The index value is less than the smallest index values in subtrees");
210 return make_pair(static_cast<TVirtualIndex*>(0), 0);
211 }
212
213 Int_t treeNo = fEntries.size() - 1;
214 for (unsigned int i = 0; i < fEntries.size() - 1; i++) {
215 if( indexValue < fEntries[i+1].GetMinIndexValPair() ) {
216 treeNo = i;
217 break;
218 }
219 }
220 // Double check we found the right range.
221 if( indexValue > fEntries[treeNo].GetMaxIndexValPair() ) {
222 return make_pair(static_cast<TVirtualIndex*>(0), 0);
223 }
224 TChain* chain = dynamic_cast<TChain*> (fTree);
225 R__ASSERT(chain);
226 chain->LoadTree(chain->GetTreeOffset()[treeNo]);
228 if (index)
229 return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
230 else {
231 index = fEntries[treeNo].fTreeIndex;
232 if (!index) {
233 Warning("GetSubTreeIndex", "The tree has no index and the chain index"
234 " doesn't store an index for that tree");
235 return make_pair(static_cast<TVirtualIndex*>(0), 0);
236 }
237 else {
239 return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
240 }
241 }
242}
243
244////////////////////////////////////////////////////////////////////////////////
245/// Releases the tree index got using GetSubTreeIndex. If the index was
246/// created by this object it is removed from the current tree, so that it isn't
247/// deleted in its destructor.
248
250{
251 if (fEntries[treeNo].fTreeIndex == index) {
254 }
255}
256
257////////////////////////////////////////////////////////////////////////////////
258/// See TTreeIndex::GetEntryNumberFriend for description
259
261{
262 if (!parent) return -3;
263 GetMajorFormulaParent(parent);
264 GetMinorFormulaParent(parent);
265 if (!fMajorFormulaParent || !fMinorFormulaParent) return -1;
267 // The Tree Index in the friend has a pair majorname,minorname
268 // not available in the parent Tree T.
269 // if the friend Tree has less entries than the parent, this is an error
270 Long64_t pentry = parent->GetReadEntry();
271 if (pentry >= fTree->GetEntries()) return -2;
272 // otherwise we ignore the Tree Index and return the entry number
273 // in the parent Tree.
274 return pentry;
275 }
276
277 // majorname, minorname exist in the parent Tree
278 // we find the current values pair majorv,minorv in the parent Tree
281 Long64_t majorv = (Long64_t)majord;
282 Long64_t minorv = (Long64_t)minord;
283 // we check if this pair exist in the index.
284 // if yes, we return the corresponding entry number
285 // if not the function returns -1
286 return fTree->GetEntryNumberWithIndex(majorv,minorv);
287}
288
289////////////////////////////////////////////////////////////////////////////////
290/// See TTreeIndex::GetEntryNumberWithBestIndex for details.
291
293{
294 std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
295 if (!indexAndNumber.first) {
296 // Error("GetEntryNumberWithBestIndex","no index found");
297 return -1;
298 }
299 else {
300 Long64_t rv = indexAndNumber.first->GetEntryNumberWithBestIndex(major, minor);
301 ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
302 TChain* chain = dynamic_cast<TChain*> (fTree);
303 R__ASSERT(chain);
304 return rv + chain->GetTreeOffset()[indexAndNumber.second];
305 }
306}
307
308////////////////////////////////////////////////////////////////////////////////
309/// Returns the entry number with given index values.
310/// See TTreeIndex::GetEntryNumberWithIndex for details.
311
313{
314 std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
315 if (!indexAndNumber.first) {
316 // Error("GetEntryNumberWithIndex","no index found");
317 return -1;
318 }
319 else {
320 Long64_t rv = indexAndNumber.first->GetEntryNumberWithIndex(major, minor);
321 ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
322 TChain* chain = dynamic_cast<TChain*> (fTree);
323 R__ASSERT(chain);
324 if (rv >= 0) {
325 return rv + chain->GetTreeOffset()[indexAndNumber.second];
326 } else {
327 return rv;
328 }
329 }
330}
331
332////////////////////////////////////////////////////////////////////////////////
333/// Return a pointer to the TreeFormula corresponding to the majorname in parent tree T.
334
336{
337 if (!fMajorFormulaParent) {
339 fMajorFormulaParent = new TTreeFormula("MajorP",fMajorName.Data(),const_cast<TTree*>(parent));
341 }
342 if (fMajorFormulaParent->GetTree() != parent) {
343 fMajorFormulaParent->SetTree(const_cast<TTree*>(parent));
345 }
346 return fMajorFormulaParent;
347}
348
349////////////////////////////////////////////////////////////////////////////////
350/// Return a pointer to the TreeFormula corresponding to the minorname in parent tree T.
351
353{
354 if (!fMinorFormulaParent) {
355 // Prevent TTreeFormula from finding any of the branches in our TTree even if it
356 // is a friend of the parent TTree.
358 fMinorFormulaParent = new TTreeFormula("MinorP",fMinorName.Data(),const_cast<TTree*>(parent));
360 }
361 if (fMinorFormulaParent->GetTree() != parent) {
362 fMinorFormulaParent->SetTree(const_cast<TTree*>(parent));
364 }
365
366 return fMinorFormulaParent;
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// Return kTRUE if index can be applied to the TTree
371
373{
374 auto *majorFormula = GetMajorFormulaParent(parent);
375 auto *minorFormula = GetMinorFormulaParent(parent);
376 if ((majorFormula == nullptr || majorFormula->GetNdim() == 0) ||
377 (minorFormula == nullptr || minorFormula->GetNdim() == 0))
378 return kFALSE;
379 return kTRUE;
380}
381
382////////////////////////////////////////////////////////////////////////////////
383/// Updates the parent formulae.
384/// Called by TChain::LoadTree when the parent chain changes it's tree.
385
387{
389 // Prevent TTreeFormula from finding any of the branches in our TTree even if it
390 // is a friend of the parent TTree.
392 if (parent) fMajorFormulaParent->SetTree((TTree*)parent);
394 }
396 if (parent) fMinorFormulaParent->SetTree((TTree*)parent);
398 }
399}
400
401////////////////////////////////////////////////////////////////////////////////
402/// See TTreeIndex::SetTree.
403
405{
406 R__ASSERT(fTree == 0 || fTree == T || T==0);
407 fTree = T;
408}
409
#define SafeDelete(p)
Definition RConfig.hxx:525
int Int_t
Definition RtypesCore.h:45
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:377
#define R__ASSERT(e)
Definition TError.h:118
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
virtual Int_t GetNdim() const
Definition TFormula.h:237
Holds a description of indices of trees in the chain.
Definition TChainIndex.h:43
std::pair< Long64_t, Long64_t > IndexValPair_t
Definition TChainIndex.h:50
void SetMinMaxFrom(const TTreeIndex *index)
A Chain Index.
Definition TChainIndex.h:40
std::vector< TChainIndexEntry > fEntries
Pointer to minor TreeFormula in Parent tree (if any)
Definition TChainIndex.h:69
TTreeFormula * fMinorFormulaParent
Pointer to major TreeFormula in Parent tree (if any)
Definition TChainIndex.h:68
void Append(const TVirtualIndex *, Bool_t delaySort=kFALSE) override
Add an index to this chain.
~TChainIndex() override
The destructor.
TString fMinorName
Definition TChainIndex.h:66
std::pair< TVirtualIndex *, Int_t > GetSubTreeIndex(Long64_t major, Long64_t minor) const
Returns a TVirtualIndex for a tree which holds the entry with the specified major and minor values an...
Long64_t GetEntryNumberWithIndex(Long64_t major, Long64_t minor) const override
Returns the entry number with given index values.
void ReleaseSubTreeIndex(TVirtualIndex *index, Int_t treeNo) const
Releases the tree index got using GetSubTreeIndex.
Long64_t GetEntryNumberWithBestIndex(Long64_t major, Long64_t minor) const override
See TTreeIndex::GetEntryNumberWithBestIndex for details.
void UpdateFormulaLeaves(const TTree *parent) override
Updates the parent formulae.
TChainIndex()
Default constructor for TChainIndex.
void DeleteIndices()
Delete all the indices which were built by this object.
TString fMajorName
Definition TChainIndex.h:65
TTreeFormula * fMajorFormulaParent
Definition TChainIndex.h:67
Long64_t GetEntryNumberFriend(const TTree *parent) override
See TTreeIndex::GetEntryNumberFriend for description.
TTreeFormula * GetMajorFormulaParent(const TTree *parent)
Return a pointer to the TreeFormula corresponding to the majorname in parent tree T.
Bool_t IsValidFor(const TTree *parent) override
Return kTRUE if index can be applied to the TTree.
void SetTree(TTree *T) override
See TTreeIndex::SetTree.
TTreeFormula * GetMinorFormulaParent(const TTree *parent)
Return a pointer to the TreeFormula corresponding to the minorname in parent tree T.
A chain is a collection of files containing TTree objects.
Definition TChain.h:33
TTree * GetTree() const override
Definition TChain.h:119
Long64_t * GetTreeOffset() const
Definition TChain.h:121
Long64_t LoadTree(Long64_t entry) override
Find the tree which contains entry, and set it as the current tree.
Definition TChain.cxx:1296
Int_t GetNtrees() const
Definition TChain.h:99
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:973
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:987
void MakeZombie()
Definition TObject.h:53
const char * Data() const
Definition TString.h:380
Used to pass a selection expression to the Tree drawing routine.
virtual void SetTree(TTree *tree)
T EvalInstance(Int_t i=0, const char *stringStack[]=nullptr)
Evaluate this treeformula.
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
virtual TTree * GetTree() const
void SetQuickLoad(Bool_t quick)
A Tree Index with majorname and minorname.
Definition TTreeIndex.h:29
Helper class to prevent infinite recursion in the usage of TTree Friends.
Definition TTree.h:188
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual Long64_t GetEntryNumberWithIndex(Long64_t major, Long64_t minor=0) const
Return entry number corresponding to major and minor number.
Definition TTree.cxx:5907
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition TTree.cxx:5476
virtual Int_t BuildIndex(const char *majorname, const char *minorname="0")
Build a Tree Index (default is TTreeIndex).
Definition TTree.cxx:2637
virtual TVirtualIndex * GetTreeIndex() const
Definition TTree.h:518
virtual Long64_t GetEntries() const
Definition TTree.h:463
virtual Long64_t GetReadEntry() const
Definition TTree.h:509
virtual TTree * GetTree() const
Definition TTree.h:517
@ kFindBranch
Definition TTree.h:212
@ kFindLeaf
Definition TTree.h:213
@ kGetBranch
Definition TTree.h:215
@ kGetLeaf
Definition TTree.h:220
virtual void SetTreeIndex(TVirtualIndex *index)
The current TreeIndex is replaced by the new index.
Definition TTree.cxx:9333
Abstract interface for Tree Index.