34 void TChainIndex::TChainIndexEntry::SetMinMaxFrom(
const TTreeIndex *index )
36 fMinIndexValue = index->GetIndexValues()[0];
37 fMinIndexValMinor = index->GetIndexValuesMinor()[0];
38 fMaxIndexValue = index->GetIndexValues()[index->GetN() - 1];
39 fMaxIndexValMinor = index->GetIndexValuesMinor()[index->GetN() - 1];
42 ClassImp(TChainIndex);
47 TChainIndex::TChainIndex(): TVirtualIndex()
50 fMajorFormulaParent = fMinorFormulaParent = 0;
63 TChainIndex::TChainIndex(
const TTree *T,
const char *majorname,
const char *minorname)
67 fMajorFormulaParent = fMinorFormulaParent = 0;
69 TChain *chain =
dynamic_cast<TChain*
>(
const_cast<TTree*
>(T));
72 Error(
"TChainIndex",
"Cannot create a TChainIndex."
73 " The Tree passed as an argument is not a TChain");
78 fMajorName = majorname;
79 fMinorName = minorname;
83 for (i = 0; i < chain->GetNtrees(); i++) {
84 chain->LoadTree((chain->GetTreeOffset())[i]);
85 TVirtualIndex *index = chain->GetTree()->GetTreeIndex();
87 TChainIndexEntry entry;
93 if (strcmp(majorname,index->GetMajorName()) || strcmp(minorname,index->GetMinorName())) {
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());
100 chain->GetTree()->BuildIndex(majorname, minorname);
101 index = chain->GetTree()->GetTreeIndex();
102 chain->GetTree()->SetTreeIndex(0);
103 entry.fTreeIndex = index;
105 if (!index || index->IsZombie() || index->GetN() == 0) {
108 Error(
"TChainIndex",
"Error creating a tree index on a tree in the chain");
112 TTreeIndex *ti_index =
dynamic_cast<TTreeIndex*
>(index);
114 Error(
"TChainIndex",
"The underlying TTree must have a TTreeIndex but has a %s.",
115 index->IsA()->GetName());
119 entry.SetMinMaxFrom(ti_index);
120 fEntries.push_back(entry);
124 for (i = 0; i < Int_t(fEntries.size() - 1); i++) {
125 if( fEntries[i].GetMaxIndexValPair() > fEntries[i+1].GetMinIndexValPair() ) {
128 Error(
"TChainIndex",
"The indices in files of this chain aren't sorted.");
137 void TChainIndex::Append(
const TVirtualIndex *index, Bool_t delaySort )
140 const TTreeIndex *ti_index =
dynamic_cast<const TTreeIndex*
>(index);
142 Error(
"Append",
"The given index is not a TTreeIndex but a %s",
143 index->IsA()->GetName());
146 TChainIndexEntry entry;
147 entry.fTreeIndex = 0;
148 entry.SetMinMaxFrom(ti_index);
149 fEntries.push_back(entry);
154 for (Int_t i = 0; i < Int_t(fEntries.size() - 1); i++) {
155 if( fEntries[i].GetMaxIndexValPair() > fEntries[i+1].GetMinIndexValPair() ) {
158 Error(
"Append",
"The indices in files of this chain aren't sorted.");
167 void TChainIndex::DeleteIndices()
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);
175 SafeDelete(fEntries[i].fTreeIndex);
183 TChainIndex::~TChainIndex()
186 if (fTree && fTree->GetTreeIndex() ==
this)
187 fTree->SetTreeIndex(0);
196 std::pair<TVirtualIndex*, Int_t> TChainIndex::GetSubTreeIndex(Long64_t major, Long64_t minor)
const
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);
204 const TChainIndexEntry::IndexValPair_t indexValue(major, minor);
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);
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() ) {
219 if( indexValue > fEntries[treeNo].GetMaxIndexValPair() ) {
220 return make_pair(static_cast<TVirtualIndex*>(0), 0);
222 TChain* chain =
dynamic_cast<TChain*
> (fTree);
224 chain->LoadTree(chain->GetTreeOffset()[treeNo]);
225 TVirtualIndex* index = fTree->GetTree()->GetTreeIndex();
227 return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
229 index = fEntries[treeNo].fTreeIndex;
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);
236 fTree->GetTree()->SetTreeIndex(index);
237 return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
247 void TChainIndex::ReleaseSubTreeIndex(TVirtualIndex* index,
int treeNo)
const
249 if (fEntries[treeNo].fTreeIndex == index) {
250 R__ASSERT(fTree->GetTree()->GetTreeIndex() == index);
251 fTree->GetTree()->SetTreeIndex(0);
258 Long64_t TChainIndex::GetEntryNumberFriend(
const TTree *parent)
260 if (!parent)
return -3;
261 GetMajorFormulaParent(parent);
262 GetMinorFormulaParent(parent);
263 if (!fMajorFormulaParent || !fMinorFormulaParent)
return -1;
264 if (!fMajorFormulaParent->GetNdim() || !fMinorFormulaParent->GetNdim()) {
268 Long64_t pentry = parent->GetReadEntry();
269 if (pentry >= fTree->GetEntries())
return -2;
277 Double_t majord = fMajorFormulaParent->EvalInstance();
278 Double_t minord = fMinorFormulaParent->EvalInstance();
279 Long64_t majorv = (Long64_t)majord;
280 Long64_t minorv = (Long64_t)minord;
284 return fTree->GetEntryNumberWithIndex(majorv,minorv);
290 Long64_t TChainIndex::GetEntryNumberWithBestIndex(Long64_t major, Long64_t minor)
const
292 std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
293 if (!indexAndNumber.first) {
298 Long64_t rv = indexAndNumber.first->GetEntryNumberWithBestIndex(major, minor);
299 ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
300 TChain* chain =
dynamic_cast<TChain*
> (fTree);
302 return rv + chain->GetTreeOffset()[indexAndNumber.second];
310 Long64_t TChainIndex::GetEntryNumberWithIndex(Long64_t major, Long64_t minor)
const
312 std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
313 if (!indexAndNumber.first) {
318 Long64_t rv = indexAndNumber.first->GetEntryNumberWithIndex(major, minor);
319 ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
320 TChain* chain =
dynamic_cast<TChain*
> (fTree);
323 return rv + chain->GetTreeOffset()[indexAndNumber.second];
333 TTreeFormula *TChainIndex::GetMajorFormulaParent(
const TTree *parent)
335 if (!fMajorFormulaParent) {
336 TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
337 fMajorFormulaParent =
new TTreeFormula(
"MajorP",fMajorName.Data(),
const_cast<TTree*
>(parent));
338 fMajorFormulaParent->SetQuickLoad(kTRUE);
340 if (fMajorFormulaParent->GetTree() != parent) {
341 fMajorFormulaParent->SetTree(const_cast<TTree*>(parent));
342 fMajorFormulaParent->UpdateFormulaLeaves();
344 return fMajorFormulaParent;
350 TTreeFormula *TChainIndex::GetMinorFormulaParent(
const TTree *parent)
352 if (!fMinorFormulaParent) {
355 TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
356 fMinorFormulaParent =
new TTreeFormula(
"MinorP",fMinorName.Data(),
const_cast<TTree*
>(parent));
357 fMinorFormulaParent->SetQuickLoad(kTRUE);
359 if (fMinorFormulaParent->GetTree() != parent) {
360 fMinorFormulaParent->SetTree(const_cast<TTree*>(parent));
361 fMinorFormulaParent->UpdateFormulaLeaves();
364 return fMinorFormulaParent;
370 Bool_t TChainIndex::IsValidFor(
const TTree *parent)
372 auto *majorFormula = GetMajorFormulaParent(parent);
373 auto *minorFormula = GetMinorFormulaParent(parent);
374 if ((majorFormula ==
nullptr || majorFormula->GetNdim() == 0) ||
375 (minorFormula ==
nullptr || minorFormula->GetNdim() == 0))
384 void TChainIndex::UpdateFormulaLeaves(
const TTree *parent)
386 if (fMajorFormulaParent) {
389 TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
390 if (parent) fMajorFormulaParent->SetTree((TTree*)parent);
391 fMajorFormulaParent->UpdateFormulaLeaves();
393 if (fMinorFormulaParent) {
394 if (parent) fMinorFormulaParent->SetTree((TTree*)parent);
395 fMinorFormulaParent->UpdateFormulaLeaves();
402 void TChainIndex::SetTree(
const TTree *T)
404 R__ASSERT(fTree == 0 || fTree == T || T==0);