Hello,
I tried to analyze some root files using the chain feature and TDataFrame.
Since I have a directory tree, I use the command:
TChain chain(“ntuple/nt”);
Up to root 6.08 I could just chain the root files together and then perform my analysis. Everything worked as expected.
Now using 6.09.02 and the new feature TDataFrame, I do the following:
i) chain the root files the same way as described above.
ii) ROOT::Experimental::TDataFrame dataFrame(chain);
iii) auto selected = Select(dataFrame); // some cuts
iv) auto h1x = selected.Histo1D(“x”);
v) h1x->Draw(“AL”);
When executing the file, I get the following error:
Warning in TTreeReader::SetEntryBase(): The current tree in the TChain ntuple/nt2 has changed (e.g. by TTree::Process) even though TTreeReader::SetEntry() was called, which switched the tree again. Did you mean to call TTreeReader::SetLocalEntry()?
Error in TTreeReaderValueBase::CreateProxy(): The branch x contains data of type double. It cannot be accessed by a TTreeReaderValue
I certainly can change the variable “x” from double to float before filling the tree, but was does the warning message mean? How do I deal with directories using chains?
Any help or additional information is highly appreciated.
@Danilo reported a failure like that to me. I’ll have to debug this - that seems to be a problem with the TTreeReader / TDataFrame interaction… We’ll let you know once that’s fixed!
thanks for the feedback: as @Axel says, we are on it.
If it is possible in your case, could you check if the TDataFrame constructor which takes in input a glob has the same effect?
Hi Danilo,
OK, if I add the directory in the in the constructor, the error message disappears. However, now I get:
Error in TFile::TFile: file ntuple does not exist
Error in TTreeReaderValueBase::CreateProxy(): The tree does not have a branch called x. You could check with TTree::Print() for available branches.
Here is what I did:
ROOT::Experimental::TDataFrame dataFrame("nt2","ntuple");
long int nentries = (long int)chain.GetEntries();
cout << "Total number of initial events: " << nentries << endl; // no complaints up to here
TCanvas* c1 = new TCanvas();
auto h1x = selected.Histo1D<double>(TH1F("h1x", "x",40,-6,6), "x");
// auto h1x = selected.Histo1D<double>("x");
h1x->Draw("AL");
I think the file(s) are not defined correctly. How are they called? With the present invocation you are looking for a file called “ntuple” while perhaps what you wanted is “ntuple*.root”
Hi Danilo,
Yes, I am sure I don’t access the files properly. Here is what I do:
TChain chain("ntuple/nt2");
std::string DataDir = "/Users/korsch/data/rootfiles/" std::string Run = "Run" + itos(run) + "/";
std::string datafile("");
const int nfiles(12);
for(int i=0; i<nfile; i++){
datafile = DataDir + Run + "SomeName" + itos(i) + ".root";
chain.Add(datafile.c_str());
}
ROOT::Experimental::TDataFrame dataFrame("nt2","ntuple");
long int nentries = (long int)chain.GetEntries();
cout << "Total number of initial events: " << nentries << endl;
auto selected = Select(dataFrame); // cuts
TCanvas* c1 = new TCanvas();
auto h1x = selected.Histo1D<double>(TH1F("h1x", "x",40,-6,6), "x");
// auto h1x = selected.Histo1D<double>("x");
h1x->Draw("AL");
This yields the error message I posted in my previous note.
I would like to access a tree (ntuple) in a directory after I chained multiple files together.
It’s clear that there is something wrong in the way how I do it.
We don’t see an error on our side, so let’s try to understand your actual issue. There are two - one is due to the Histo1D which should be a Histo1F because the branch x contains floats. That one was easy
Now the second one: I’m a bit lost - there seems to be more than what I can read out of your posts (e.g. your chain set of with DataDir + Run + "SomeName" + ... isn’t used in the setup of the TDataFrame).
Can you create a stand-alone reproducer of what you are doing? Or share a single file that we then copy 12 times - anything that allows us to reproduce the issue you have?