Problem while reading an opened file from another function in pyroot


ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


Hi

I am having a class with some functions, like


class SFs():
    def __init__(self):
        # initialize your global vars instead as
        global eff_dataH #= root.std.map("string", root.TGraphAsymmErrors)()
        global eff_mcH #= root.std.map("string", root.TGraphAsymmErrors)()
        global inputRootFile

    def ScaleFactor(self,inputFile) :
        self.inputRootFile = str(inputFile)
        self.eff_dataH = root.std.map("string", root.TGraphAsymmErrors)()
        self.eff_mcH = root.std.map("string", root.TGraphAsymmErrors)()
        EtaBins=["Lt0p9", "0p9to1p2","1p2to2p1","Gt2p1"]

        #print inputRootFile
        fileIn = root.TFile(self.inputRootFile,"read")
        fileIn.ls()
        HistoBaseName = "ZMassEta"
        self.etaBinsH = fileIn.Get("etaBinsH")
        nEtaBins = int(self.etaBinsH.GetNbinsX())
        print "EtaBins...........",nEtaBins, len(EtaBins)
        for iBin in range (0, nEtaBins) :
            etaLabel = EtaBins[iBin]
            GraphName = HistoBaseName+etaLabel+"_Data"
            print GraphName,etaLabel

            self.eff_dataH[etaLabel]=fileIn.Get(str(GraphName))


            GraphName = HistoBaseName+etaLabel+"_MC"
            self.eff_mcH[etaLabel]=fileIn.Get(str(GraphName))

    def get_ScaleFactor(self,pt, eta) :
        print "checking for ",pt,eta
        efficiency_data = self.get_EfficiencyData(pt, eta)
        efficiency_mc = self.get_EfficiencyMC(pt, eta)
        if  efficiency_mc != 0. :
            SF = float(efficiency_data)/float(efficiency_mc)
        else  :
            SF=1.

        print "ScaleFactor::get_ScaleFactor(double pt, double eta) Scale Factor set to",SF,self.efficiency_data,self.efficiency_mc
        return SF


    def get_EfficiencyMC(self,pt, eta) :

        label = str(self.FindEtaLabel(eta))
        binNumber = self.etaBinsH.GetXaxis().FindFixBin(eta)
        label = self.etaBinsH.GetXaxis().GetBinLabel(binNumber)
        ptbin = self.FindPtBin("mc", label, pt)
        Eta = math.fabs(eta)
        label=label.replace("Eta","")

        if ptbin == -99 : eff =1
        else  : eff= self.eff_mcH[label].GetY()[ptbin-1]

        if eff > 1.  : eff = -1
        if eff < 0 : eff = 0.
        return eff

    def get_EfficiencyData(self,pt, eta) :

        label = self.FindEtaLabel(eta)
        binNumber = self.etaBinsH.GetXaxis().FindFixBin(eta)
        label = self.etaBinsH.GetXaxis().GetBinLabel(binNumber)
        print self.eff_dataH
        ptbin = self.FindPtBin("data", label, pt)
        Eta = math.fabs(eta)
        label=label.replace("Eta","")
        print "inside eff_data pt",pt,"eta",eta,"label",label,"N",self.eff_dataH[label].GetN(),"ptbin",ptbin

        if ptbin == -99 : eff =1
        else  : eff= self.eff_dataH[label].GetY()[ptbin-1]
        print "inside eff_data",eff

        if eff > 1.  : eff = -1
        if eff < 0 : eff = 0.

        return eff

    def FindPtBin(self, whatisit,EtaLabel, Pt) :

        eff_map=self.eff_mcH
        EtaLabel=EtaLabel.replace("Eta","")
        if whatisit == "mc" : eff_map=self.eff_mcH #EtaLabel = "ZMass"+EtaLabel+"_MC"
        if whatisit == "data" : eff_map=self.eff_dataH #EtaLabel = "ZMass"+EtaLabel+"_MC"
        #if whatisit == "data" : EtaLabel = "ZMass"+EtaLabel+"_Data"
        print "and inside FintPtBin",EtaLabel,self.eff_mcH[EtaLabel].GetN(),EtaLabel,eff_map[EtaLabel].GetN()

        Npoints = eff_map[EtaLabel].GetN()
        ptMAX = (eff_map[EtaLabel].GetX()[Npoints-1])+(eff_map[EtaLabel].GetErrorXhigh(Npoints-1))
        ptMIN = (eff_map[EtaLabel].GetX()[0])-(eff_map[EtaLabel].GetErrorXlow(0))
        print Npoints, "Npoints for  ===============>",eff_map[EtaLabel].GetN(),EtaLabel,Pt,eff_map[EtaLabel].GetN(),whatisit,ptMAX,ptMIN,eff_map[EtaLabel].GetXaxis().FindBin(Pt)
        if Pt >= ptMAX : return Npoints
        elif Pt < ptMIN :
            return -99
        else : return eff_map[EtaLabel].GetXaxis().FindFixBin(Pt)


    def FindEtaLabel(self,Eta) :

        Eta = math.fabs(Eta)
        binNumber = self.etaBinsH.GetXaxis().FindFixBin(Eta)
        EtaLabel = self.etaBinsH.GetXaxis().GetBinLabel(binNumber)

        print "inside FindEtaLabel",EtaLabel

        return EtaLabel

my problem is that when trying to call the get_ScaleFactor from another function, it fails. For instance, if I do


import sys
sys.path.append('SFs')
import ScaleFactor as SF


sf = SF.SFs()

getsf = sf.ScaleFactor("SFs/Muon_IsoMu27.root")

sf.get_ScaleFactor(34.8,2.1)

with an error like

   sf.get_ScaleFactor(34.8,2.1)
  File "SFs/ScaleFactor.py", line 70, in get_ScaleFactor
    efficiency_data = self.get_EfficiencyData(pt, eta)
  File "SFs/ScaleFactor.py", line 99, in get_EfficiencyData
    label = self.FindEtaLabel(eta)
  File "SFs/ScaleFactor.py", line 139, in FindEtaLabel
    binNumber = self.etaBinsH.GetXaxis().FindFixBin(Eta)
SystemError: none of the 2 overloaded methods succeeded. Full details:
  TAxis* TH1::GetXaxis() =>
    problem in C++; program state has been reset
  const TAxis* TH1::GetXaxis() =>
    problem in C++; program state has been reset

if on the other hand, I call the get_Scalefactor from withing the ScaleFactor methods, it works, but in that case, I would opening the .root file for every single event, while what I want, is to open the root file, store the histograms I need in the arrays (method ScaleFactor) and then, keep in memory these arrays/histos and while looping for the events, just pass the (pt,eta) to get the efficiency. Apparenlty, when calling the get_Scalefactor, something is not working when it comes to read the histograms.

This indicates that there was an error when invoking GetXaxis on the self.etaBinsH histogram. I see that
the histogram is obtained from the file here:
self.etaBinsH = fileIn.Get("etaBinsH")

Can you try to find out if that histogram has a correct value when retrieved from the file? Just a simple code like:

        fileIn = root.TFile(self.inputRootFile,"read")
        self.etaBinsH = fileIn.Get("etaBinsH")
        self.etaBinsH.GetXaxis()

works?

If what I suggested in my previous post works, then it might be an issue with the histogram being deleted because it is owned by the TFile from which you got it, and the TFile has already been destructed at the time you invoke get_ScaleFactor (it is the internal memory management of ROOT that ties TFiles to the objects that are retrieved from them, in C++).

If that is the reason, a quick fix would be to keep the TFile around, for instance binding it to self:
self.fileIn = root.TFile(self.inputRootFile,"read")

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