Hi,
I have a TTree with two branches and I want to add a friend tree in the same root file with new branches.
I am using RDataFrames to define the new columns in the friend tree but I can’t figure out how to correctly snapshot the friend tree in the same file as the main TTree.
This is the best I can achieve so far:
//some code here
...
//
typedef std::tuple<ROOT::VecOps::RVec<double>,ROOT::VecOps::RVec<double>,ROOT::VecOps::RVec<double>,ROOT::VecOps::RVec<double>> TYPE_TUPLE_WITH_4_RVEC;
void add_friend(TString fileName, TString treeName, TString friendTreeName){
TFile *f = new TFile(fileName, "UPDATE");
TTree *myTree = (TTree*)f->Get(treeName);
myTree->AddFriend(new TTree(friendTreeName,friendTreeName), fileName);
f->Write();
f->Close();
}
int main(int argc, char** argv)
{
//some code here
...
//
//set I/O file names
string outDir = argv[1],
rootIn = argv[2],
rootOut = rootIn; //update same file
//id like to use MT
ROOT::EnableImplicitMT();
add_friend(rootIn, "amulet", "decoded_signals");
ROOT::RDataFrame df_trig("amulet", rootIn.c_str());
//tell snapshot to update root file
ROOT::RDF::RSnapshotOptions opt;
opt.fMode="UPDATE";
opt.fOverwriteIfExists=true;
//define new columns with the decoded informations and update root files with the new columns (branches)
df_trig .Define("ch0_wvf_time" , [sampfreq]( ROOT::VecOps::RVec<int> ADC_ch ){ return temporalize(ADC_ch, sampfreq); }, {"ch0_wvf_amp"} )
.Define("ch1_wvf_time" , [sampfreq]( ROOT::VecOps::RVec<int> ADC_ch ){ return temporalize(ADC_ch, sampfreq); }, {"ch1_wvf_amp"} )
.Define("ch0Decoded" , [sampfreq]( ROOT::VecOps::RVec<int> ADC_ch ){ return analyze(ADC_ch, sampfreq); }, {"ch0_wvf_amp"} )
.Define("ch1Decoded" , [sampfreq]( ROOT::VecOps::RVec<int> ADC_ch ){ return analyze(ADC_ch, sampfreq); }, {"ch1_wvf_amp"} )
.Define("ch0Nup" , []( TYPE_TUPLE_WITH_4_RVEC WVF_dec ){ return (int)get<0>(WVF_dec).size(); }, {"ch0Decoded" } )
.Define("ch0Ndwn" , []( TYPE_TUPLE_WITH_4_RVEC WVF_dec ){ return (int)get<1>(WVF_dec).size(); }, {"ch0Decoded" } )
.Define("ch0timeups" , []( TYPE_TUPLE_WITH_4_RVEC WVF_dec ){ return get<0>(WVF_dec); }, {"ch0Decoded" } )
.Define("ch0timedwns" , []( TYPE_TUPLE_WITH_4_RVEC WVF_dec ){ return get<1>(WVF_dec); }, {"ch0Decoded" } )
.Define("ch1Nup" , []( TYPE_TUPLE_WITH_4_RVEC WVF_dec ){ return (int)get<0>(WVF_dec).size(); }, {"ch1Decoded" } )
.Define("ch1Ndwn" , []( TYPE_TUPLE_WITH_4_RVEC WVF_dec ){ return (int)get<1>(WVF_dec).size(); }, {"ch1Decoded" } )
.Define("ch1timeups" , []( TYPE_TUPLE_WITH_4_RVEC WVF_dec ){ return get<0>(WVF_dec); }, {"ch1Decoded" } )
.Define("ch1timedwns" , []( TYPE_TUPLE_WITH_4_RVEC WVF_dec ){ return get<1>(WVF_dec); }, {"ch1Decoded" } )
.Snapshot("decoded_signals", rootOut.c_str(), {"ch0_wvf_time","ch0Nup","ch0Ndwn","ch0timeups","ch0timedwns",
"ch1_wvf_time","ch1Nup","ch1Ndwn","ch1timeups","ch1timedwns"}, opt );
return 0;
}
If I try to draw a scatter plot with
amulet->Draw("ch0_wvf_amp:ch0_wvf_time")
where the two variables are one from the main tree (amulet) and the other from the friend tree I get the plot that I expect.
The problem is that while the script is being executed I get this error:
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
Error in <TChain::LoadTree>: Cannot find tree with name decoded in file ../DAQERM/preprocessed/run2meas1_amulet.root
If I do not use ImplicitMT the error disappears, anyway I am not sure that I am handling the friend tree as I should otherwise it should work even with MT enabled.
I also tried using another approach:
TFile* myFile = new TFile(rootIn.c_str(), "UPDATE");
TTree* myTree = (TTree*)myFile->Get("amulet");
TTree* myFT = new TTree("decoded","decoded");
myFT->CopyEntries(myTree);
myTree->AddFriend(myFT,"decoded");
myFT->BuildIndex("Entry$");
myFT->Write();
myTree->Write("",TObject::kOverwrite);
myFile->Close();
ROOT::RDataFrame df_trig("amulet", rootIn);
//tell snapshot to update root file
ROOT::RDF::RSnapshotOptions opt;
opt.fMode="UPDATE";
opt.fOverwriteIfExists=true;
//and here I define the columns and snapshot the df
but I get the exact same error.
Any hint or advise that you might have will be useful, thanks in advance.
ROOT Version: 6.24/00
Platform: Manjaro
Compiler: GCC