Choose same event from two root files

Hi,

I have two root files. I want to choose those events from the second root file which are present in the first one. There are different numbers of entries in two root files but the variable is common, for which I want to extract the values. Here is my sample code, which seems to choose all the events from the second one, instead of those which are also available in the first one.

        RooRealVar mbc("mbc","mbc",5.2,5.29);
        TFile *file = new TFile("rec.root");  //1st root file
        TTree *tree =(TTree*)file->Get("h1");
        TFile *file1 = new TFile("gen.root"); //2nd root file
        TTree *tree1 =(TTree*)file1->Get("h1");

        Float_t s_mbc;
        tree1->SetBranchAddress("mbc",&s_mbc);

        for(int j=0;j<tree->GetEntries();j++){
        tree->GetEntry(j); 
        
        for(int i=0;i<tree1->GetEntries();i++){
        tree1->GetEntry(i);
        if(i == j){
        mbc.setVal(s_mbc);
        cout <<i<<"\t"<<j<<"\t"<< "gen mbc =" <<mbc<<endl;  
        myfile <<i<<"\t"<<j<<"\t"<<mbc.getVal()<<endl;
        }
      }

Thank you in advance.

Maybe I didn’t understand what you’re trying to do, but why not using a TChain?

Hi @bellenot,

TChain is to add root files. I don’t want to add them. Instead, I want to show the resolution of a variable, let’s say mbc. For this I need to find the values of mbc from reconstruction level and subtract the values from generator level information. Let’s say I have 10K events in reconstruction level and 50K events in generator level. To get the resolution of the mbc, I need to choose those 10K events from generator level, which are also available in reconstruction level.

Am I clear now?

OK, I see. But in your code you only call SetBranchAddress on tree1:

        Float_t s_mbc;
        tree1->SetBranchAddress("mbc",&s_mbc);

Hi @bellenot,

Even though I defined mbc for two trees, it doesn’t solve the problem.
With the condition,
if(i == j){ mbc.setVal(s_mbc); myfile <<i<<"\t"<<j<<"\t"<<mbc.getVal()<<endl; }
I was expecting to choose only those events (i) of generator level, which are there in reconstruction level (j). Am I doing something wrong?

Sorry, I was confused with your code and the nested loops. So looking more carefully at your code, I think it is equivalent to:

   for (int i=0;i<tree->GetEntries();i++){
      tree1->GetEntry(i);
      mbc.setVal(s_mbc);
      cout <<i<<"\t"<< "gen mbc =" <<mbc<<endl;  
      myfile <<i<<"\t"<<mbc.getVal()<<endl;
   }

Since tree->GetEntry(j) does nothing and you only call mbc.setVal(s_mbc) when (i == j), am I correct?

Yes, I am getting the output of i (generator level) loop only.
What is the correct way to get information of i loop, the events which are also present in j loop?

You have to read each event in the first tree and compare with all the events of the second tree. Maybe @eguiraud has a faster (or more clever) method with RDataFrame…

Thanks for the response. But it’s not easy to read 1M events manually.
I would be grateful, if someone can suggest a easy/faster way to do this.

How do you know/compare events between one file and the other? What are the criteria? if it’s only the event number, then just do it sequentially…

Hi,
if the values you need to compare all fit in memory (1 million doubles occupy less than 8 MB of RAM) I suggest you extract them as standard vectors and then just operate on those.

With RDataFrame you can get the values of the mbc variable for all events with:

std::vector<float> all_mbc_rec = ROOT::RDataFrame("h1", "rec.root").Take<float>("mbc").GetValue();
std::vector<float> all_mbc_gen = ROOT::RDataFrame("h1", "gen.root").Take<float>("mbc").GetValue();

(I haven’t tested the code but it should give you an idea)

Cheers,
Enrico

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