RooFit: fit in a range

Hi,
I defined a Pdf(m,t) that I use to generate data with m in the range [m_min=5190,m_max=5500] and t in [t_min=-2,t_max=12]
I would like to fit the data selecting only the events with t in the subrange [t_1=0.5;t_2=12]
So I defined
t->setRange(“largeTimes”,0.5,12);
If I define:
RooNLLVar nll_TOT = new RooNLLVar(name.c_str(),“log(L)”,pdf_TOT,*data,Extended(true),Range(“largeTimes”));
I get this message:
RooRealVar::setRange(m) new range named ‘NormalizationRange’ created with bounds [5190,5500]
RooRealVar::setRange(t) new range named ‘NormalizationRange’ created with bounds [-2,12]
RooRealVar::setRange(m) new range named ‘fit’ created with bounds [5190,5500]
RooRealVar::setRange(t) new range named ‘fit’ created with bounds [-2,12]
_refCoefRangeName = 0x3e7eff0
RooAddPdf::syncCoefProjList(pdf_TOT) creating coefficient projection integrals
from current normalization: (m,t)
with current range:
to reference normalization: (m,t)
with reference range: NormalizationRange
_refCoefRangeName = 0x3e7eff0
RooAddPdf::syncCoefProjList(pdf_sig_mass) creating coefficient projection integrals
from current normalization: (m)
with current range:
to reference normalization: (m)
with reference range: NormalizationRange
RooNLLVar::RooNLLVar ERROR: unrecognized command: RangeWithName

The fit works anyways, but the plots I do after minimization indicate that the normalization of the pdf might have some problems
While if I type
RooNLLVar nll_TOT = new RooNLLVar(name.c_str(),"-log(L)",pdf_TOT,*data,true,“t>0.5”);
I get no error

RooRealVar::setRange(m) new range named ‘NormalizationRange’ created with bounds [5190,5500]
RooRealVar::setRange(t) new range named ‘NormalizationRange’ created with bounds [-2,12]
RooRealVar::setRange(m) new range named ‘fit’ created with bounds [5190,5500]
RooRealVar::setRange(t) new range named ‘fit’ created with bounds [-2,12]
_refCoefRangeName = 0x3e7ef70
RooAddPdf::syncCoefProjList(pdf_TOT) creating coefficient projection integrals
from current normalization: (m,t)
with current range:
to reference normalization: (m,t)
with reference range: NormalizationRange
_refCoefRangeName = 0x3e7ef70
RooAddPdf::syncCoefProjList(pdf_sig_mass) creating coefficient projection integrals
from current normalization: (m)
with current range:
to reference normalization: (m)
with reference range: NormalizationRange

and the same problems of normalization.
From the message above it seems that the fit and normalization range is still m=[5190,5500] t=[-2,12]
Could you help me to understand if this is correct?
Thanks,
Stefania

Hi Stefania

(Sorry for the late reply, I was on vacation among others)

The informational messages you see from the construction of the first likelihood in your example are OK and consistent with what you do. From what I can see it correctly defines a likelihood in the range “largeTimes”. What you see happening is that a NormalizationRanges is created that is identical to the full range of the observables. This range is needed to maintain a correct definition of your RooAddPdf construction: in principle the fraction parameter of a RooAddPdf is always interpreted as the fraction of the associated component p.d.f in the domain of the observable. However, if you construct a likelihood in a subrange of you observables, your domain changes and this would implicitly also change the shape your p.d.f as that same fraction is now made to a apply to a subset of your p.d.f (you can visualize this yourself easily: make a flat + gaussian p.df in rooft and plot it, then change the range of the observable and plot it again). As this behavious is undesirable in most use cases, the default behavior of a RooAddPdf is that in case a likelihood is calculated on a subrange the definition of the fraction is explicitly fixed to the original domain of the variables which is now encoded in the named range NormalizationRange. That will keep the shape of a RooAddPdf identical regardless of the range chosen to calculate the likelihood on.

In your second likelihood construction you do something that does not make sense, you request it to be restricted to a range “t>0.5”. Each range string is strictly interpreted as a named range associated with the observables, so in this case it will look for a range named “t>0.5”, which does not exist, so it reverts to its default behavious by making it on the fly as a copy of the default range. This is exactly what you observe.

Any normalization problems you may have may be unrelated to the ‘nll on subrange’ issue. If you send me some more idetails I might provide some more insight. PS: Which ROOT version are you using?

Wouter

Hi Wouter,
thanks for your explanations
back to this issue… with some delay…

What doesnt’ convince me that I am doing the right thing is that when I use the commands

t->setRange(“largeTimes”,0.5,12);
If I define:
RooNLLVar nll_TOT = new RooNLLVar(name.c_str(),“log(L)”,pdf_TOT,*data,Extended(true),Range(“largeTimes”));

I get the ERROR message
RooNLLVar::RooNLLVar ERROR: unrecognized command: RangeWithName

and the FIT history is the same of the one WIHOUT the Range

Now, since a new discussion on a similar item was posted recently I tried with the lines:
pdf_TOT-> fitTo(*data,Extended(true),…,Range(“largeTimes”));

In this case I get a more reassuring message:

[#1] INFO:Caching – RooAddPdf::syncCoefProjList(pdf_TOT) creating coefficient projection integrals
from current normalization: (m,t)
with current range:
to reference normalization: (m,t)
with reference range: NormalizationRangeForlargeTimes
and indeed the Fit history seems much different from the oune WITHOUT the Range.

So, given that your first reply is still valid… now the question is:
what is wrong in the syntax below?

RooNLLVar nll_TOT = new RooNLLVar(name.c_str(),“log(L)”,pdf_TOT,*data,Extended(true),Range(“largeTimes”));

By the way, I am using root 5.18.00

Thanks,
Cheers,
Stefania

Hi Stefania,

Your syntax is OK. There was however a problem in the RooNLLVar ctor in 5.18.
It is fixed in >=5.20

Wouter