Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions roottest/root/tree/index/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ ROOTTEST_ADD_TEST(index64
MACRO runindex64.C
OUTREF index64.ref)

ROOTTEST_ADD_TEST(varsizearr
MACRO runvarsizearr.C
OUTREF varsizearr.ref)
31 changes: 31 additions & 0 deletions roottest/root/tree/index/runvarsizearr.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "TTree.h"
#include "TTreeIndex.h"
#include <vector>
#include <iostream>

// https://github.com/root-project/root/pull/19619
int runvarsizearr()
{
const Long64_t nEvents = 2;
const size_t nElements = 3;
std::vector<int> otherNumbers(nElements);
Long64_t eventNumber;
TTree t("tree", "tree");
t.Branch("eventNumber", &eventNumber);
t.Branch("otherNumbers", &otherNumbers);
for (Long64_t i = 0; i < nEvents; i++) {
eventNumber = i;
for (size_t j = 0; j < nElements; ++j)
otherNumbers[j] = -2. * eventNumber + 3500 * j;
t.Fill();
}
std::cout << t.GetEntries() << std::endl;
// use Scan to show what otherNumbers[2] contains
t.Scan("eventNumber:otherNumbers", "", "", nEvents);

TTreeIndex firstIndex(&t, "otherNumbers[2]", "eventNumber");
firstIndex.Print("2"); // before the fix: major was always a garbage value and events were wrongly sorted
TTreeIndex secondIndex(&t, "otherNumbers", "eventNumber");
secondIndex.Print("2"); // major is otherNumbers[0] since index not specified (fine before and after fix)
return 0;
}
30 changes: 30 additions & 0 deletions roottest/root/tree/index/varsizearr.ref
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

Processing runvarsizearr.C...
2
***********************************************
* Row * Instance * eventNumb * otherNumb *
***********************************************
* 0 * 0 * 0 * 0 *
* 0 * 1 * 0 * 3500 *
* 0 * 2 * 0 * 7000 *
* 1 * 0 * 1 * -2 *
* 1 * 1 * 1 * 3498 *
* 1 * 2 * 1 * 6998 *
***********************************************

**********************************************
* Index of Tree: tree/tree
**********************************************
serial : otherNumbers[2] : eventNumber
**********************************************
0 : 6998 : 1
1 : 7000 : 0

**********************************************
* Index of Tree: tree/tree
**********************************************
serial : otherNumbers : eventNumber
**********************************************
0 : -2 : 1
1 : 0 : 0
(int) 0
9 changes: 9 additions & 0 deletions tree/treeplayer/src/TTreeIndex.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

/** \class TTreeIndex
A Tree Index with majorname and minorname.

If minorname is "0" (default arg in TTree::BuildIndex), just majorname will be used.
*/

#include "TTreeIndex.h"
Expand Down Expand Up @@ -180,6 +182,13 @@ TTreeIndex::TTreeIndex(const TTree *T, const char *majorname, const char *minorn
fMajorFormula->UpdateFormulaLeaves();
fMinorFormula->UpdateFormulaLeaves();
}
if ((fMajorFormula->GetNdata() + fMinorFormula->GetNdata()) <= 0) {
// Calling GetNdata is essential before calling EvalInstance, otherwise a wrong
// result is silently returned by EvalInstance below if formula is value from a variable-sized array
// We raise an error to prevent the if clause being optimized-out if we do not use the return
Error("TTreeIndex", "In tree entry %lld, Ndata in formula is zero for both '%s' and '%s'", i,
fMajorName.Data(), fMinorName.Data());
}
auto GetAndRangeCheck = [this](bool isMajor, Long64_t entry) {
LongDouble_t ret = (isMajor ? fMajorFormula : fMinorFormula)->EvalInstance<LongDouble_t>();
// Check whether the value (vs significant bits) of ldRet can represent
Expand Down
Loading