ROOT Conditional branch selection

I have a ROOT file. I can read the tree and select the data inside a specific branch of it, called for instance “branch_name_1”. Now, I want to select the data on this branch with a specific condition on another branch. Let me provide an example. I want all entries of the “branch_name_1” with the condition that the value of “branch_name_2” is bigger than 10. How can I do this?

You should try to use TDataFrame

1 Like

Thank you very much bellenot. Providing I’m new to ROOT, could you provide more details?

I think @eguiraud or @Danilo are the best candidates to give more details :slight_smile:

Hi,

I believe the guide is rather complete, you should have a look to it and to the TDataFrame tutorials (https://root.cern/doc/master/group__tutorial__tdataframe.html).

In your case, assuming that

  • The tree is called myTree and the file myFIle.root
  • branch_name_1 and branch_name_1 are two doubles
  • you want to make an histogram of the values in branch_name_1
    you can do:
ROOT::Experimental::TDataFrame d("myTree","myFile.root");
auto h = d.Filter("branch_name_2 > 3.").Histo1D("branch_name_1");
h->Draw();

In case you want all values of branch_name_1 in a vector for every entry passing the filter on branch_name_2 you should use the Take action instead of Histo1D (see https://root.cern/doc/master/classROOT_1_1Experimental_1_1TDF_1_1TInterface.html#a9f38cc47a9d03fc95ed9c550c8664612).

Cheers,
D

2 Likes

Hi,

Thank you very much @Danilo. I just ran the code you wrote and I got this error:

IncrementalExecutor::executeFunction: symbol ‘_ZN4ROOT6Detail3TDF12TLoopManager3RunEv’ unresolved while linking [cling interface function]!
You are probably missing the definition of ROOT::Detail::TDF::TLoopManager::Run()
Maybe you need to load the corresponding shared library?

I use ROOT 6.10/00. I don’t get what the problem is. I would be very much thankful if I could get the point of the problem.

Cheers

Hi,
if you are running the code as a macro, try putting a + at the end (this issue should be fixed in the next patch release): root -l macro.C+.

Otherwise you can always make this a full-blown program:

#include "ROOT/TDataFrame.hxx"

int main() {
  ROOT::Experimental::TDataFrame d("myTree","myFile.root");
  auto h = d.Filter("branch_name_2 > 3.").Histo1D("branch_name_1");
  h->Draw();
  return 0;
}

and compile it with g++ -o main main.cpp $(root-config --libs --cflags) -lTreePlayer (-lTreePlayer tells the linker to bring in the library where TDataFrame is defined).

1 Like

Thank you very much @eguiraud! It worked.

Cheers

Great,
marking this as solved then

This one is a solution but I would be interested in understanding how the missing symbol error occurred. What platform are you on? Did you use binaries or build root yourself?
Last important question: how did you run the snippet? Prompt or macro?

Cheers,
D

Actually, I still have problem with the code you wrote. It has an error related to double declaration of a variable as far as I understand.

I use ubuntu 16.04, and I ran it as macro.

Hi,
can you post the macro you are executing? And do you still have problems if you compile the code?

@Danilo @eguiraud. Here is my code and the error I got.

    TFile *f = new TFile("./MC13TeV_TTJets.root");
	ROOT::Experimental::TDataFrame d("data",f,{"mttbar"});
	int k=1;
	auto fil = d.Filter("nj=="+std::to_string(k));
	cout << *(fil.Mean()) << "result" << endl;

I got this error:

input_line_16:3:5: error: redefinition of ‘nj’
int nj;
^
input_line_16:2:5: note: previous definition is here
int nj;
^
terminate called after throwing an instance of ‘std::runtime_error’
what(): Cannot declare these variables namespace __tdf_0 {
int nj;
int nj;
}
Interpreter error code is 1.

I executed the code using this: root -l test.c+.

Hi,

I cannot reproduce. This is the macro I use (I create a dummy dataset with 2 columns according to the names you mentioned):

#include "ROOT/TDataFrame.hxx"
void a() {
// Create dummy dtaset
ROOT::Experimental::TDataFrame i(10);
int nj_0 = 1;
i.Define("mttbar", [&nj_0](){return 100+nj_0;}).Define("nj", [&nj_0](){return nj_0++;}).Snapshot("data", "MC13TeV_TTJets.root");

// Your code
auto f = new TFile("./MC13TeV_TTJets.root");
ROOT::Experimental::TDataFrame d("data",f,{"mttbar"});
int k=1;
auto fil = d.Filter("nj=="+std::to_string(k));
cout << *(fil.Mean()) << "result" << endl;
}

Cheers,
D

1 Like

I ran your code without any problem, but I still have the same problem with the root file I have.

@Danilo I ran the following code with this root file: https://root.cern.ch/root/files/tutorials/mockupx.root

#include <TROOT.h>
#include <TFile.h>
#include <TTree.h>
#include <TCanvas.h>
#include <TH1F.h>
#include <string>

#include "ROOT/TDataFrame.hxx"

void final() {
    TFile *f = new TFile("./mockupx.root");
	ROOT::Experimental::TDataFrame d("MyTree",f);
	std::string s = std::to_string(1.0);
	std:string c = "electrons.fTriggered < "+s;
	auto fil = d.Filter(c.c_str()).Histo1D("electrons.fPt");
}

#ifndef __CINT__
int main() {
	final();
}
#endif

I got the following error:

input_line_17:1:41: error: no member named ‘fTriggered’ in ‘TClonesArray’
namespace __tdf_0{ auto res = electrons.fTriggered < 1.000000;}
~~~~~~~~~ ^
terminate called after throwing an instance of ‘std::runtime_error’
what(): Cannot interpret this expression: namespace __tdf_0{ auto res = electrons.fTriggered < 1.000000;}

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.