Strange behavior with convolutions and SplitRange()


I have constructed a mass + pseudoproper lifetime pdf that uses per event errors and a number of convoluted decay PDFs. To model the background under the signal peak in a data-driven way, I split the mass fit into a signal region and two sidebands to extract the lifetime shape of the background. To get the proper normalizations in each range I am under the impression that I need to define ranges as ‘fitRange_indexCat’ in the sideband and signal regions that I want to fit in and then when fitting the simultaneous PDF specify the Range and then pass the option SplitRange to fitTo().

My problem seems to be coming from specifying the ranges in the fit. In order to speed up the convolution of the RooDecay pdfs with the resolution model I use a flat scale factor integral. However, when I request the data to be simultaneously fit in these separate ranges the flat analytical integral is no longer used and RooFit attempts to numerically integrate over the per-event error when fitting the decay + prompt pdf. This gets very slow, as you can imagine.

I dug into this a little bit and it seems that when the ranges are created there is one case where a numerical integral is requested, but it really makes no sense as nowhere have I constructed a PDF that requires one…

If I do not specify any ranges, the (analytical) flat scale factor integral is performed, as one would expect.

I have attached an example script that reproduces the problem I am experiencing exactly, but in the case of a single fit instead of a simultaneous fit. Here, I’ve modified a tutorial script to generate a toy mass/lifetime pdf and data with per-event errors, then I fit to a range in the mass (the results are “interesting”). If the fit is run without using a range, the results are perfect and no numerical integral is performed over the per-event error.

Thanks in advance,

(Edit to reproduce problem in fitting as well. It is now quite slow, however.)
brokenIntegrals.C (5.09 KB)

Furthermore, I can run this script with the range “test” set to the full range of the mass observable and the results are still quite strange.

Thanks again,