Fit an offset for RooHistPdf

Hi,

I would need to fit an offset on x-axes for a RooHistPdf.
How can I do it??

Thanks!

L:ivia

Hi Livia,

I assume you mean you reparameterize a RooHIstPdf H(x) as H(x-a).
You can do that using an alternate constructor form for RooHistPdf
(you’ll need a ROOT version 5.26 for this)

RooHistPdf(const char *name, const char *title, const RooArgList& pdfObs,
const RooArgList& histObs, const RooDataHist& dhist, Int_t intOrder=0);

This allows you to do e.g. the following

// Declare x and D(x)
RooRealVar x(“x”,“x”,-10,10) ;
RooDataHist dx(“dx”,“dx”,x,myTH1) ;

// Declare shifted xf(x) = x - a
RooRealVar a("a","a",1,0,10) ;
RooFormulaVar xf("xf","x-a",RooArgSet(x,a)) ;

// Take dx(x) as shape but represent it as dx(fx)
RooHistPdf hx("hx","hx",xf,x,dx,1) ;

In this way you RooHistPdf has now a parameter a that can be fitted.
You will most likely need to interpolate your histogram (as done above
in 1st order through the ‘1’ argument), otherwise your likelihood may not
depend in a smooth way on the parameter ‘a’ which will cause MINUIT
problems (this is especially the case if you fit binned data).

Wouter

Hi Wouter,

I must apologize for posting to a 3-year-old thread, but this seems to be the only place this is discussed. Do you think you demonstrate actually how the above example can be fit to data?

I have a somewhat more complete example perhaps to use as a starting point:

import ROOT

# Create binned data to make a PDF
energy = ROOT.RooRealVar("anenergy", "anenergy", 0, 10) 
mean = ROOT.RooRealVar("mean", "mean", 0, 10) 
sigma = ROOT.RooRealVar("sigma", "sigma", 0, 2)
gauss = ROOT.RooGaussian("gauss", "gauss", energy, mean, sigma)
ds = gauss.generate(ROOT.RooArgSet(energy), 100000)
binned_data = ds.binnedClone()

# define a coordinate transformation
scale = ROOT.RooRealVar("scale", "scale", 0.8, 1.1)
offset = ROOT.RooConstVar("offset", "offset", 0)
real_energy = ROOT.RooLinearVar("re", "re", energy, scale, offset)

# define the PDF
apdf = ROOT.RooHistPdf("test", "test", 
        ROOT.RooArgList(real_energy), 
        ROOT.RooArgList(energy), 
        binned_data, 
        1)  

# generate some new data.
ds = gauss.generate(ROOT.RooArgSet(energy), 100000).binnedClone()

# Try to plot the NLL
c1 = ROOT.TCanvas()
nll = apdf.createNLL(ds)

aframe = scale.frame()
nll.plotOn(aframe)
aframe.Draw()
c1.Update()
raw_input("E")

The above outputs several warnings, e.g.:

...
[#0] WARNING:Plotting -- At observable [x]=0.887 RooHistPdf::test[ pdfObs=(re) ]
     getLogVal() top-level p.d.f evaluates to zero @ pdfObs=(re = 0.57655)
...

which is generally telling me that the observables in data/pdf are not lining up. How would one properly do this?

Thanks for the help,
Mike