Logo ROOT   6.18/05
Reference Guide
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];
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]);
85 TVirtualIndex *index = chain->GetTree()->GetTreeIndex();
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
137void TChainIndex::Append(const TVirtualIndex *index, Bool_t delaySort )
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{
186 if (fTree && fTree->GetTreeIndex() == this)
188}
189
190////////////////////////////////////////////////////////////////////////////////
191/// Returns a TVirtualIndex for a tree which holds the entry with the specified
192/// major and minor values and the number of that tree.
193/// If the index for that tree was created by this object it's set to the tree.
194/// The tree index should be later released using ReleaseSubTreeIndex();
195
196std::pair<TVirtualIndex*, Int_t> TChainIndex::GetSubTreeIndex(Long64_t major, Long64_t minor) const
197{
198 using namespace std;
199 if (fEntries.size() == 0) {
200 Warning("GetSubTreeIndex", "No subindices in the chain. The chain is probably empty");
201 return make_pair(static_cast<TVirtualIndex*>(0), 0);
202 }
203
204 const TChainIndexEntry::IndexValPair_t indexValue(major, minor);
205
206 if( indexValue < fEntries[0].GetMinIndexValPair() ) {
207 Warning("GetSubTreeIndex", "The index value is less than the smallest index values in subtrees");
208 return make_pair(static_cast<TVirtualIndex*>(0), 0);
209 }
210
211 Int_t treeNo = fEntries.size() - 1;
212 for (unsigned int i = 0; i < fEntries.size() - 1; i++) {
213 if( indexValue < fEntries[i+1].GetMinIndexValPair() ) {
214 treeNo = i;
215 break;
216 }
217 }
218 // Double check we found the right range.
219 if( indexValue > fEntries[treeNo].GetMaxIndexValPair() ) {
220 return make_pair(static_cast<TVirtualIndex*>(0), 0);
221 }
222 TChain* chain = dynamic_cast<TChain*> (fTree);
223 R__ASSERT(chain);
224 chain->LoadTree(chain->GetTreeOffset()[treeNo]);
226 if (index)
227 return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
228 else {
229 index = fEntries[treeNo].fTreeIndex;
230 if (!index) {
231 Warning("GetSubTreeIndex", "The tree has no index and the chain index"
232 " doesn't store an index for that tree");
233 return make_pair(static_cast<TVirtualIndex*>(0), 0);
234 }
235 else {
236 fTree->GetTree()->SetTreeIndex(index);
237 return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
238 }
239 }
240}
241
242////////////////////////////////////////////////////////////////////////////////
243/// Releases the tree index got using GetSubTreeIndex. If the index was
244/// created by this object it is removed from the current tree, so that it isn't
245/// deleted in its destructor.
246
248{
249 if (fEntries[treeNo].fTreeIndex == index) {
250 R__ASSERT(fTree->GetTree()->GetTreeIndex() == index);
252 }
253}
254
255////////////////////////////////////////////////////////////////////////////////
256/// See TTreeIndex::GetEntryNumberFriend for description
257
259{
260 if (!parent) return -3;
261 GetMajorFormulaParent(parent);
262 GetMinorFormulaParent(parent);
263 if (!fMajorFormulaParent || !fMinorFormulaParent) return -1;
265 // The Tree Index in the friend has a pair majorname,minorname
266 // not available in the parent Tree T.
267 // if the friend Tree has less entries than the parent, this is an error
268 Long64_t pentry = parent->GetReadEntry();
269 if (pentry >= fTree->GetEntries()) return -2;
270 // otherwise we ignore the Tree Index and return the entry number
271 // in the parent Tree.
272 return pentry;
273 }
274
275 // majorname, minorname exist in the parent Tree
276 // we find the current values pair majorv,minorv in the parent Tree
279 Long64_t majorv = (Long64_t)majord;
280 Long64_t minorv = (Long64_t)minord;
281 // we check if this pair exist in the index.
282 // if yes, we return the corresponding entry number
283 // if not the function returns -1
284 return fTree->GetEntryNumberWithIndex(majorv,minorv);
285}
286
287////////////////////////////////////////////////////////////////////////////////
288/// See TTreeIndex::GetEntryNumberWithBestIndex for details.
289
291{
292 std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
293 if (!indexAndNumber.first) {
294 // Error("GetEntryNumberWithBestIndex","no index found");
295 return -1;
296 }
297 else {
298 Long64_t rv = indexAndNumber.first->GetEntryNumberWithBestIndex(major, minor);
299 ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
300 TChain* chain = dynamic_cast<TChain*> (fTree);
301 R__ASSERT(chain);
302 return rv + chain->GetTreeOffset()[indexAndNumber.second];
303 }
304}
305
306////////////////////////////////////////////////////////////////////////////////
307/// Returns the entry number with given index values.
308/// See TTreeIndex::GetEntryNumberWithIndex for details.
309
311{
312 std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
313 if (!indexAndNumber.first) {
314 // Error("GetEntryNumberWithIndex","no index found");
315 return -1;
316 }
317 else {
318 Long64_t rv = indexAndNumber.first->GetEntryNumberWithIndex(major, minor);
319 ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
320 TChain* chain = dynamic_cast<TChain*> (fTree);
321 R__ASSERT(chain);
322 if (rv >= 0) {
323 return rv + chain->GetTreeOffset()[indexAndNumber.second];
324 } else {
325 return rv;
326 }
327 }
328}
329
330////////////////////////////////////////////////////////////////////////////////
331/// Return a pointer to the TreeFormula corresponding to the majorname in parent tree T.
332
334{
335 if (!fMajorFormulaParent) {
337 fMajorFormulaParent = new TTreeFormula("MajorP",fMajorName.Data(),const_cast<TTree*>(parent));
339 }
340 if (fMajorFormulaParent->GetTree() != parent) {
341 fMajorFormulaParent->SetTree(const_cast<TTree*>(parent));
343 }
344 return fMajorFormulaParent;
345}
346
347////////////////////////////////////////////////////////////////////////////////
348/// Return a pointer to the TreeFormula corresponding to the minorname in parent tree T.
349
351{
352 if (!fMinorFormulaParent) {
353 // Prevent TTreeFormula from finding any of the branches in our TTree even if it
354 // is a friend of the parent TTree.
356 fMinorFormulaParent = new TTreeFormula("MinorP",fMinorName.Data(),const_cast<TTree*>(parent));
358 }
359 if (fMinorFormulaParent->GetTree() != parent) {
360 fMinorFormulaParent->SetTree(const_cast<TTree*>(parent));
362 }
363
364 return fMinorFormulaParent;
365}
366
367////////////////////////////////////////////////////////////////////////////////
368/// Updates the parent formulae.
369/// Called by TChain::LoadTree when the parent chain changes it's tree.
370
372{
374 // Prevent TTreeFormula from finding any of the branches in our TTree even if it
375 // is a friend of the parent TTree.
377 if (parent) fMajorFormulaParent->SetTree((TTree*)parent);
379 }
381 if (parent) fMinorFormulaParent->SetTree((TTree*)parent);
383 }
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// See TTreeIndex::SetTree.
388
390{
391 R__ASSERT(fTree == 0 || fTree == T || T==0);
392}
393
#define SafeDelete(p)
Definition: RConfig.hxx:543
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
#define R__ASSERT(e)
Definition: TError.h:96
virtual Int_t GetNdim() const
Definition: TFormula.h:237
Holds a description of indices of trees in the chain.
Definition: TChainIndex.h:42
std::pair< Long64_t, Long64_t > IndexValPair_t
Definition: TChainIndex.h:49
TVirtualIndex * fTreeIndex
Definition: TChainIndex.h:59
void SetMinMaxFrom(const TTreeIndex *index)
Definition: TChainIndex.cxx:34
A Chain Index.
Definition: TChainIndex.h:39
std::vector< TChainIndexEntry > fEntries
Pointer to minor TreeFormula in Parent tree (if any)
Definition: TChainIndex.h:68
TTreeFormula * fMinorFormulaParent
Pointer to major TreeFormula in Parent tree (if any)
Definition: TChainIndex.h:67
virtual void UpdateFormulaLeaves(const TTree *parent)
Updates the parent formulae.
virtual ~TChainIndex()
The destructor.
virtual Long64_t GetEntryNumberWithBestIndex(Long64_t major, Long64_t minor) const
See TTreeIndex::GetEntryNumberWithBestIndex for details.
virtual Long64_t GetEntryNumberFriend(const TTree *parent)
See TTreeIndex::GetEntryNumberFriend for description.
TString fMinorName
Definition: TChainIndex.h:65
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...
virtual void Append(const TVirtualIndex *, Bool_t delaySort=kFALSE)
Add an index to this chain.
virtual void SetTree(const TTree *T)
See TTreeIndex::SetTree.
void ReleaseSubTreeIndex(TVirtualIndex *index, Int_t treeNo) const
Releases the tree index got using GetSubTreeIndex.
TChainIndex()
Default constructor for TChainIndex.
Definition: TChainIndex.cxx:47
void DeleteIndices()
Delete all the indices which were built by this object.
virtual Long64_t GetEntryNumberWithIndex(Long64_t major, Long64_t minor) const
Returns the entry number with given index values.
TString fMajorName
Definition: TChainIndex.h:64
TTreeFormula * fMajorFormulaParent
Definition: TChainIndex.h:66
virtual TTreeFormula * GetMajorFormulaParent(const TTree *parent)
Return a pointer to the TreeFormula corresponding to the majorname in parent tree T.
virtual 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:34
virtual Long64_t LoadTree(Long64_t entry)
Find the tree which contains entry, and set it as the current tree.
Definition: TChain.cxx:1277
virtual TTree * GetTree() const
Definition: TChain.h:116
Long64_t * GetTreeOffset() const
Definition: TChain.h:118
Int_t GetNtrees() const
Definition: TChain.h:96
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition: TObject.h:134
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
void MakeZombie()
Definition: TObject.h:49
const char * Data() const
Definition: TString.h:364
Used to pass a selection expression to the Tree drawing routine.
Definition: TTreeFormula.h:58
T EvalInstance(Int_t i=0, const char *stringStack[]=0)
Evaluate this treeformula.
virtual void SetTree(TTree *tree)
Definition: TTreeFormula.h:208
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
virtual TTree * GetTree() const
Definition: TTreeFormula.h:210
void SetQuickLoad(Bool_t quick)
Definition: TTreeFormula.h:207
A Tree Index with majorname and minorname.
Definition: TTreeIndex.h:28
virtual Long64_t * GetIndexValues() const
Definition: TTreeIndex.h:57
virtual Long64_t * GetIndexValuesMinor() const
Definition: TTreeIndex.cxx:427
virtual Long64_t GetN() const
Definition: TTreeIndex.h:61
Helper class to prevent infinite recursion in the usage of TTree Friends.
Definition: TTree.h:174
A TTree represents a columnar dataset.
Definition: TTree.h:71
virtual Long64_t GetEntryNumberWithIndex(Long64_t major, Long64_t minor=0) const
Return entry number corresponding to major and minor number.
Definition: TTree.cxx:5695
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition: TTree.cxx:5263
virtual Int_t BuildIndex(const char *majorname, const char *minorname="0")
Build a Tree Index (default is TTreeIndex).
Definition: TTree.cxx:2542
virtual TVirtualIndex * GetTreeIndex() const
Definition: TTree.h:457
virtual Long64_t GetEntries() const
Definition: TTree.h:402
virtual Long64_t GetReadEntry() const
Definition: TTree.h:448
virtual TTree * GetTree() const
Definition: TTree.h:456
@ kFindBranch
Definition: TTree.h:198
@ kFindLeaf
Definition: TTree.h:199
@ kGetBranch
Definition: TTree.h:201
@ kGetLeaf
Definition: TTree.h:206
virtual void SetTreeIndex(TVirtualIndex *index)
The current TreeIndex is replaced by the new index.
Definition: TTree.cxx:8942
Abstract interface for Tree Index.
Definition: TVirtualIndex.h:29
virtual const char * GetMajorName() const =0
virtual const char * GetMinorName() const =0
virtual Long64_t GetN() const =0
double T(double x)
Definition: ChebyshevPol.h:34