Creating a RooDataHist from a 2D histogram

I’m struggling currently with PyROOT and trying to create a RooDataHist from a TH2D. The creation from a TTree works like charm, but when I try to initialize the RooDataHist with the 2D histogram it fails to convert the argument:

hs=getH2FromTree(11,"saveHPS/cands","sumpt:mp","nlep==3",nbin,bmin,bmax,nbin,bmin,bmax,lumi)

mp=RooRealVar("mp","Mass",10,500)
sumpt=RooRealVar("sumpt","Scalar sum of pT",0,500)
data=RooDataHist("data","data",RooArgSet(mp,sumpt),hs)
Traceback (most recent call last):
  File "./test2DRooFit.py", line 22, in <module>
    data=RooDataHist("data","data",RooArgSet(mp,sumpt),hs)
TypeError: none of the 8 overloaded methods succeeded. Full details:
  RooDataHist::RooDataHist() =>
    takes at most 0 arguments (4 given)
  RooDataHist::RooDataHist(const char* name, const char* title, const RooArgSet& vars, const char* binningName = 0) =>
    could not convert argument 4 (expected string or Unicode object, TH2D found)
  RooDataHist::RooDataHist(const char* name, const char* title, const RooArgList& vars, const RooCmdArg& arg1, const RooCmdArg& arg2 = RooCmdArg(), const RooCmdArg& arg3 = RooCmdArg(), const RooCmdArg& arg4 = RooCmdArg(), const RooCmdArg& arg5 = RooCmdArg(), const RooCmdArg& arg6 = RooCmdArg(), const RooCmdArg& arg7 = RooCmdArg(), const RooCmdArg& arg8 = RooCmdArg()) =>
    could not convert argument 3
  RooDataHist::RooDataHist(const RooDataHist& other, const char* newname = 0) =>
    takes at most 2 arguments (4 given)
  RooDataHist::RooDataHist(const char* name, const char* title, const RooArgSet& vars, const RooAbsData& data, Double_t initWgt = 1.0) =>
    could not convert argument 4
  RooDataHist::RooDataHist(const char* name, const char* title, const RooArgList& vars, const TH1* hist, Double_t initWgt = 1.0) =>
    could not convert argument 3
  RooDataHist::RooDataHist(const char* name, const char* title, const RooArgList& vars, RooCategory& indexCat, map<std::string,TH1*> histMap, Double_t initWgt = 1.0) =>
    takes at least 5 arguments (4 given)
  RooDataHist::RooDataHist(const char* name, const char* title, const RooArgList& vars, RooCategory& indexCat, map<std::string,RooDataHist*> dhistMap, Double_t wgt = 1.0) =>
    takes at least 5 arguments (4 given)

The reason I wanted to use TH2D is that it’s a combination of a lot of trees with correct weights. If I can create a RooDataSet with say 10 trees each with a fixed weight attached to it, then that’s an alternative…

Hi,

not a RooFit expert here … are you sure it can be done? The only ctors I see for RooDataHist are 1D, and its data members are all 1D AFAICS.

If it is not a python-specific problem, you’re better off on the “Stat and Math Tools” as that’ll be read by RooFit experts.

Cheers,
Wim

[quote=“wlav”]not a RooFit expert here … are you sure it can be done? The only ctors I see for RooDataHist are 1D, and its data members are all 1D AFAICS.

If it is not a python-specific problem, you’re better off on the “Stat and Math Tools” as that’ll be read by RooFit experts.
[/quote]

All the tutorials done in C++ accept 1-3 dimensional TH’s there I’m assuming it’s again an implicit cast that’s being done that doesn’t work with python. I know I have to always use direct RooArgList or RooArgSet instead of the variables in arguments and I’m assuming that because the constructor has a direct TH1 that works, but for TH2 etc there are dynamic casts in C++ that take care of this.

And it has to be possible… From RooFit manual:
Importing data
Generally speaking, data comes in two flavors: unbinned data, represented in ROOT by class TTree and binned data, represented in ROOT by classes TH1,TH2 and TH3. RooFit can work with both.

The examples in this section have always dealt with one-dimensional datasets. Both RooDataSet and RooDataHist can however handle data with an arbitrary number of dimensions.

But I think the best example is from page 98 of the manual:

TH2* hh = (TH2*) gDirectory->Get(“ahisto”) ; 

RooRealVar x(“x”,”x”,-10,10) ;
RooRealVar x(“y”,”y”,-10,10) ; 
RooDataHist data(“data”,”dataset with (x,y)”,RooArgList(x,y),hh)
1 Like

Ah, I see, a TH2 derives from TH1. Never knew that. So in the list of arguments in your example, you have a RooArgSet for the 3rd variable, in the RooFit example, a RooArgList is used. In the python printout of constructors, it also wants a RooArgList. I see that there is an implicit conversion from RooArgSet to RooArgList, so the problem in python is with the 3rd argument, not the 4th.

I.e., this should work (barring issues with temporaries, as RooFit likes to cast const away):data=RooDataHist("data","data",RooArgList(RooArgSet(mp,sumpt)),hs)
And if temporaries are a problem, this can be done:as = RooArgSet(mp,sumpt) al = RooArgList(as) data=RooDataHist("data","data",al,hs)
HTH,
Wim

Damn, that’s stupid of me how I didn’t notice the ArgSet vs ArgList difference :stuck_out_tongue: Anyway, works now and no temporaries were needed…

Btw is there some way to make PyROOT not require RooFit. prefix for things like CutRange, LineColor, … ?

Hi,

no, that’s not currently possible: RooFit is a namespace and that is implemented as a python class, not a python module. The reason for using a class is to allow properties (i.e. global variables that are settable).

Cheers,
Wim

Hi,

correction, I’ve just learned here from Armin Rigo that you can do:[code]>>> import ROOT

import sys
sys.modules[‘RooFit’] = ROOT.RooFit
from RooFit import *[/code]
Cheers,
Wim