Cloning histograms with the same name

Hi,

I don’t know if this is a bug or a feature, but it has been painful to figure out.

I have a small macro which takes in argument the name of a file containing some trees. The macro processes the trees by creating some histograms. I don’t believe there is need for an example here.

Then, I would like to plot the same histogram for several different files on the same canvas. The histograms hence have the same names. Here is what I did :

root [0] .L mymacro.C
root [1] .x myfunction("file1.root");
root [2] TH1F* h1 = (TH1F*)histo->Clone("h1");
root [3] .x myfunction("file2.root");
Warning in <TROOT::Append>: Replacing existing TH1: histo (Potential memory leak).
root [4] TH1F* h2 = (TH1F*)histo->Clone("h2");

I was expecting that this procedure would clone as h1 and h2 the “histo” from respectively file1.root and file2.root. However, both h1 and h2 corresponded to the “histo” from the first file.

Apparently, despite the warning “histo” was not replaced by the new one. A workaround is to explicitely delete the first occurrence of “histo” before to execute the function again :

root [0] .L mymacro.C
root [1] .x myfunction("file1.root");
root [2] TH1F* h1 = (TH1F*)histo->Clone("h1");
root [3] histo->Delete();
root [4] .x myfunction("file2.root");
Warning in <TROOT::Append>: Replacing existing TH1: histo (Potential memory leak).
root [5] TH1F* h2 = (TH1F*)histo->Clone("h2");

I found this topic, which although related didn’t help much (I am mentioning it because it could help people trying to achieve this for different files).

[quote] was expecting that this procedure would clone as h1 and h2 the “histo” from respectively file1.root and file2.root. However, both h1 and h2 corresponded to the “histo” from the first file.[/quote]In your example only file1.root is used …

[quote]Apparently, despite the warning “histo” was not replaced by the new one. [/quote]The warning talks about ‘hsum’, so I am confused by your statement …

[quote]A workaround is to explicitely delete the first occurrence of “histo” before to execute the function again[/quote]I fail to see from your output how things are different …

Philippe.

Sorry, mix from actual names and dummy examples… I have edited and corrected the first post.

So this might be a bug ? I am using ROOT 5.28/00c, but I just tried on another computer with 5.18/00b with the following script and the behaviour is exactly the same :

void dummy(float uu)
{
        TH1F* histo = new TH1F("histo","histo",10,0,10);
        histo->Fill(uu);
}
root [0] .L /tmp/dummy.C                      
root [1] dummy(5)                             
root [2] TH1F* h1 = (TH1F*)histo->Clone("h1");
root [3] h1->GetMean()
(const Double_t)5.00000000000000000e+00
root [4] dummy(3)                             
Warning in <TH1::Build>: Replacing existing histogram: histo (Potential memory leak).
root [5] TH1F* h2 = (TH1F*)histo->Clone("h2");
root [6] h2->GetMean()                        
(const Double_t)5.00000000000000000e+00

[quote]So this might be a bug ? I am using ROOT 5.28/00c, but I just tried on another computer with 5.18/00b with the following script and the behaviour is exactly the same :[/quote]No, it is the expected behavior of your code:

root [1] dummy(5)creates one histogram named ‘histo’.

TH1F* h1 = (TH1F*)histo->Clone("h1");creates a second histogram named ‘h1’ … at this point histo still exist …

dummy(3) creates a 3rd histogram whose name is also histo and ‘somewhat’ replace the previous one … however it depends on how the old histogram is looked up.

root [5] TH1F* h2 = (TH1F*)histo->Clone("h2");In this case ‘histo’ still refers to the first histogram named ‘histo’.

Cheers,
Philippe.

Why ? Is there any way to access to the newly created histo ?

[quote]Why ? Is there any way to access to the newly created histo ?[/quote]If the histogram are going to have the same name, do not rely on the name lookup. For example use:TH1F *createHisto(float uu) { TH1F* histo = new TH1F("histo","histo",10,0,10); histo->Fill(uu); return histo; }

.L dummy.C histo = dummy(5) TH1F* h1 = (TH1F*)histo->Clone("h1"); h1->GetMean() histo = dummy(3) // Warning in <TH1::Build>: Replacing existing histogram: histo (Potential memory leak). TH1F* h2 = (TH1F*)histo->Clone("h2"); h2->GetMean()

Cheers,
Philippe.

Thanks. Unfortunately it becomes complicated when you have several histograms per script… I’m going to stick on the explicit delete method.

[quote]… I’m going to stick on the explicit delete method.[/quote]Which is anyway probably the ‘right’ solution, since you no longer need nor want the ‘first’ histogram, isn’t it?

Philippe.

Yes indeed.