RooFit: problems fitting Gaussian + Chebychev in a subrange


I am trying to fit a dataset using a sum of a RooGaussian and a RooChebychev.
The fit on the full dataset works fine, but when I try to do the fit in only two subranges, the fit failed returning the error:

root.exe: /opt/root_v5.34.18/roofit/roofit/src/RooChebychev.cxx:142: virtual Double_t RooChebychev::analyticalIntegral(Int_t, const char*) const: Assertion `xminfull <= _x.max(rangeName) && _x.max(rangeName) <= xmaxfull’ failed.

In attachment you can find the macro that perform the fit using the Chebychev only and the Chebychev + Gaussian.

I have also tried to do the same using a RooExponential, instead of RooChebychev and the fit works, both in the full range and in the two subranges, so it seems to be something related to the RooChebychev function.

I found this example … fit.C.html

that shows how to fit of a Gaussian + Chebychev in a subrange, but in this case the two pdfs are defined in the sub range itself:
x.setRange(“signalRange”,4,6) ;
RooExtendPdf esig(“esig”,“extended signal p.d.f”,sig,nsig,“signalRange”) ;
RooExtendPdf ebkg(“ebkg”,“extended background p.d.f”,bkg,nbkg,“signalRange”) ;

My “real” case is different since I have a blinded dataset (so I have data only in the sidebands) and thus I want to perform the fit using only the sidebands, but I want my pdf being defined in the full range to be able to extrapolate the number of background events in the blinded signal region.

Am I doing something wrong?

Thanks a lot!


RooFit_test.C (3.49 KB)


I have tried to do some tests, adding some prints in the RooChebychev.cxx and recompiling the ROOT (I am using the latest version of ROOT, v5_34_20).
What crashes ROOT is the assert() in lines 141-142 that checks that the subranges are within the range of the variable used in the declaration of the RooChebychev (in my case “mass”)

RooRealVar mass(“mass”,“mass”,4700,5900,“MeV/c^{2}”);
RooRealVar slope (“slope” ,“slope” ,-0.1,-10.0,0.0,“MeV/c^{2}”)
RooChebychev cheb (“cheb” ,“cheb” ,mass ,slope);

so mass is defined in the range [4700,5900]. I added some cout that print the values of


When I try to fit only the chebychev, everything is fine and I get prints like

_x.min(rangeName) = 5500
_x.max(rangeName) = 5900
xminfull = 5500
xmaxfull = 5900


_x.min(rangeName) = 4700
_x.max(rangeName) = 5100
xminfull = 4700
xmaxfull = 5900

Now, looking at RooChebychev.h, if I understood correctly, “_x” should correspond to the variable “mass” (in my case) and so xminfull = _x.min() should always be equal to 4700.

When I try to fit the chebychev+gaussian in the two subranges [4700,5100] and [5500,5900], the fit immediately crashes and I got this

[#1] INFO:Minization – p.d.f. provides expected number of events, including extended term in likelihood.
[#1] INFO:Fitting – RooAbsOptTestStatistic::ctor(nll_model_modelData_SB1) constructing test statistic for sub-range named SB1
[#1] INFO:Eval – RooRealVar::setRange(mass) new range named ‘NormalizationRangeForSB1’ created with bounds [4700,5900]
[#1] INFO:Eval – RooRealVar::setRange(mass) new range named ‘fit_nll_model_modelData_SB1’ created with bounds [4700,5100]
[#1] INFO:Fitting – RooAbsOptTestStatistic::ctor(nll_model_modelData_SB1) fixing interpretation of coefficients of any RooAddPdf to full domain of observables
_x.min(rangeName) = 4700
_x.max(rangeName) = 5100
xminfull = 4700
xmaxfull = 5100
_x.min(rangeName) = 4700
_x.max(rangeName) = 5900
xminfull = 4700
xmaxfull = 5100
Assertion failed: (xminfull <= _x.max(rangeName) && _x.max(rangeName) <= xmaxfull), function analyticalIntegral, file /Users/Cri/Library/root_v5-34-20/roofit/roofit/src/RooChebychev.cxx, line 151.

Hope this can help fixing the problem.

Thanks a lot for your help!



Running ROOT in debug mode, this is the print that I get:

Program received signal SIGABRT, Aborted.
0x0000003587c32635 in raise () from /lib64/
Missing separate debuginfos, use: debuginfo-install expat-2.0.1-11.el6_2.x86_64 fontconfig-2.8.0-3.el6.x86_64 freetype-2.3.11-14.el6_3.1.x86_64 glibc-2.12-1.132.el6_5.4.x86_64 gsl-1.13-1.el6.x86_64 keyutils-libs-1.4-4.el6.x86_64 krb5-libs-1.10.3-10.el6_4.6.x86_64 libX11-1.5.0-4.el6.x86_64 libXau-1.0.6-4.el6.x86_64 libXcursor-1.1.13-6.20130524git8f677eaea.el6.x86_64 libXext-1.3.1-2.el6.x86_64 libXfixes-5.0-3.el6.x86_64 libXft-2.3.1-2.el6.x86_64 libXpm-3.5.10-2.el6.x86_64 libXrender-0.9.7-2.el6.x86_64 libcom_err-1.41.12-18.el6.x86_64 libgcc-4.4.7-4.el6.x86_64 libjpeg-turbo-1.2.1-3.el6_5.x86_64 libpng-1.2.49-1.el6_2.x86_64 libselinux-2.0.94-5.3.el6_4.1.x86_64 libstdc+±4.4.7-4.el6.x86_64 libxcb-1.8.1-1.el6.x86_64 openssl-1.0.1e-16.el6_5.15.x86_64 pcre-7.8-6.el6.x86_64 zlib-1.2.3-29.el6.x86_64
(gdb) bt
#0 0x0000003587c32635 in raise () from /lib64/
#1 0x0000003587c33e15 in abort () from /lib64/
#2 0x0000003587c2b75e in __assert_fail_base () from /lib64/
#3 0x0000003587c2b820 in __assert_fail () from /lib64/
#4 0x00007ffff20892ba in RooChebychev::analyticalIntegral(int, char const*) const () from /opt/root_v5.34.18/lib/
#5 0x00007ffff30cf3ba in RooAbsPdf::analyticalIntegralWN(int, RooArgSet const*, char const*) const () from /opt/root_v5.34.18/lib/
#6 0x00007ffff31f1b34 in RooRealIntegral::evaluate() const () from /opt/root_v5.34.18/lib/
#7 0x00007ffff30e7772 in RooAbsReal::traceEval(RooArgSet const*) const () from /opt/root_v5.34.18/lib/
#8 0x00007ffff31ef862 in RooRealIntegral::getValV(RooArgSet const*) const () from /opt/root_v5.34.18/lib/
#9 0x00007ffff3107550 in RooAddPdf::updateCoefficients(RooAddPdf::CacheElem&, RooArgSet const*) const () from /opt/root_v5.34.18/lib/
#10 0x00007ffff310ae7c in RooAddPdf::evaluate() const () from /opt/root_v5.34.18/lib/
#11 0x00007ffff30d3fee in RooAbsPdf::getValV(RooArgSet const*) const () from /opt/root_v5.34.18/lib/
#12 0x00007ffff30c7120 in RooAbsOptTestStatistic::initSlave(RooAbsReal&, RooAbsData&, RooArgSet const&, char const*, char const*) () from /opt/root_v5.34.18/lib/
#13 0x00007ffff30c7c01 in RooAbsOptTestStatistic::RooAbsOptTestStatistic(char const*, char const*, RooAbsReal&, RooAbsData&, RooArgSet const&, char const*, char const*, int, RooFit::MPSplit, bool, bool, bool) () from /opt/root_v5.34.18/lib/
#14 0x00007ffff31c1413 in RooNLLVar::RooNLLVar(char const*, char const*, RooAbsPdf&, RooAbsData&, RooArgSet const&, bool, char const*, char const*, int, RooFit::MPSplit, bool, bool, bool, bool) () from /opt/root_v5.34.18/lib/
#15 0x00007ffff30d3177 in RooAbsPdf::createNLL(RooAbsData&, RooLinkedList const&) () from /opt/root_v5.34.18/lib/
#16 0x00007ffff30cfd21 in RooAbsPdf::fitTo(RooAbsData&, RooLinkedList const&) () from /opt/root_v5.34.18/lib/
#17 0x00007ffff30cb661 in RooAbsPdf::fitTo(RooAbsData&, RooCmdArg const&, RooCmdArg const&, RooCmdArg const&, RooCmdArg const&, RooCmdArg const&, RooCmdArg const&, RooCmdArg const&, RooCmdArg const&) () from /opt/root_v5.34.18/lib/
#18 0x00007ffff091638d in RooFit_test() () from /.data/alpigiani/CODE/BackgroundBDTdependence/./
#19 0x00007ffff0917119 in G__RooFit_test_C_ACLiC_dict__0_4071(G__value*, char const*, G__param*, int) () from /.data/alpigiani/CODE/BackgroundBDTdependence/./
#20 0x00007ffff6aa9b79 in Cint::G__ExceptionWrapper(int ()(G__value, char const*, G__param*, int), G__value*, char*, G__param*, int) () from /opt/root_v5.34.18/lib/
#21 0x00007ffff6b4df01 in G__execute_call () from /opt/root_v5.34.18/lib/
#22 0x00007ffff6b4ed42 in G__call_cppfunc () from /opt/root_v5.34.18/lib/
#23 0x00007ffff6b2af18 in G__interpret_func () from /opt/root_v5.34.18/lib/
#24 0x00007ffff6b18ccb in G__getfunction () from /opt/root_v5.34.18/lib/
#25 0x00007ffff6af676e in G__getitem () from /opt/root_v5.34.18/lib/
#26 0x00007ffff6afb2e8 in G__getexpr () from /opt/root_v5.34.18/lib/
#27 0x00007ffff6b047f8 in G__calc_internal () from /opt/root_v5.34.18/lib/
#28 0x00007ffff6b89e33 in G__process_cmd () from /opt/root_v5.34.18/lib/
#29 0x00007ffff7851516 in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /opt/root_v5.34.18/lib/
#30 0x00007ffff784ec13 in TCint::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) () from /opt/root_v5.34.18/lib/
#31 0x00007ffff77baca8 in TApplication::ExecuteFile(char const*, int*, bool) () from /opt/root_v5.34.18/lib/
#32 0x00007ffff77b8fb3 in TApplication::ProcessLine(char const*, bool, int*) () from /opt/root_v5.34.18/lib/
#33 0x00007ffff740cd7b in TRint::HandleTermInput() () from /opt/root_v5.34.18/lib/
#34 0x00007ffff788bb3e in TUnixSystem::CheckDescriptors() () from /opt/root_v5.34.18/lib/
#35 0x00007ffff788bce3 in TUnixSystem::DispatchOneEvent(bool) () from /opt/root_v5.34.18/lib/
#36 0x00007ffff78113e6 in TSystem::InnerLoop() () from /opt/root_v5.34.18/lib/
#37 0x00007ffff7812dcb in TSystem::Run() () from /opt/root_v5.34.18/lib/
#38 0x00007ffff77b6d5f in TApplication::Run(bool) () from /opt/root_v5.34.18/lib/
#39 0x00007ffff740e304 in TRint::Run(bool) () from /opt/root_v5.34.18/lib/
#40 0x000000000040103c in main ()

I have also posted the issue on JIRA, here the link

I have added some other tests that I performed in the meanwhile, and a new macro that creates a blinded dataset (just to be more consistent with our real case).

Thanks a lot!



Sorry for the delay in dea;ing with this problem. It should be now fixed in both 5.34 and master revisions


[quote=“moneta”]Sorry for the delay in dea;ing with this problem. It should be now fixed in both 5.34 and master revisions


Dear Lorenzo,

I downloaded and installed newest ROOT patch (5.34.22), and the problem is still there. I’m also using RooChebychev and making fit in ranges. The issue here is that the fit does converge, but it gives a horrible result with a crazy chi^2/ndf.

When I make a fit in the full range, the chi^2/ndf is much better.

The example of my code is attached here.

testIntervalShape.C (1.94 KB)

Could you, please, help?