Hi @psadangi ,
I think the problem is the "HLT_BPH_isFired"
branch, which is a map<string, bool>
for which ROOT does not have dictionaries by default (like it does for vector<int>
, vector<float>
etc.).
Cause
This code that only depends on TTreeReader (the interface RDataFrame uses for reading data under the hood) reproduces the problem:
void repro_treereader() {
TFile f("flatntuple_MC_.root");
auto *t = f.Get<TTree>("ntuplizer/tree");
R__ASSERT(t != nullptr);
TTreeReader r(t);
TTreeReaderValue<std::map<std::string, bool>> rv(r, "HLT_BPH_isFired");
r.Next();
*rv;
}
Doing the same with TTree directly instead of TTreeReader actually provides a better error message (and the lack of clear errors using TTreeReader is a bug, I’ll open an issue):
void repro_tree() {
TFile f("flatntuple_MC_.root");
auto *t = f.Get<TTree>("ntuplizer/tree");
R__ASSERT(t != nullptr);
std::map<std::string, bool> *m = nullptr;
t->SetBranchAddress("HLT_BPH_isFired", &m);
t->GetEntry(0);
}
$ root -l repro_tree.C
root [0]
Processing repro_tree.C...
Error in <TTree::SetBranchAddress>: The class requested (map<string,bool>) for the branch "HLT_BPH_isFired" is an instance of an stl collection and does not have a compiled CollectionProxy. Please generate the dictionary for this collection (map<string,bool>) to avoid to write corrupted data.
*** Break *** segmentation violation
So we need to generate dictionaries for map<string, bool>
in order to read that branch correctly.
Solution
This version of your original code should work when invoked as root -l -b -q original_repro.C+
(note the +
, which compiles your code in a shared library including the necessary dictionaries):
#include <TFile.h>
#include <TTree.h>
#include <ROOT/RDataFrame.hxx>
#pragma link C++ class std::map < std::string, bool>;
void original_repro() {
auto oldfile1 = TFile::Open("flatntuple_MC_.root");
TTree *t1 = (TTree *)oldfile1->Get("ntuplizer/tree");
Int_t nEntries1;
nEntries1 = t1->GetEntries();
ROOT::RDataFrame df1("ntuplizer/tree", "flatntuple_MC_.root");
df1.Range(nEntries1 / 3)
.Snapshot("events0", "flatntuple_MC_v4_custom_PU_full_final_1.root");
df1.Range(nEntries1 / 3, 2 * nEntries1 / 3)
.Snapshot("events1", "flatntuple_MC_v4_custom_PU_full_final_2.root");
df1.Range(2 * nEntries1 / 3, nEntries1)
.Snapshot("events2", "flatntuple_MC_v4_custom_PU_full_final_3.root");
}
For other ways to generate dictionaries see I/O of custom classes - ROOT .
Cheers,
Enrico