Cuts with two different ttrees

Dear experts,

I have two TTrees with different number of entries. What I would like to have a correlation between these two trees in order to plot one variable from one tree with cuts applied on a variable from the other tree.

I try to reproduce below a simplified version of what I have so far:

Double_t x1;
tree1->SetBranchAddress("x1", &x1);
Double_t x2;
tree2->SetBranchAddress("x2", &x2);
TCut cut = "x1>1.";
TH1F *hist;
tree2->Draw("x2>>hist", cut);

Is there any way I can do this?

Any suggestion is highly welcomed!
Thank you in advance :slight_smile:

Hi @Ailema ,
if the two trees have different number of entries what is the association between entries in tree1 and entries in tree2?

Cheers,
Enrico

Hi eguiraud! Sorry for the late reply…
I have an event tree and a track tree, so for each event I have a number o tracks that correspond to it.

Hi @Ailema ,

typically this is done in ROOT with TTreeIndex, or the TTree method BuildIndex.

Basically what you want to do is:

  • call eventTree->BuildIndex("run", "event") where “run”/“event” should be the names of branches that provide an association between entries of the two trees. Basically for every entry in the trackTree, the corresponding entry that will be loaded from eventTree will be the one with the same values for "run" and "event" (and there must be one, otherwise you’ll read bogus data)
  • call trackTree->AddFriend(eventTree) so that loading entries in trackTree now triggers the loading of the corresponding entries in eventTree
  • loop over trackTree – you can check by calling eventTree->GetReadEntry() that the correct entry of eventTree is loaded for every entry of trackTree

@pcanal might be able to add more information or point to an example usage of BuildIndex

Cheers,
Enrico

2 Likes

Thanks a lot for your reply!
Just to make sure that I have understood right: so I just add a branch containing the run and event no. in both event and track tree (in order to have a match between these two trees since they have different no of entries).
Just when I want to match the trees and read them, I call the BuildIndex() and AddFriend() methods?

Yes, that’s the idea :slight_smile:

1 Like

So I did what you have mentioned and it looks ok, it seems that the index is used correctly.
However, I am struggling a bit to understand how I should further use this information in order to access data in the friend tree correctly in order to correlate an observable from the event tree with one from the track tree? I didn;t found an example with trees with different number of entries and different observables (except for the indexes) that need to be correlated .

Thanks to the combination of BuildIndex and AddFriend, when you call trackTree->GetEntry(n) this will automatically set the corresponding entry in eventTree. Other than that you should read the data from the tree as usual.

If you provide a small self-contained reproducer I can take a better look.

Cheers,
Enrico

Hi @eguiraud

Please find below an example of how I read the trees:

    TFile *file = TFile::Open("data.root");
    TTree *eventTree = (TTree *)file->Get("ev");
    eventTree->BuildIndex("run", "event");
    TTree *trackTree = (TTree *)file->Get("trk");
    trackTree->BuildIndex("run", "event");
    eventTree->AddFriend(trackTree);
    Int_t run(0), event(0);
    Double_t fP(0.);
    trackTree->SetBranchAddress("run", &run);
    trackTree->SetBranchAddress("event", &event);
    trackTree->SetBranchAddress("p", &fP);
    Int_t fRun(0), fEvent(0);
    Double_t fMult(0.), fMult2(0.);
    eventTree->SetBranchAddress("run", &fRun);
    eventTree->SetBranchAddress("event", &fEvent);
    eventTree->SetBranchAddress("mult", &fMult);
    eventTree->SetBranchAddress("mult2", &fMult2);

I would like to make sure that the observables are correlated, and, for example, I would like to draw “fMult” with cuts on “fP”, or a 2D hist of fMult:fP with cuts on fMult2.

Later edit:
are these ok?
trackTree->Draw(“ev.mult>>hist”, “p>3”);
trackTree->Draw(“ev.mult:p>>hist”, “mult2>10”);

Many thanks in advance!

@pcanal can you please take a look?

@Ailema I think you only need the BuildIndex call on the friend tree, not on both (but it should not break anything). Anyway when you call eventTree->GetEntry(n) does that load the correct data for run, event and fP?

Cheers,
Enrico

They look fine.