RooFit in Python

Dear experts,

I am trying to write a code that has multiple pdf’s and want to be able to fit them to data and plot the background model along with plot. Including the appropriate snippet:

    w = ROOT.RooWorkspace("w")
    # create the variable
    w.factory( "tp_mass[100, 160]" )
    w.var( "tp_mass" ).SetTitle("tp_mass")
    w.var( "tp_mass" ).setUnit("GeV")

    w.factory( "dp1_mass[0,200]" )
    w.factory( "dp2_mass[0,200]" )

    # the set of variables
    treeVars = ROOT.RooArgSet()
    treeVars.add( w.var( "tp_mass" ) )
    treeVars.add( w.var("dp1_mass") )
    treeVars.add( w.var("dp2_mass") )
    data_RooDataSet = ROOT.RooDataSet( "data", "data", ROOT.RooArgSet( w.var( "tp_mass" ) ) )

    #RooArgList *mypdfs
    for itree in range(len(trees_data['trees'])) :

      data_RooDataSet_temp = ROOT.RooDataSet( "data", "data", (trees_data['trees'][itree]), treeVars)
      data_RooDataSet.append(data_RooDataSet_temp.reduce('(' + trees_data['weights'][itree] + ') * (' + cuts[cutName] + ')'))
      c1 = TCanvas('c1','PDF Fits',200,10,700,500)
      frame = tp_mass.frame()

However this throws me the error
AttributeError: ‘str’ object has no attribute ‘plotOn’"

I am using RooFit with python. Any help is very appreciated.

I do not see where you created the data Python object. Python is assuming it is a string, which does not have the method for plotting. Maybe you meant data_RooDataSet.plotOn(frame)?

Thanks for your reply Guilherme.
Maybe I should have specified, but I do create the RooDataSet called “data”

Is that not the correct syntax for creating “data” ?

Thanks in advance,

I spoke too soon. Your solution worked. Thanks a lot!

Hi Guilherme,

I have a related question:
I created some pdf’s and now want to plot the bkg_exp_pdf

    w.factory( "Exponential:bkg_exp_pdf(tp_mass, a1[4.03336e-02, 0.0001, 10])")
    w.factory( "Exponential:bkg_exp2_pdf(tp_mass, a2[4.88218e-01, 0.0001, 10])")
    w.factory( "Exponential:bkg_pdf(tp_mass, a[-0.5,-2,-0.2])"  )

    c1 = TCanvas('c1','PDF Fits',200,10,700,500)
    frame = tp_mass.frame()

But get the error:
"NameError: name ‘bkg_exp_pdf’ is not defined"
Can you point my mistake here?

Many thanks in advance,

Sure, when you call

w.factory( "Exponential:bkg_exp_pdf(tp_mass, a1[4.03336e-02, 0.0001, 10])")

you still need a way to get a hold of the Python object later, as it’s not created automatically

# not quite sure if this is what you want, but something similar to what's below
bkg_exp_pdf = ROOT.RooDataSet( "bkg_exp_pdf", "bkg_exp_pdf", ROOT.RooArgSet( w.var( "tp_mass" ) ) )

That is, the name given to the factory does not create the Python object by itself, you have to create it.
That is also why you needed data_RooDataSet before instead of just data, since Python didn’t know about the object named data, since you had created it with the other name. Hope that helps.

Thanks Guilherme for all the help :slight_smile:

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