Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tree] Respect TChain's entryList when GetMinimum/Maximum #17789

Closed
wants to merge 4 commits into from
Closed
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
81 changes: 69 additions & 12 deletions tree/tree/src/TChain.cxx
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@ the trees in the chain.
#include <iostream>
#include <cfloat>
#include <string>
#include <map>

#include "TBranch.h"
#include "TBrowser.h"
@@ -66,6 +67,26 @@ the trees in the chain.

ClassImp(TChain);

/**
* @brief Helper function getting a map between treeNumber (key) defined in an entryList, and the position of the latter
* in the collection (value). Only those entry lists that are active (treeNumber != -1) are used to fill the map.
* @param elist the TChain's TEntryList
* @return map of int to int
*/
std::map<Int_t, Int_t> GetEntryListMap(const TEntryList *elist)
{
const auto *elists = elist->GetLists();
const auto ne = elists->GetEntries();
std::map<Int_t, Int_t> map_elists;
for (Int_t e = 0; e < ne; ++e) {
auto el = static_cast<TEntryList *>(elists->At(e));
if (el && el->GetTreeNumber() >= 0) {
map_elists[el->GetTreeNumber()] = e;
}
}
return map_elists;
}

////////////////////////////////////////////////////////////////////////////////
/// Default constructor.

@@ -1169,12 +1190,30 @@ TObjArray* TChain::GetListOfLeaves()
Double_t TChain::GetMaximum(const char* columname)
{
Double_t theMax = -DBL_MAX;
for (Int_t file = 0; file < fNtrees; file++) {
Long64_t first = fTreeOffset[file];
LoadTree(first);
Double_t curmax = fTree->GetMaximum(columname);
if (curmax > theMax) {
theMax = curmax;
auto elist = GetEntryList();
if (!elist || !elist->GetLists()) {
for (Int_t file = 0; file < fNtrees; file++) {
Long64_t first = fTreeOffset[file];
LoadTree(first);
Double_t curmax = fTree->GetMaximum(columname);
if (curmax > theMax) {
theMax = curmax;
}
}
} else {
auto map_elists = GetEntryListMap(elist);
for (Int_t file = 0; file < fNtrees; file++) {
Long64_t first = fTreeOffset[file];
LoadTree(first);
const auto prev = fTree->GetEntryList();
if (map_elists.find(file) != map_elists.end()) {
fTree->SetEntryList(static_cast<TEntryList *>(elist->GetLists()->At(map_elists[file])));
}
Double_t curmax = fTree->GetMaximum(columname);
fTree->SetEntryList(prev);
if (curmax > theMax) {
theMax = curmax;
}
}
}
return theMax;
@@ -1186,12 +1225,30 @@ Double_t TChain::GetMaximum(const char* columname)
Double_t TChain::GetMinimum(const char* columname)
{
Double_t theMin = DBL_MAX;
for (Int_t file = 0; file < fNtrees; file++) {
Long64_t first = fTreeOffset[file];
LoadTree(first);
Double_t curmin = fTree->GetMinimum(columname);
if (curmin < theMin) {
theMin = curmin;
auto elist = GetEntryList();
if (!elist || !elist->GetLists()) {
for (Int_t file = 0; file < fNtrees; file++) {
Long64_t first = fTreeOffset[file];
LoadTree(first);
Double_t curmin = fTree->GetMinimum(columname);
if (curmin < theMin) {
theMin = curmin;
}
}
} else {
auto map_elists = GetEntryListMap(elist);
for (Int_t file = 0; file < fNtrees; file++) {
Long64_t first = fTreeOffset[file];
LoadTree(first);
const auto prev = fTree->GetEntryList();
if (map_elists.find(file) != map_elists.end()) {
fTree->SetEntryList(static_cast<TEntryList *>(elist->GetLists()->At(map_elists[file])));
}
Double_t curmin = fTree->GetMinimum(columname);
fTree->SetEntryList(prev);
if (curmin < theMin) {
theMin = curmin;
}
}
}
return theMin;
49 changes: 48 additions & 1 deletion tree/tree/test/TChainRegressions.cxx
Original file line number Diff line number Diff line change
@@ -2,7 +2,9 @@
#include <TFile.h>
#include <TSystem.h>
#include <TTree.h>

#include <TEntryList.h>
#include <TDirectory.h>

#include "gtest/gtest.h"

class TTreeCache;
@@ -30,3 +32,48 @@ TEST(TChain, GetReadCacheBug)

gSystem->Unlink(filename);
}

// ROOT-7097, ROOT-8505
TEST(TChain, GetMinMaxEntryList)
{
std::unique_ptr<TFile> file1(TFile::Open("t1_7067.root", "RECREATE"));
TTree t1("t", "");
int value;
t1.Branch("value", &value);
value = 0;
t1.Fill();
value = 1;
t1.Fill();
value = 2;
t1.Fill();
value = 3;
t1.Fill();
file1->Write();
file1->Close();

std::unique_ptr<TFile> file2(TFile::Open("t2_7067.root", "RECREATE"));
TTree t2("t", "");
// int value;
t2.Branch("value", &value);
value = 10;
t2.Fill();
value = 11;
t2.Fill();
value = 12;
t2.Fill();
value = 13;
t2.Fill();
file2->Write();
file2->Close();

TChain ch("t");
ch.AddFile("t1_7067.root");
ch.AddFile("t2_7067.root");
EXPECT_FLOAT_EQ(ch.GetMinimum("value"), 0.);
EXPECT_FLOAT_EQ(ch.GetMaximum("value"), 13.);
ch.Draw(">>myList", "value<11 && value >1", "entrylist");
TEntryList *myList = static_cast<TEntryList *>(gDirectory->Get("myList"));
ch.SetEntryList(myList);
EXPECT_FLOAT_EQ(ch.GetMinimum("value"), 2.);
EXPECT_FLOAT_EQ(ch.GetMaximum("value"), 10.);
}
Loading