Converted RooFit intro tutorials to PyRoot but issues remain

Hi all,

I decided to learn RooFit this week, so I started working my way through the introX tutorials found at

http://roofit.sourceforge.net/docs/tutorial/intro/index.html

I’ve been using PyRoot more than CINT lately, so I figured I’d convert the 9 tutorials to introX.py as a learning tool. Most worked fine, with some minor tweaks, but I’m still running into issues with two of them. I’m attaching a tarball here with the files in the hopes that they will be useful to others…and perhaps someone can point out my issues. The problems are summarized below.


intro2.py - I’m unable to plot the Components of a RooAddPdf. It’s trying to plot something, but it just shows up as a line at y=0. The code is at line 59:

sum.plotOn(xframe, RooFit.Components(RooArgSet(argus, gauss2)), RooFit.LineColor(2))

Where sum is a RooAddPdf.

intro8.py - I’m unable to plot a RooDataHist, dh, located at line 126.

dh.plotOn(yframe, RooTreeData.PlotOpt() )

This causes the code to spit out unintelligible (to me, at least) text.

TClass::TClass:0: RuntimeWarning: no dictionary for class RooTreeData::PlotOpt is available Error in <RooFormula::Compile>: ')' is expected [#0] ERROR:InputArguments -- RooFormula::RooFormula(hj <98>r Â Â±ì· Â±ì·¨Â±ì·¨Â±ì·°Â±ì·°Â±ì·¸Â±ì·¸Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬[#0]±ì±ì: compile error- RooDataHist::dh:fillHistogram: invalid cuts "`Ñ xy Â Â±ì· Â±ì·¨Â±ì·¨Â±ì·°Â±ì·°Â±ì·¸Â±ì·¸Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã[#0]¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬Â±Ã¬t::dh:plotOn: fillHistogram() failed [#0]

At line 148, I'm unable to properly add the dh2 RooDataHist to the frame and the session seg faults. 
dh2 = dh.reduce( RooArgSet(y), "x>0") # RooDataHist

Any help or suggestions would be greatly appreciated.

Matt
roofit_intro.tar.gz (8.55 KB)

Matt,

the issue with plotOn is a known one (lack of the C++ “using” statement as provided in the dictionary). This should help to get aroundit: http://root.cern.ch/phpBB2/viewtopic.php?t=6551.

Cheers,
Wim

I’d found that post, and tried the first two but they didn’t work. However, trying the third option

does seem to work! Thanks!

What is the "super"doing?

For completeness, here are the responses from the first two options.

dh.plotOn(yframe, RooLinkedList() )
seg faults with

[code]TClass::TClass:0: RuntimeWarning: no dictionary for class RooTreeData::PlotOpt is available

*** Break *** segmentation violation
Generating stack trace…

[/code]
2)

crashes more gracefully with

TClass::TClass:0: RuntimeWarning: no dictionary for class RooTreeData::PlotOpt is available Traceback (most recent call last): File "./intro8.py", line 127, in <module> RooDataHist.plotOn(dh,yframe) TypeError: RooPlot* RooDataHist::plotOn(RooPlot* frame, RooTreeData::PlotOpt o) => takes at least 2 arguments (1 given)

Is this a problem specific to RooDataHist? I’d used these fixes for the RooDataSet object without issue.

Matt

Hi Wim,

I was able to get past the second error in intro8.py with this

What is happening when I call this magical “super” function?

Matt

Matt,

‘super’ is a way of finding a method on a base class of a current instance without having to know the exact base class that defines the method. It is helpful if the hierarchy above the current class is subject to change. You can also use it to start off on a branch in case of multiple inheritance.

Here’s a code example:[code]class A( object ):
def m1( self ):
print ‘A.m1’

def m2( self ):
print ‘A.m2’

class B( A ):
def m2( self ):
print ‘B.m2’

class C( B ):
def m1( self ):
print ‘C.m1’

def m2( self ):
print ‘C.m2’

c = C()
super( C, c ).m1()
super( C, c ).m2()[/code]
Without ‘super’ you’d have to make the calls explicit (e.g. “A.m1©” and “B.m2©”), which is subject to errors if e.g. class B removes “m2” or adds “m1”.

As for 1) above, you get a segfault as an unknown class in a function is allowed to get objects passed through it (under the principle of “user knows best” this is been useful in the past).

Cheers,
Wim

Hi Wim,

Ah! Much appreciated for the tutorial. Very useful to know.

Inspired by your response, I returned to my Components issue in intro2. My original code reads

where sum is a RooAddPdf and argus and gauss2 are a RooArgusBG and RooGaussian respectively. When I run this, I do not see the line of the two components…just a line at y=0. So I decided to try

Unfortunately, I get the exact same output as the first bit of code. :frowning: Which is at least good in that they are consistent. Any thoughts on that?
Matt

Matt,

super() isn’t the solution in intro2.py b/c it’s still the same plotOn() function called (no issues with “using” here).

The problem appears to be a difference in python and C++ scoping rules: the result of “RooArgSet(argus, gauss2)” is refcounted to zero and collected before the plotOn call is done (i.e. python thinks that after passing the argument to RooFit.Components(), the useful life of the temporary is finished and it collects it, even though the ArgSet still likes to use it after that point …).

You’ll have to explicitly keep it alive a little longer:argset = RooArgSet(argus, gauss2) sum.plotOn(xframe, RooFit.Components(argset), RooFit.LineColor(2))
HTH,
Wim

Hi Wim,

Awesome! Works perfectly. I’ll have to keep scoping issues in mind for any other bugs I run across. Thanks much for the time on this. I’m glad I can keep using PyRoot for this stuff.

Matt