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#include <cstring> // std::strlen
31
32////////////////////////////////////////////////////////////////////////////////
33/// \class TChainIndex::TChainIndexEntry
34/// Holds a description of indices of trees in the chain.
35
37{
38 fMinIndexValue = index->GetIndexValues()[0];
39 fMinIndexValMinor = index->GetIndexValuesMinor()[0];
40 fMaxIndexValue = index->GetIndexValues()[index->GetN() - 1];
41 fMaxIndexValMinor = index->GetIndexValuesMinor()[index->GetN() - 1];
42}
43
45{
46 std::swap(fMinIndexValue, other.fMinIndexValue);
47 std::swap(fMinIndexValMinor, other.fMinIndexValMinor);
48 std::swap(fMaxIndexValue, other.fMaxIndexValue);
49 std::swap(fMaxIndexValMinor, other.fMaxIndexValMinor);
50 std::swap(fTreeIndex, other.fTreeIndex);
51}
52
54{
55 fMinIndexValue = other.fMinIndexValue;
56 fMinIndexValMinor = other.fMinIndexValMinor;
57 fMaxIndexValue = other.fMaxIndexValue;
58 fMaxIndexValMinor = other.fMaxIndexValMinor;
59 fTreeIndex = (other.fTreeIndex ? static_cast<TVirtualIndex *>(other.fTreeIndex->Clone()) : nullptr);
60}
61
63
64////////////////////////////////////////////////////////////////////////////////
65/// Default constructor for TChainIndex
66
68{
69 fTree = nullptr;
71}
72
73////////////////////////////////////////////////////////////////////////////////
74/// Normal constructor for TChainIndex. See TTreeIndex::TTreeIndex for the description of the
75/// parameters.
76/// The tree must be a TChain.
77/// All the index values in the first tree of the chain must be
78/// less then any index value in the second one, and so on.
79/// If any of those requirements isn't met the object becomes a zombie.
80/// If some subtrees don't have indices the indices are created and stored inside this
81/// TChainIndex.
82
83TChainIndex::TChainIndex(const TTree *T, const char *majorname, const char *minorname)
85{
86 fTree = nullptr;
88
89 TChain *chain = dynamic_cast<TChain*>(const_cast<TTree*>(T));
90 if (!chain) {
91 MakeZombie();
92 Error("TChainIndex", "Cannot create a TChainIndex."
93 " The Tree passed as an argument is not a TChain");
94 return;
95 }
96
97 fTree = (TTree*)T;
98 fMajorName = majorname;
99 fMinorName = minorname;
100 Int_t i = 0;
101
102 // Go through all the trees and check if they have indeces. If not then build them.
103 for (i = 0; i < chain->GetNtrees(); i++) {
104 chain->LoadTree((chain->GetTreeOffset())[i]);
106
107 TChainIndexEntry entry;
108 entry.fTreeIndex = nullptr;
109
110 //if an index already exists, we must check if major/minorname correspond
111 //to the major/minor names in this function call
112 if (index) {
113 if (strcmp(majorname,index->GetMajorName()) || strcmp(minorname,index->GetMinorName())) {
114 MakeZombie();
115 Error("TChainIndex","Tree in file %s has an index built with majorname=%s and minorname=%s",chain->GetTree()->GetCurrentFile()->GetName(),index->GetMajorName(),index->GetMinorName());
116 return;
117 }
118 }
119 if (!index) {
120 chain->GetTree()->BuildIndex(majorname, minorname);
121 index = chain->GetTree()->GetTreeIndex();
122 chain->GetTree()->SetTreeIndex(nullptr);
123 entry.fTreeIndex = index;
124 }
125 if (!index || index->IsZombie() || index->GetN() == 0) {
127 MakeZombie();
128 Error("TChainIndex", "Error creating a tree index on a tree in the chain");
129 return;
130 }
131
132 TTreeIndex *ti_index = dynamic_cast<TTreeIndex*>(index);
133 if (ti_index == nullptr) {
134 Error("TChainIndex", "The underlying TTree must have a TTreeIndex but has a %s.",
135 index->IsA()->GetName());
136 return;
137 }
138
139 entry.SetMinMaxFrom(ti_index);
140 fEntries.push_back(entry);
141 }
142
143 // Check if the indices of different trees are in order. If not then return an error.
144 for (i = 0; i < Int_t(fEntries.size() - 1); i++) {
145 if( fEntries[i].GetMaxIndexValPair() > fEntries[i+1].GetMinIndexValPair() ) {
147 MakeZombie();
148 Error("TChainIndex", "The indices in files of this chain aren't sorted.");
149 }
150 }
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// Add an index to this chain.
155/// if delaySort is false (default) check if the indices of different trees are in order.
156
157void TChainIndex::Append(const TVirtualIndex *index, bool delaySort )
158{
159 if (index) {
160 const TTreeIndex *ti_index = dynamic_cast<const TTreeIndex*>(index);
161 if (ti_index == nullptr) {
162 Error("Append", "The given index is not a TTreeIndex but a %s",
163 index->IsA()->GetName());
164 }
165
166 TChainIndexEntry entry;
167 entry.fTreeIndex = nullptr;
168 entry.SetMinMaxFrom(ti_index);
169 fEntries.push_back(entry);
170 }
171
172 if (!delaySort) {
173 // Check if the indices of different trees are in order. If not then return an error.
174 for (Int_t i = 0; i < Int_t(fEntries.size() - 1); i++) {
175 if( fEntries[i].GetMaxIndexValPair() > fEntries[i+1].GetMinIndexValPair() ) {
177 MakeZombie();
178 Error("Append", "The indices in files of this chain aren't sorted.");
179 }
180 }
181 }
182}
183
184////////////////////////////////////////////////////////////////////////////////
185/// Delete all the indices which were built by this object.
186
188{
189 for (unsigned int i = 0; i < fEntries.size(); i++) {
190 if (fEntries[i].fTreeIndex) {
191 if (fTree->GetTree() && fTree->GetTree()->GetTreeIndex() == fEntries[i].fTreeIndex) {
192 fTree->GetTree()->SetTreeIndex(nullptr);
193 SafeDelete(fEntries[i].fTreeIndex);
194 }
195 SafeDelete(fEntries[i].fTreeIndex);
196 }
197 }
198}
199
200////////////////////////////////////////////////////////////////////////////////
201/// The destructor.
202
204{
205 if (fTree) {
207 if (fTree->GetTreeIndex() == this)
208 fTree->SetTreeIndex(nullptr);
209 }
210}
211
212////////////////////////////////////////////////////////////////////////////////
213/// Returns a TVirtualIndex for a tree which holds the entry with the specified
214/// major and minor values and the number of that tree.
215/// If the index for that tree was created by this object it's set to the tree.
216/// The tree index should be later released using ReleaseSubTreeIndex();
217
218std::pair<TVirtualIndex*, Int_t> TChainIndex::GetSubTreeIndex(Long64_t major, Long64_t minor) const
219{
220 using std::make_pair;
221 if (fEntries.empty()) {
222 Warning("GetSubTreeIndex", "No subindices in the chain. The chain is probably empty");
223 return make_pair(static_cast<TVirtualIndex*>(nullptr), 0);
224 }
225
226 const TChainIndexEntry::IndexValPair_t indexValue(major, minor);
227
228 if( indexValue < fEntries[0].GetMinIndexValPair() ) {
229 Warning("GetSubTreeIndex", "The index value is less than the smallest index values in subtrees");
230 return make_pair(static_cast<TVirtualIndex*>(nullptr), 0);
231 }
232
233 Int_t treeNo = fEntries.size() - 1;
234 for (unsigned int i = 0; i < fEntries.size() - 1; i++) {
235 if( indexValue < fEntries[i+1].GetMinIndexValPair() ) {
236 treeNo = i;
237 break;
238 }
239 }
240 // Double check we found the right range.
241 if( indexValue > fEntries[treeNo].GetMaxIndexValPair() ) {
242 return make_pair(static_cast<TVirtualIndex*>(nullptr), 0);
243 }
244 TChain* chain = dynamic_cast<TChain*> (fTree);
245 R__ASSERT(chain);
246 chain->LoadTree(chain->GetTreeOffset()[treeNo]);
248 if (index)
249 return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
250 else {
251 index = fEntries[treeNo].fTreeIndex;
252 if (!index) {
253 Warning("GetSubTreeIndex", "The tree has no index and the chain index"
254 " doesn't store an index for that tree");
255 return make_pair(static_cast<TVirtualIndex*>(nullptr), 0);
256 }
257 else {
259 return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
260 }
261 }
262}
263
264////////////////////////////////////////////////////////////////////////////////
265/// Releases the tree index got using GetSubTreeIndex. If the index was
266/// created by this object it is removed from the current tree, so that it isn't
267/// deleted in its destructor.
268
270{
271 if (fEntries[treeNo].fTreeIndex == index) {
273 fTree->GetTree()->SetTreeIndex(nullptr);
274 }
275}
276
277////////////////////////////////////////////////////////////////////////////////
278/// See TTreeIndex::GetEntryNumberFriend for description
279
281{
282 if (!parent) return -3;
283 GetMajorFormulaParent(parent);
284 GetMinorFormulaParent(parent);
285 if (!fMajorFormulaParent || !fMinorFormulaParent) return -1;
287 // The Tree Index in the friend has a pair majorname,minorname
288 // not available in the parent Tree T.
289 // if the friend Tree has less entries than the parent, this is an error
290 Long64_t pentry = parent->GetReadEntry();
291 if (pentry >= fTree->GetEntries()) return -2;
292 // otherwise we ignore the Tree Index and return the entry number
293 // in the parent Tree.
294 return pentry;
295 }
296
297 // majorname, minorname exist in the parent Tree
298 // we find the current values pair majorv,minorv in the parent Tree
301 Long64_t majorv = (Long64_t)majord;
302 Long64_t minorv = (Long64_t)minord;
303 // we check if this pair exist in the index.
304 // if yes, we return the corresponding entry number
305 // if not the function returns -1
306 return fTree->GetEntryNumberWithIndex(majorv,minorv);
307}
308
309////////////////////////////////////////////////////////////////////////////////
310/// See TTreeIndex::GetEntryNumberWithBestIndex for details.
311
313{
314 std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
315 if (!indexAndNumber.first) {
316 // Error("GetEntryNumberWithBestIndex","no index found");
317 return -1;
318 }
319 else {
320 Long64_t rv = indexAndNumber.first->GetEntryNumberWithBestIndex(major, minor);
321 ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
322 TChain* chain = dynamic_cast<TChain*> (fTree);
323 R__ASSERT(chain);
324 return rv + chain->GetTreeOffset()[indexAndNumber.second];
325 }
326}
327
328////////////////////////////////////////////////////////////////////////////////
329/// Returns the entry number with given index values.
330/// See TTreeIndex::GetEntryNumberWithIndex for details.
331
333{
334 std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
335 if (!indexAndNumber.first) {
336 // Error("GetEntryNumberWithIndex","no index found");
337 return -1;
338 }
339 else {
340 Long64_t rv = indexAndNumber.first->GetEntryNumberWithIndex(major, minor);
341 ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
342 TChain* chain = dynamic_cast<TChain*> (fTree);
343 R__ASSERT(chain);
344 if (rv >= 0) {
345 return rv + chain->GetTreeOffset()[indexAndNumber.second];
346 } else {
347 return rv;
348 }
349 }
350}
351
352////////////////////////////////////////////////////////////////////////////////
353/// Return a pointer to the TreeFormula corresponding to the majorname in parent tree T.
354
356{
357 if (!fMajorFormulaParent) {
359 fMajorFormulaParent = new TTreeFormula("MajorP",fMajorName.Data(),const_cast<TTree*>(parent));
361 }
362 if (fMajorFormulaParent->GetTree() != parent) {
363 fMajorFormulaParent->SetTree(const_cast<TTree*>(parent));
365 }
366 return fMajorFormulaParent;
367}
368
369////////////////////////////////////////////////////////////////////////////////
370/// Return a pointer to the TreeFormula corresponding to the minorname in parent tree T.
371
373{
374 if (!fMinorFormulaParent) {
375 // Prevent TTreeFormula from finding any of the branches in our TTree even if it
376 // is a friend of the parent TTree.
378 fMinorFormulaParent = new TTreeFormula("MinorP",fMinorName.Data(),const_cast<TTree*>(parent));
380 }
381 if (fMinorFormulaParent->GetTree() != parent) {
382 fMinorFormulaParent->SetTree(const_cast<TTree*>(parent));
384 }
385
386 return fMinorFormulaParent;
387}
388
389////////////////////////////////////////////////////////////////////////////////
390/// Return true if index can be applied to the TTree
391
393{
394 auto *majorFormula = GetMajorFormulaParent(parent);
395 auto *minorFormula = GetMinorFormulaParent(parent);
396 if ((majorFormula == nullptr || majorFormula->GetNdim() == 0) ||
397 (minorFormula == nullptr || minorFormula->GetNdim() == 0))
398 return false;
399 return true;
400}
401
402////////////////////////////////////////////////////////////////////////////////
403/// Updates the parent formulae.
404/// Called by TChain::LoadTree when the parent chain changes it's tree.
405
407{
409 // Prevent TTreeFormula from finding any of the branches in our TTree even if it
410 // is a friend of the parent TTree.
412 if (parent) fMajorFormulaParent->SetTree((TTree*)parent);
414 }
416 if (parent) fMinorFormulaParent->SetTree((TTree*)parent);
418 }
419}
420
421////////////////////////////////////////////////////////////////////////////////
422/// See TTreeIndex::SetTree.
423
425{
426 R__ASSERT(fTree == nullptr || fTree == T || T==nullptr);
427 fTree = T;
428}
429
430////////////////////////////////////////////////////////////////////////////////
431/// \brief Create a deep copy of the TChainIndex
432/// \param[in] newname A new name for the index
433///
434/// The new index is allocated on the heap without being managed. Also, it is
435/// not attached to any tree. It is the responsibility of the caller to manage
436/// its lifetime and attach it to a tree if necessary.
437TObject *TChainIndex::Clone(const char *newname) const
438{
439 auto index = new TChainIndex();
440 index->SetName(newname && std::strlen(newname) ? newname : GetName());
441 index->SetTitle(GetTitle());
442
443 // Note that the TTreeFormula * data members are not cloned since they would
444 // need the attached tree data member to function properly.
445 index->fMajorName = fMajorName;
446 index->fMinorName = fMinorName;
447
448 index->fEntries = fEntries;
449
450 return index;
451}
#define SafeDelete(p)
Definition RConfig.hxx:542
int Int_t
Definition RtypesCore.h:45
long long Long64_t
Definition RtypesCore.h:80
#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:56
void Swap(TChainIndexEntry &other)
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:75
TTreeFormula * fMinorFormulaParent
Pointer to major TreeFormula in Parent tree (if any)
Definition TChainIndex.h:74
~TChainIndex() override
The destructor.
TString fMinorName
Definition TChainIndex.h:72
bool IsValidFor(const TTree *parent) override
Return true if index can be applied to the TTree.
TObject * Clone(const char *newname="") const override
Create a deep copy of the TChainIndex.
void Append(const TVirtualIndex *, bool delaySort=false) override
Add an index to this chain.
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:71
TTreeFormula * fMajorFormulaParent
Definition TChainIndex.h:73
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.
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:1302
Int_t GetNtrees() const
Definition TChain.h:99
TObject * Clone(const char *newname="") const override
Make a clone of an object using the Streamer facility.
Definition TNamed.cxx:74
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
Mother of all ROOT objects.
Definition TObject.h:41
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:376
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.
void SetQuickLoad(bool quick)
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
virtual TTree * GetTree() const
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:5910
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition TTree.cxx:5479
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:9346
Abstract interface for Tree Index.