25 struct IndexSortComparator {
27 IndexSortComparator(Long64_t *major, Long64_t *minor)
28 : fValMajor(major), fValMinor(minor)
31 template<
typename Index>
32 bool operator()(Index i1, Index i2) {
33 if( *(fValMajor + i1) == *(fValMajor + i2) )
34 return *(fValMinor + i1) < *(fValMinor + i2);
36 return *(fValMajor + i1) < *(fValMajor + i2);
41 Long64_t *fValMajor, *fValMinor;
48 TTreeIndex::TTreeIndex(): TVirtualIndex()
53 fIndexValuesMinor = 0;
57 fMajorFormulaParent = 0;
58 fMinorFormulaParent = 0;
125 TTreeIndex::TTreeIndex(
const TTree *T,
const char *majorname,
const char *minorname)
131 fIndexValuesMinor = 0;
135 fMajorFormulaParent = 0;
136 fMinorFormulaParent = 0;
137 fMajorName = majorname;
138 fMinorName = minorname;
140 fN = T->GetEntries();
143 Error(
"TreeIndex",
"Cannot build a TreeIndex with a Tree having no entries");
149 if (!fMajorFormula || !fMinorFormula) {
151 Error(
"TreeIndex",
"Cannot build the index with major=%s, minor=%s",fMajorName.Data(), fMinorName.Data());
154 if ((fMajorFormula->GetNdim() != 1) || (fMinorFormula->GetNdim() != 1)) {
156 Error(
"TreeIndex",
"Cannot build the index with major=%s, minor=%s",fMajorName.Data(), fMinorName.Data());
166 Long64_t *tmp_major =
new Long64_t[fN];
167 Long64_t *tmp_minor =
new Long64_t[fN];
169 Long64_t oldEntry = fTree->GetReadEntry();
172 Long64_t centry = fTree->LoadTree(i);
173 if (centry < 0)
break;
174 if (fTree->GetTreeNumber() != current) {
175 current = fTree->GetTreeNumber();
176 fMajorFormula->UpdateFormulaLeaves();
177 fMinorFormula->UpdateFormulaLeaves();
179 tmp_major[i] = (Long64_t) fMajorFormula->EvalInstance<LongDouble_t>();
180 tmp_minor[i] = (Long64_t) fMinorFormula->EvalInstance<LongDouble_t>();
182 fIndex =
new Long64_t[fN];
183 for(i = 0; i < fN; i++) { fIndex[i] = i; }
184 std::sort(fIndex, fIndex + fN, IndexSortComparator(tmp_major, tmp_minor) );
186 fIndexValues =
new Long64_t[fN];
187 fIndexValuesMinor =
new Long64_t[fN];
189 fIndexValues[i] = tmp_major[fIndex[i]];
190 fIndexValuesMinor[i] = tmp_minor[fIndex[i]];
195 fTree->LoadTree(oldEntry);
201 TTreeIndex::~TTreeIndex()
203 if (fTree && fTree->GetTreeIndex() ==
this) fTree->SetTreeIndex(0);
204 delete [] fIndexValues; fIndexValues = 0;
205 delete [] fIndexValuesMinor; fIndexValuesMinor = 0;
206 delete [] fIndex; fIndex = 0;
207 delete fMajorFormula; fMajorFormula = 0;
208 delete fMinorFormula; fMinorFormula = 0;
209 delete fMajorFormulaParent; fMajorFormulaParent = 0;
210 delete fMinorFormulaParent; fMinorFormulaParent = 0;
218 void TTreeIndex::Append(
const TVirtualIndex *add, Bool_t delaySort )
221 if (add && add->GetN()) {
224 const TTreeIndex *ti_add =
dynamic_cast<const TTreeIndex*
>(add);
226 Error(
"Append",
"Can only Append a TTreeIndex to a TTreeIndex but got a %s",
227 add->IsA()->GetName());
233 Long64_t *oldIndex = fIndex;
234 Long64_t *oldValues = GetIndexValues();
235 Long64_t *oldValues2 = GetIndexValuesMinor();
237 fIndex =
new Long64_t[fN];
238 fIndexValues =
new Long64_t[fN];
239 fIndexValuesMinor =
new Long64_t[fN];
242 Long_t size =
sizeof(Long64_t) * oldn;
243 Long_t add_size =
sizeof(Long64_t) * add->GetN();
245 memcpy(fIndex,oldIndex, size);
246 memcpy(fIndexValues,oldValues, size);
247 memcpy(fIndexValuesMinor,oldValues2, size);
249 Long64_t *addIndex = ti_add->GetIndex();
250 Long64_t *addValues = ti_add->GetIndexValues();
251 Long64_t *addValues2 = ti_add->GetIndexValuesMinor();
253 memcpy(fIndex + oldn, addIndex, add_size);
254 memcpy(fIndexValues + oldn, addValues, add_size);
255 memcpy(fIndexValuesMinor + oldn, addValues2, add_size);
256 for(Int_t i = 0; i < add->GetN(); i++) {
257 fIndex[oldn + i] += oldn;
262 delete [] oldValues2;
267 Long64_t *addValues = GetIndexValues();
268 Long64_t *addValues2 = GetIndexValuesMinor();
269 Long64_t *ind = fIndex;
270 Long64_t *conv =
new Long64_t[fN];
272 for(Long64_t i = 0; i < fN; i++) { conv[i] = i; }
273 std::sort(conv, conv+fN, IndexSortComparator(addValues, addValues2) );
277 fIndex =
new Long64_t[fN];
278 fIndexValues =
new Long64_t[fN];
279 fIndexValuesMinor =
new Long64_t[fN];
281 for (Int_t i=0;i<fN;i++) {
282 fIndex[i] = ind[conv[i]];
283 fIndexValues[i] = addValues[conv[i]];
284 fIndexValuesMinor[i] = addValues2[conv[i]];
287 delete [] addValues2;
299 bool TTreeIndex::ConvertOldToNew()
301 if( !fIndexValuesMinor && fN ) {
302 fIndexValuesMinor =
new Long64_t[fN];
303 for(
int i=0; i<fN; i++) {
304 fIndexValuesMinor[i] = (fIndexValues[i] & 0x7fffffff);
305 fIndexValues[i] >>= 31;
321 Long64_t TTreeIndex::GetEntryNumberFriend(
const TTree *parent)
323 if (!parent)
return -3;
324 GetMajorFormulaParent(parent);
325 GetMinorFormulaParent(parent);
326 if (!fMajorFormulaParent || !fMinorFormulaParent)
return -1;
327 if (!fMajorFormulaParent->GetNdim() || !fMinorFormulaParent->GetNdim()) {
331 Long64_t pentry = parent->GetReadEntry();
332 if (pentry >= fTree->GetEntries())
return -2;
340 Double_t majord = fMajorFormulaParent->EvalInstance();
341 Double_t minord = fMinorFormulaParent->EvalInstance();
342 Long64_t majorv = (Long64_t)majord;
343 Long64_t minorv = (Long64_t)minord;
347 return fTree->GetEntryNumberWithIndex(majorv,minorv);
356 Long64_t TTreeIndex::FindValues(Long64_t major, Long64_t minor)
const
358 Long64_t mid, step, pos = 0, count = fN;
364 if( fIndexValues[mid] < major
365 || ( fIndexValues[mid] == major && fIndexValuesMinor[mid] < minor ) ) {
391 Long64_t TTreeIndex::GetEntryNumberWithBestIndex(Long64_t major, Long64_t minor)
const
393 if (fN == 0)
return -1;
395 Long64_t pos = FindValues(major, minor);
396 if( pos < fN && fIndexValues[pos] == major && fIndexValuesMinor[pos] == minor )
416 Long64_t TTreeIndex::GetEntryNumberWithIndex(Long64_t major, Long64_t minor)
const
418 if (fN == 0)
return -1;
420 Long64_t pos = FindValues(major, minor);
421 if( pos < fN && fIndexValues[pos] == major && fIndexValuesMinor[pos] == minor )
429 Long64_t* TTreeIndex::GetIndexValuesMinor()
const
431 return fIndexValuesMinor;
439 TTreeFormula *TTreeIndex::GetMajorFormula()
441 if (!fMajorFormula) {
442 fMajorFormula =
new TTreeFormula(
"Major",fMajorName.Data(),fTree);
443 fMajorFormula->SetQuickLoad(kTRUE);
445 return fMajorFormula;
451 TTreeFormula *TTreeIndex::GetMinorFormula()
453 if (!fMinorFormula) {
454 fMinorFormula =
new TTreeFormula(
"Minor",fMinorName.Data(),fTree);
455 fMinorFormula->SetQuickLoad(kTRUE);
457 return fMinorFormula;
463 TTreeFormula *TTreeIndex::GetMajorFormulaParent(
const TTree *parent)
465 if (!fMajorFormulaParent) {
468 TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
469 fMajorFormulaParent =
new TTreeFormula(
"MajorP",fMajorName.Data(),
const_cast<TTree*
>(parent));
470 fMajorFormulaParent->SetQuickLoad(kTRUE);
472 if (fMajorFormulaParent->GetTree() != parent) {
473 fMajorFormulaParent->SetTree(const_cast<TTree*>(parent));
474 fMajorFormulaParent->UpdateFormulaLeaves();
476 return fMajorFormulaParent;
482 TTreeFormula *TTreeIndex::GetMinorFormulaParent(
const TTree *parent)
484 if (!fMinorFormulaParent) {
487 TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
488 fMinorFormulaParent =
new TTreeFormula(
"MinorP",fMinorName.Data(),
const_cast<TTree*
>(parent));
489 fMinorFormulaParent->SetQuickLoad(kTRUE);
491 if (fMinorFormulaParent->GetTree() != parent) {
492 fMinorFormulaParent->SetTree(const_cast<TTree*>(parent));
493 fMinorFormulaParent->UpdateFormulaLeaves();
495 return fMinorFormulaParent;
501 Bool_t TTreeIndex::IsValidFor(
const TTree *parent)
503 auto *majorFormula = GetMajorFormulaParent(parent);
504 auto *minorFormula = GetMinorFormulaParent(parent);
505 if ((majorFormula ==
nullptr || majorFormula->GetNdim() == 0) ||
506 (minorFormula ==
nullptr || minorFormula->GetNdim() == 0))
517 void TTreeIndex::Print(Option_t * option)
const
519 TString opt = option;
520 Bool_t printEntry = kFALSE;
522 if (opt.Contains(
"10")) n = 10;
523 if (opt.Contains(
"100")) n = 100;
524 if (opt.Contains(
"1000")) n = 1000;
525 if (opt.Contains(
"all")) {
530 Printf(
"\n*****************************************************************");
531 Printf(
"* Index of Tree: %s/%s",fTree->GetName(),fTree->GetTitle());
532 Printf(
"*****************************************************************");
533 Printf(
"%8s : %16s : %16s : %16s",
"serial",fMajorName.Data(),fMinorName.Data(),
"entry number");
534 Printf(
"*****************************************************************");
535 for (Long64_t i=0;i<n;i++) {
536 Printf(
"%8lld : %8lld : %8lld : %8lld",
537 i, fIndexValues[i], GetIndexValuesMinor()[i], fIndex[i]);
541 Printf(
"\n**********************************************");
542 Printf(
"* Index of Tree: %s/%s",fTree->GetName(),fTree->GetTitle());
543 Printf(
"**********************************************");
544 Printf(
"%8s : %16s : %16s",
"serial",fMajorName.Data(),fMinorName.Data());
545 Printf(
"**********************************************");
546 for (Long64_t i=0;i<n;i++) {
547 Printf(
"%8lld : %8lld : %8lld",
548 i, fIndexValues[i],GetIndexValuesMinor()[i]);
558 void TTreeIndex::Streamer(TBuffer &R__b)
561 if (R__b.IsReading()) {
562 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v) { }
563 TVirtualIndex::Streamer(R__b);
564 fMajorName.Streamer(R__b);
565 fMinorName.Streamer(R__b);
567 fIndexValues =
new Long64_t[fN];
568 R__b.ReadFastArray(fIndexValues,fN);
570 fIndexValuesMinor =
new Long64_t[fN];
571 R__b.ReadFastArray(fIndexValuesMinor,fN);
575 fIndex =
new Long64_t[fN];
576 R__b.ReadFastArray(fIndex,fN);
577 R__b.CheckByteCount(R__s, R__c, TTreeIndex::IsA());
579 R__c = R__b.WriteVersion(TTreeIndex::IsA(), kTRUE);
580 TVirtualIndex::Streamer(R__b);
581 fMajorName.Streamer(R__b);
582 fMinorName.Streamer(R__b);
584 R__b.WriteFastArray(fIndexValues, fN);
585 R__b.WriteFastArray(fIndexValuesMinor, fN);
586 R__b.WriteFastArray(fIndex, fN);
587 R__b.SetByteCount(R__c, kTRUE);
594 void TTreeIndex::UpdateFormulaLeaves(
const TTree *parent)
596 if (fMajorFormula) { fMajorFormula->UpdateFormulaLeaves();}
597 if (fMinorFormula) { fMinorFormula->UpdateFormulaLeaves();}
598 if (fMajorFormulaParent) {
599 if (parent) fMajorFormulaParent->SetTree(const_cast<TTree*>(parent));
600 fMajorFormulaParent->UpdateFormulaLeaves();
602 if (fMinorFormulaParent) {
603 if (parent) fMinorFormulaParent->SetTree(const_cast<TTree*>(parent));
604 fMinorFormulaParent->UpdateFormulaLeaves();
613 void TTreeIndex::SetTree(
const TTree *T)