Home | News | Documentation | Download

SetDirectory(0) using PyROOT inside a function

Dear experts,

I have a doubt on how SetDirectory works when using it inside a Python function.

I have a .root file which contains severals historams, in this case I am using a simple one for the sake of simplicity. I want to retrieve this histogram from the file, but this process is being done inside a function GetHist.

First, I tried this:

from ROOT import *

def GetHist():
    file = TFile("data_MC_original.root", "READ")
    h1 = file.Get("h_ptbin3_etabin6_nom_OrigDT")
    h1.SetDirectory(0)
    file.Close()
    return h1

h = GetHist()
c1 = TCanvas("", "", 800, 600)
h.Draw("hist")
c1.Update()

In the above case everything goes right. However, when I try changing the function to this

def GetHist():
    file = TFile("data_MC_original.root", "READ")
    h1 = file.Get("h_ptbin3_etabin6_nom_OrigDT")
    h1.SetDirectory(0)
    h_copy = h1.Clone()
    file.Close()
    return h_copy

I get an error saying

'CPyCppyy_NoneType' object has no attribute 'Draw'

So what’s happening there?

Other thing I tried was cloning the histogram ‘by hand’

from ROOT import *

def GetHist():
    file = TFile("data_MC_original.root", "READ")
    h1 = file.Get("h_ptbin3_etabin6_nom_OrigDT")
#    h1.SetDirectory(0) # With or without this, same error
    nbins = h1.GetNbinsX()
    xlow = h1.GetXaxis().GetXmin()
    xup = h1.GetXaxis().GetXmax()

    h_copy = TH1F("", "", nbins, xlow, xup)

    for bin in range(1, nbins):
        content = h1.GetBinContent(bin)
        h_copy.SetBinContent(bin, content)
    file.Close()
    del h1
    return h_copy

In that case, I get the same error as before:

'CPyCppyy_NoneType' object has no attribute 'Draw'

That last case worries me most. I have a histogram created by hand, not related at all (only the content, which is set by hand as well) with the file, so why this keeps happening?

EDIT: Also, sometimes when I run this version which works

def GetHist():
    file = TFile("data_MC_original.root", "READ")
    h1 = file.Get("h_ptbin3_etabin6_nom_OrigDT")
    h1.SetDirectory(0)
    file.Close()

    nbins = h1.GetNbinsX()
    xlow = h1.GetXaxis().GetXmin()
    xup = h1.GetXaxis().GetXmax()

    h_copy = TH1F("", "", nbins, xlow, xup)
    for bin in range(1, nbins):
        content = h1.GetBinContent(bin)
        h_copy.SetBinContent(bin, content)

    del h1
    return h_copy

the process “python 3.7” keeps running in my computer and using 100% of CPU. I have to manually kill it in Activity Monitor (using MacOS Catalina). Why this is happening?


Any help is very much appreciated!

Thank you very much!

Cheers,
Francisco

Hi,

About the first case, it looks like when you do the Clone, the cloned histogram is tied to the file, so when you close the file, the C++ histogram underneath is deleted and its Python proxy becomes None. Can you try to do h_copy.SetDirectory(0)? That should work and you won’t need to do the copy by hand.

1 Like

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