Superimpose 2 Histo's from different root files with different trees

Hi, I have 2 different root files, with different trees but same leaves. I want to draw the same variable for each of the root files in one histogram so that I can compare. The code for “extracting” one histogram out of the root file is:

void energy_top_susysignal(){
TFile * f = new TFile(“susysignal_total.root”);
TH1F * h1 = (TH1F*) f->Get(“signal_Tree”);

I know about Draw(“same”), but here the argument of Draw is the leaf. How do I do it?



ROOT::Experimental::TDataFrame d1("signal_Tree","susysignal_total.root");
auto h1 = d.Histo1D("energytop1");
ROOT::Experimental::TDataFrame d2("signal_Tree","TheOtherFile.root");
auto h2 = d2.Histo1D("energytop1");


Hello, and thank you very much for the response. But I get the following error:

Error: class,struct,union or type ROOT::Experimental not defined energy_top.C:3:
*** Interpreter error recovered ***
How should I confront it?

Thank you!

One more question if I may, shouldn’t this also work? where is the mistake?

TFile * f = new TFile(“susysignal_total.root”);
TFile * g = new TFile(“susybackground_total.root”);
TH1F * h1 = (TH1F*) f->Get(“signal_Tree”);
TH1F * h2 = (TH1F*) g->Get(“susybg_Tree”);

h1->Draw(); h2->Draw(“same”);

the arguments in “Draw” are the leafs that have the histogram, so they need to be specified…

histograms have no leaves.

True. But leaves have histograms. That’s what I said…

??? leaves of what ???

Root file-> has tree(s)->has leaves->leaves correspond to a histo.

So, maybe you try:

TFile * f = new TFile("susysignal_total.root");
TTree *t1; f->GetObject("signal_Tree", t1);
TFile * g = new TFile("susybackground_total.root");
TTree *t2; g->GetObject("susybg_Tree", t2);
t1->Draw("energytop1 >> h1");
t2->Draw("energytop1 >> h2", "", "same");

Ok Thank you very much. It worked. But since you plot them like that, how do I get to fix the axis range? I tried “t1->GetYaxis()->SetRangeUser(0,700);” but it doesn’t work.

Thank you

This is looking terribly wrong and is one of the things I hate about ROOT/many people using ROOT.
A tree is NOT a histogram. Thus you are casting two things that don’t fit. Even if the C-style cast (i.e. (type)something) is used in many ROOT examples, I can only urge everyone not to use it. In this case that should be a dynamic_cast<TTree*> plus an additional check if the result is nullptr - and if it is, something fatal should be happening.

Wile’s solution using GetObject doesn’t have this problem but I dislike having separate declare + get steps.

So my solution (and IMHO something like this should be provided by ROOT) is something like this

template <typename T>
T* checkedGet(TFile *f, const char *name) {
   auto obj = f->Get(name);
   if (!obj) throw std::runtime_error((string("No object named ") + name + " in the file " + f->GetName()).c_str());
   auto result = dynamic_cast<T*>(obj);
   if (!result) throw std::runtime_error((string("Object named ") + name + " in the file " + f->GetName() + " is of a different type").c_str());
   return result;

// use it:
auto tree = checkedGet<TTree>(f, "nameOfTree");


this is available only starting with ROOT 6.10.


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