1

I am using PyROOT to try to loop over the files in a folder, get a specific histogram which is present in all the files (two in a minimal test) and draw all the histograms in the same canvas. The minimal example which I run with just two histograms is the following.

import ROOT
import os

inputDir = "inputExample/"
outputDir =  "outputExample/"

c1 = ROOT.TCanvas('c1', 'c1')
for filename in os.listdir(inputDir):
    inputFile = ROOT.TFile.Open(inputDir+filename)
    hist = inputFile.Get("variables/Method_BDT/BDT/MVA_BDT_trainingRejBvsS")
    if filename == "first.root":
        hist.Draw("")
    else:
        hist.Draw("SAME")

c1.SaveAs(outputDir+"Superimposed.png")

I do not understand why only the second histogram is saved. Here is another minimal example which I would expect to be equivalent and is working correctly (I get both histograms drawn in the same canvas).

import ROOT

inputDir = "inputExample/"
outputDir =  "outputExample/"

c1 = ROOT.TCanvas('c1', 'c1')
inputFile1 = ROOT.TFile.Open(inputDir+"first.root")
hist = inputFile1.Get("variables/Method_BDT/BDT/MVA_BDT_trainingRejBvsS")
hist.Draw("")
inputFile2 = ROOT.TFile.Open(inputDir+"second.root")
hist = inputFile2.Get("variables/Method_BDT/BDT/MVA_BDT_trainingRejBvsS")
hist.Draw("SAME")

c1.SaveAs(outputDir+"Superimposed.png")
Mil
  • 111
  • 7
  • a naive thing to check: have you made sure that `'first.root'` is actually the first that appears in your `for` loop? – pseyfert Apr 27 '20 at 07:09
  • yes, I have already checked that and unfortunately it is not the issue – Mil Apr 27 '20 at 07:15
  • I have found this other question which maybe is related where pyroot is behaving unexpectedly https://stackoverflow.com/questions/25487199/python-c-api-omitted-variable-assignment-causes-unexpected-behaviour – Mil Apr 27 '20 at 07:27
  • Can you share the input `.root` files, to reproduce the issue? – Keldorn Apr 27 '20 at 13:32
  • @Keldorn here: https://www.dropbox.com/sh/dgek2mvwt8tzqno/AACgUX3I2EiA9fFu8Kg4jyIoa?dl=0 . Thanks! – Mil Apr 27 '20 at 13:37

1 Answers1

1

I suspect you're running into an issue with object ownership and the garbage collector between python and root. In the second example, all objects are still present in memory when c1.SaveAs is called. In the first example, the references to hist and the inputFile are created inside the loop, and thus their references go out of scope when you get to the second iteration.

In general, trying to use loops to create objects for plots in pyroot is fraught. Making a THStack and filling it with clones of the histograms you want to plot can often circumvent the problem of the original objects falling out of memory.

Red
  • 11
  • 1