Logo ROOT   6.10/09
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
13 A Chain Index.
14 A Chain Index with majorname and minorname.
15 It uses tree indices of all the trees in the chain instead of building
16 a new index.
17 The index values from the first tree should be less then
18 all the index values from the second tree, and so on.
19 If a tree in the chain doesn't have an index the index will be created
20 and 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 
63 TChainIndex::TChainIndex(const TTree *T, const char *majorname, const char *minorname)
64  : TVirtualIndex()
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) {
106  DeleteIndices();
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() ) {
126  DeleteIndices();
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 
137 void 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() ) {
156  DeleteIndices();
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) {
172  fTree->GetTree()->SetTreeIndex(0);
173  SafeDelete(fEntries[i].fTreeIndex);
174  }
175  SafeDelete(fEntries[i].fTreeIndex);
176  }
177  }
178 }
179 
180 ////////////////////////////////////////////////////////////////////////////////
181 /// The destructor.
182 
184 {
185  DeleteIndices();
186  if (fTree && fTree->GetTreeIndex() == this)
187  fTree->SetTreeIndex(0);
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 
196 std::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]);
225  TVirtualIndex* index = fTree->GetTree()->GetTreeIndex();
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 
247 void TChainIndex::ReleaseSubTreeIndex(TVirtualIndex* index, int treeNo) const
248 {
249  if (fEntries[treeNo].fTreeIndex == index) {
250  R__ASSERT(fTree->GetTree()->GetTreeIndex() == index);
251  fTree->GetTree()->SetTreeIndex(0);
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 
371 void TChainIndex::UpdateFormulaLeaves(const TTree *parent)
372 {
373  if (fMajorFormulaParent) {
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  }
380  if (fMinorFormulaParent) {
381  if (parent) fMinorFormulaParent->SetTree((TTree*)parent);
383  }
384 }
385 
386 ////////////////////////////////////////////////////////////////////////////////
387 /// See TTreeIndex::SetTree.
388 
389 void TChainIndex::SetTree(const TTree *T)
390 {
391  R__ASSERT(fTree == 0 || fTree == T || T==0);
392 }
393 
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TVirtualIndex * fTreeIndex
Definition: TChainIndex.h:59
long long Long64_t
Definition: RtypesCore.h:69
Abstract interface for Tree Index.
Definition: TVirtualIndex.h:29
virtual Long64_t GetN() const
Definition: TTreeIndex.h:61
virtual Long64_t GetEntryNumberFriend(const TTree *parent)
See TTreeIndex::GetEntryNumberFriend for description.
double T(double x)
Definition: ChebyshevPol.h:34
std::pair< Long64_t, Long64_t > IndexValPair_t
Definition: TChainIndex.h:49
virtual ~TChainIndex()
The destructor.
#define R__ASSERT(e)
Definition: TError.h:96
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
virtual void SetTree(const TTree *T)
See TTreeIndex::SetTree.
STL namespace.
virtual void SetTree(TTree *tree)
Definition: TTreeFormula.h:208
void SetMinMaxFrom(const TTreeIndex *index)
Definition: TChainIndex.cxx:34
A Tree Index with majorname and minorname.
Definition: TTreeIndex.h:28
Long64_t * GetTreeOffset() const
Definition: TChain.h:117
virtual Int_t GetNdim() const
Definition: TFormula.h:237
TString fMinorName
Definition: TChainIndex.h:65
virtual Long64_t GetEntryNumberWithBestIndex(Long64_t major, Long64_t minor) const
See TTreeIndex::GetEntryNumberWithBestIndex for details.
#define SafeDelete(p)
Definition: RConfig.h:499
virtual void SetTreeIndex(TVirtualIndex *index)
The current TreeIndex is replaced by the new index.
Definition: TTree.cxx:8735
virtual Int_t BuildIndex(const char *majorname, const char *minorname="0")
Build a Tree Index (default is TTreeIndex).
Definition: TTree.cxx:2545
virtual Long64_t LoadTree(Long64_t entry)
Find the tree which contains entry, and set it as the current tree.
Definition: TChain.cxx:1259
Used to pass a selection expression to the Tree drawing routine.
Definition: TTreeFormula.h:58
virtual TTree * GetTree() const
Definition: TTree.h:432
virtual Long64_t * GetIndexValuesMinor() const
Definition: TTreeIndex.cxx:427
virtual TTreeFormula * GetMinorFormulaParent(const TTree *parent)
Return a pointer to the TreeFormula corresponding to the minorname in parent tree T...
virtual TVirtualIndex * GetTreeIndex() const
Definition: TTree.h:433
virtual Long64_t * GetIndexValues() const
Definition: TTreeIndex.h:57
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition: TTree.cxx:5163
virtual Long64_t GetN() const =0
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
virtual void Append(const TVirtualIndex *, Bool_t delaySort=kFALSE)
Add an index to this chain.
std::vector< TChainIndexEntry > fEntries
Pointer to minor TreeFormula in Parent tree (if any)
Definition: TChainIndex.h:68
TTreeFormula * fMajorFormulaParent
Definition: TChainIndex.h:66
#define ClassImp(name)
Definition: Rtypes.h:336
Bool_t IsZombie() const
Definition: TObject.h:122
void ReleaseSubTreeIndex(TVirtualIndex *index, Int_t treeNo) const
Releases the tree index got using GetSubTreeIndex.
double Double_t
Definition: RtypesCore.h:55
virtual TTreeFormula * GetMajorFormulaParent(const TTree *parent)
Return a pointer to the TreeFormula corresponding to the majorname in parent tree T...
T EvalInstance(Int_t i=0, const char *stringStack[]=0)
Evaluate this treeformula.
Helper class to prevent infinite recursion in the usage of TTree Friends.
Definition: TTree.h:172
Int_t GetNtrees() const
Definition: TChain.h:95
virtual TTree * GetTree() const
Definition: TTreeFormula.h:210
virtual TTree * GetTree() const
Definition: TChain.h:115
TChainIndex()
Default constructor for TChainIndex.
Definition: TChainIndex.cxx:47
void DeleteIndices()
Delete all the indices which were built by this object.
void MakeZombie()
Definition: TObject.h:49
A chain is a collection of files containing TTree objects.
Definition: TChain.h:33
virtual const char * GetMinorName() const =0
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 const char * GetMajorName() const =0
virtual void UpdateFormulaLeaves(const TTree *parent)
Updates the parent formulae.
TTreeFormula * fMinorFormulaParent
Pointer to major TreeFormula in Parent tree (if any)
Definition: TChainIndex.h:67
A TTree object has a header with a name and a title.
Definition: TTree.h:78
void SetQuickLoad(Bool_t quick)
Definition: TTreeFormula.h:207
TString fMajorName
Definition: TChainIndex.h:64
const Bool_t kTRUE
Definition: RtypesCore.h:91
virtual Long64_t GetEntryNumberWithIndex(Long64_t major, Long64_t minor) const
Returns the entry number with given index values.
Holds a description of indices of trees in the chain.
Definition: TChainIndex.h:42
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:859
A Chain Index.
Definition: TChainIndex.h:39