Get a Variable from RooAbsPdf in PyROOT

In RooFit one can get variables of the given pdf:

RooArgSet* sigVars = sig->getVariables();

In C++ one can probably convert them to RooRealVar-s. However, in Python I can’t see how one could do that.

It works for RooArgList, but getVariables() returns a RooArgSet.

I would like to print the pdf for each given data point, that is why I need to set the RooFit variable for each point (which is ugly in itself, but it is so).

I think @jonas can help

thank you. At the moment I have to return Variables separately (not inside RooAbsPdf, but together with that in a tuple).

Hi!

PyROOT automatically casts any object down to its actual type. So you can just get the elements from the RooArgSet and they will be RooRealVar proxies that you can do the usual RooRealVar things with (e.g. getVal()).

Here a little demo:

import ROOT

x = ROOT.RooRealVar("x", "x", 0., -10., +10.)
mu = ROOT.RooRealVar("mu", "mu", 0., -10., +10.)
sigma = ROOT.RooRealVar("sigma", "sigma", 4., 0.01, 10.)

gauss = ROOT.RooGaussian("gauss", "gauss", x, mu, sigma)

variables = gauss.getVariables()

variables[0].Print()
print(type(variables[0]))
print(variables[0].getVal())

Output

RooRealVar::mu = 0  L(-10 - 10)
<class cppyy.gbl.RooRealVar at 0x40f119a0>
0.0

I hope this is what you needed! If not, let me know.

Thank you, @jonas !

I believe my problem was that I transferred that variable to another function, and it was deleted on its way (constants of my fit were deleted). I fixed that later by keeping track of those parameters.

I see, yes Python takes ownership of everything.

In that case, you can release the Python ownership and pass it to the RooFit pdf, then you don’t need to do the bookkeeping yourself:

import ROOT

def release_python_ownership(args):
    for arg in args:
        ROOT.SetOwnership(arg, False)
    return args

def create_pdf():

    x = ROOT.RooRealVar("x", "x", 0., -10., +10.)
    mu = ROOT.RooRealVar("mu", "mu", 0., -10., +10.)
    sigma = ROOT.RooRealVar("sigma", "sigma", 4., 0.01, 10.)

    gauss = ROOT.RooGaussian("gauss", "gauss", x, mu, sigma)

    variables = [x, mu, sigma]

    gauss.addOwnedComponents(release_python_ownership(variables))

    return gauss

gauss = create_pdf()

variables = gauss.getVariables()

variables[0].Print()
print(type(variables[0]))
print(variables[0].getVal())

Or using the RooWorkspace is also a good option, because then it owns all the RooFit objects (in fact this is what most RooFit-based frameworks do).

1 Like

Hi @jonas, thanks for the suggestion.
Unfortunately I don’t get from your function: do you release Python or ROOT ownership?
I would like my fit results to be copied (via Python’s copy.deepcopy). And ideally pickled when needed.
Would your function solve that or should I do something else?
I can open a new topic if needed.
Thank you in advance.

UPD: I created a similar topic on copying and memory management:

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