-2

I am trying to call a function from within a function, and the former calls more functions etc.

import ROOT as root
import sys, math

class SFs():
    def __init__(self):
        self.get_EfficiencyData = None
        self.get_EfficiencyMC = None
        self.get_ScaleFactor = None
        self.eff_dataH = None
        self.eff_mcH = None
        self.get_ScaleFactor = None
        self.get_EfficiencyMC = None

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

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

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

        print self.eff_mcH[etaLabel].GetXaxis().GetNbins()
        print self.eff_mcH[etaLabel].GetX()[5]
        self.get_ScaleFactor(46.8,2.0)


    def get_ScaleFactor(self,pt, eta):

        efficiency_mc = get_EfficiencyMC(pt, eta)
        if  efficiency_mc != 0.:
            SF = 1/float(efficiency_mc)
        else:
            SF=1.

        return SF


    def get_EfficiencyMC(self,pt, eta):

        label = FindEtaLabel(eta,"mc")
        # label= "Lt0p9"
        binNumber = etaBinsH.GetXaxis().FindFixBin(eta)
        label = etaBinsH.GetXaxis().GetBinLabel(binNumber)
        ptbin = FindPtBin(eff_mcH, label, pt)
        Eta = math.fabs(eta)
        print "eff_mcH ==================",eff_mcH,binNumber,label,ptbin
        # ptbin=10
        if ptbin == -99: eff =1
        else: eff= eff_mcH[label].GetY()[ptbin-1]

        if eff > 1.: eff = -1
        if eff < 0: eff = 0.
        print "inside eff_mc",eff
        return eff

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

I want to call the get_ScaleFactor() which in turn calls the get_EfficiencyMC() etc, but I once trying calling the former, I get TypeError: 'NoneType' object is not callable

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
Terma
  • 81
  • 8
  • 3
    This is because you defined `get_ScaleFactor` and `get_EfficiencyMC` as None in your init method (in fact, you defined them as None twice). Why have you done that? – Daniel Roseman May 26 '19 at 18:55
  • You are calling the attribute, not the method. You should give them different names or remove the one in __init__ – Buckeye14Guy May 26 '19 at 18:55
  • @DanielRoseman can you suggest the correct syntax/working example ? – Terma May 26 '19 at 19:03
  • 1
    The correct syntax is not to define those attributes in `__init__`. – Daniel Roseman May 26 '19 at 19:19
  • I'd suggest adopting the conventions laid out in [PEP 8](https://www.python.org/dev/peps/pep-0008/). It will make your code a lot easier for others to read. – kungphu May 27 '19 at 05:23

1 Answers1

0

in your class init you define:

self.get_EfficiencyMC = None

and later define a function (i.e. class method) def get_EfficiencyMC(self,pt, eta):

when you create an instance of the class, the init part is executed shadowing the class method. Just either remove it from the init, or change the method name.

w_bufffet
  • 35
  • 5