Skip to content
Snippets Groups Projects
Commit 0422a894 authored by Danilo Piparo's avatar Danilo Piparo
Browse files

[DF][ROOT-9559] Throw if processing of indexed friend trees is triggered

parent d5ecc717
No related branches found
No related tags found
No related merge requests found
......@@ -123,6 +123,7 @@ class RLoopManager : public RNodeBase {
/// Cache of the tree/chain branch names. Never access directy, always use GetBranchNames().
ColumnNames_t fValidBranchNames;
void CheckIndexedFriends();
void RunEmptySourceMT();
void RunEmptySource();
void RunTreeProcessorMT();
......
......@@ -207,6 +207,25 @@ RLoopManager::RLoopManager(std::unique_ptr<RDataSource> ds, const ColumnNames_t
fDataSource->SetNSlots(fNSlots);
}
// ROOT-9559: we cannot handle indexed friends
void RLoopManager::CheckIndexedFriends()
{
auto friends = fTree->GetListOfFriends();
if (!friends)
return;
for (auto friendElObj : *friends) {
auto friendEl = static_cast<TFriendElement *>(friendElObj);
auto friendTree = friendEl->GetTree();
if (friendTree && friendTree->GetTreeIndex()) {
std::string err = fTree->GetName();
err += " has a friend, \"";
err += friendTree->GetName();
err += "\", which has an index. This is not supported.";
throw std::runtime_error(err);
}
}
}
/// Run event loop with no source files, in parallel.
void RLoopManager::RunEmptySourceMT()
{
......@@ -259,6 +278,7 @@ void RLoopManager::RunEmptySource()
void RLoopManager::RunTreeProcessorMT()
{
#ifdef R__USE_IMT
CheckIndexedFriends();
RSlotStack slotStack(fNSlots);
const auto &entryList = fTree->GetEntryList() ? *fTree->GetEntryList() : TEntryList();
auto tp = std::make_unique<ROOT::TTreeProcessorMT>(*fTree, entryList);
......@@ -284,6 +304,7 @@ void RLoopManager::RunTreeProcessorMT()
/// Run event loop over one or multiple ROOT files, in sequence.
void RLoopManager::RunTreeReader()
{
CheckIndexedFriends();
TTreeReader r(fTree.get(), fTree->GetEntryList());
if (0 == fTree->GetEntriesFast())
return;
......
......@@ -211,4 +211,76 @@ TEST_F(RDFAndFriends, FriendChainMT)
ROOT::DisableImplicitMT();
}
// ROOT-9559
void FillIndexedFriend(const char *mainfile, const char *auxfile)
{
// Start by creating main Tree
TFile f(mainfile, "RECREATE");
TTree mainTree("mainTree", "mainTree");
int idx;
mainTree.Branch("idx", &idx);
float x;
mainTree.Branch("x", &x);
idx = 1;
x = 0.5;
mainTree.Fill();
idx = 1;
x = 2;
mainTree.Fill();
idx = 1;
x = 5;
mainTree.Fill();
idx = 2;
x = 1;
mainTree.Fill();
idx = 2;
x = 8;
mainTree.Fill();
mainTree.Write();
f.Close();
// And aux tree
TFile f2(auxfile, "RECREATE");
TTree auxTree("auxTree", "auxTree");
auxTree.Branch("idx", &idx);
float y;
auxTree.Branch("y", &y);
idx = 1;
y = 5;
auxTree.Fill();
idx = 2;
y = 7;
auxTree.Fill();
auxTree.Write();
f2.Close();
}
TEST(RDFAndFriendsNoFixture, IndexedFriend)
{
auto mainFile = "IndexedFriend_main.root";
auto auxFile = "IndexedFriend_aux.root";
FillIndexedFriend(mainFile, auxFile);
TChain mainChain("mainTree", "mainTree");
mainChain.Add(mainFile);
TChain auxChain("auxTree", "auxTree");
auxChain.Add(auxFile);
auxChain.BuildIndex("idx");
mainChain.AddFriend(&auxChain);
int ret = 1;
try {
auto df = ROOT::RDataFrame(mainChain);
*df.Min<int>("x");
} catch (const std::runtime_error &) {
ret = 0;
}
EXPECT_EQ(0, ret);
gSystem->Unlink(mainFile);
gSystem->Unlink(auxFile);
}
#endif // R__USE_IMT
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment