# Difficult problem with ROOT

First, sorry for the long post, but it’s very simple. This problem is not a difficult problem, but I’ve a big problem to work with ROOT. I simplify the problem, I hope someone can find an easier solution.

Let t1 and t2 be two TTree class. They have the same variables called “A”, “B”, … but t1 and t2 are different, in particular they have different entries number.

Let el1, el2, el3, … be TEntryLists that can be applied to t1 and to t2.

Let a list like: variables_to_draw=[“A”,“B”,“A:B”,…] describe what we want to plot.

The problem is: draw the histogram normalized of the variables specified in variables_to_draw. In this example I want to draw 2 TH1F (A,B) and 1 TH2F (A:B). I want to draw all the histograms in the same canvas, and I want to superimpose the variable of the two TTree. Redo all applying el1,el2,el3, …

The code is a python code, but it’s not this the problem

``````import copy
import random

def do(canvas,variables_to_draw,t1,t2):
...
canvas.Divide(nx,ny)
histos = []
seed = random.random()
for (n,var) in enumerate(variables_to_draw):
canvas.cd(n+1)
name1 = "1_%s%s" % (n,seed)
name2 = "2_%s%s" % (n,seed)

t1.Draw(var+">>"+name1,"","goff")
t2.Draw(var+">>"+name2,"","goff")

h1 = copy.copy(gDirectory.Get(name1))
h2 = copy.copy(gDirectory.Get(name2))

try:
h1.Scale(1./h1.GetEntries())
except(ZeroDivisionError):
pass
try:
h2.Scale(1./h2.GetEntries())
except(ZeroDivisionError):
pass

histos.append(h1)
histos.append(h2)

h1.Draw()
h2.Draw("same")

canvas.Update()
canvas.histos = histos

def main(canvas,variables_to_draw,t1,t2,el1,el2,el3):
els = [el1,el2,el3]
for e in els:
t1.SetEntryList(e)
t2.SetEntryList(e)
do(canvas,variables_to_draw,t1,t2)
wait_key_pressed()``````

the random seed is necessary, because the name of the histogram need to be different for all the els loop
This is my dream:

``````def do(canvas,variables_to_draw,t1,t2):
...
canvas.Divide(nx,ny)

for var in variables_to_draw:
h1 = Data2Histogram(t1,var)
h2 = Data2Histogram(t2,var)

h1.NormalizeArea(1)
h2.NormalizeArea(1)

subcanvas = canvas.NextSubCanvas()
subcanvas.Draw(h1)
subcanvas.Draw(h2,"same")  #no persistency problem, all automatic

# or better:
subcanvas.DrawHistogram([h1,h2],NormalizedArea=True)
# ok, this is too much for C++``````

It is not obvious to understand what your problem is, since you do not state it. If if it just a graphics problem (superimposition of histograms in the same pad, I suggest to use a THStack. see tutorial \$ROOTSYS/tutorials/hist/hstack.C

Rene

[quote=“brun”]It is not obvious to understand what your problem is, since you do not state it. If if it just a graphics problem (superimposition of histograms in the same pad, I suggest to use a THStack. see tutorial \$ROOTSYS/tutorials/hist/hstack.C

Rene[/quote]

No, the problem is not this. The problem is that the code is simply horrible, for example why I need to use a random seed? I stated what is the problem:

Rene

the problem is: is the random seed necessary? Is there an easier solution similar to the second code? For example

``````     name1 = "1_%s%s" % (n,seed)
name2 = "2_%s%s" % (n,seed)

t1.Draw(var+">>"+name1,"","goff")
t2.Draw(var+">>"+name2,"","goff")

h1 = copy.copy(gDirectory.Get(name1))
h2 = copy.copy(gDirectory.Get(name2))``````

an other problem is: why name1 and name2? They are necessary only because I don’t know an alternative solution. name1 and name2 has no importance, but they’re needed by ROOT, only this.

``````     histos.append(h1)
histos.append(h2)
canvas.histos = histos ``````

without this the histograms are deleted when they go out of scope, but why? Why the canvas doesn’t automatically save them inside itself? Can someone tell me a easier and better solution?

[quote]the problem is: is the random seed necessary[/quote]You probably can replace it by information from the tree name or the file name (which actually would be a clearer solution).

Cheers,
Philippe.

The name is necessary only to recover the histogram generated by the Draw function, and I don’t understand why. It is more simple something like:

``h1 = Data2Histogram(t1,var) ``

that return an histogram, t1 is one TTree, var a string containing the name of the variables you want to plot.

[quote=“pcanal”][quote]the problem is: is the random seed necessary[/quote]You probably can replace it by information from the tree name or the file name (which actually would be a clearer solution).

Cheers,
Philippe.[/quote]
The name and the file are the same for all the data I want to plot. What is different is the name of the variable, and the name of the TEntryList, but the function “do” doesn’t know the TEntryList (name), because the TEntryList is set to the TTree before the calling of the funcion “do”. Yes, I can do TTree::GetEntryList… The main problem is: why we need naming?

Thanks to reply to my post, I know… I’m a pain

I think his question is: why he should use intermediate variables and functions call like name1 and name2 etc, in order to pass the data from a tree to a histogram for example?

Data2Histogram is type of function he is looking for, which in principle can be written by a user.

TTree has a very strong Draw method and there are ways to pass the data from a tree to another object, such as GetV1, GetV2, etc.

Cheers,
Philippe.