Folding (RooFFTConvPdf)

Hi All,

this is my framework:
-> ROOT version 5.22 (including RooFit 2.91) - on 32bit machine

I am using the RooFFTConvPdf class in RooFit to convolve one variable
with a gaussian resolution in a multi-variable function of the form:

f(t,angle_1,angle_2) = exp(-par_0t)(1-cos^2angle_1)*cos^2(angle_2)

I implement this as class (RooDecayRateFullModel) and solve the
integral analytically.

I implemented the function first without convolution and generated
toys and fitted them, successfully. In a second step I convolve the
variable t with a gaussian g(0.,0.1) using RooFFTConvPdf as below:

// theoretical model
RooDecayRateFullModel decay(“RooDecayRateFullModel”," full decay rate model",

// resolution model
m = new RooRealVar(“m”,"",0.);
s = new RooRealVar(“s”,"",0.1);

RooGaussian resolution(“resolution”,“resolution”,*dectime,*m,*s);

// numerical convolution RooFFTConvPdf

RooFFTConvPdf modelC(“modelC”," theory (x) resolution",*dectime,decay,resolution);

// toy generation
RooDataSet* sig = modelC.generate(RooArgSet(*dectime,*angle_1,*angle_2),1000);

The generation of toys crashes. I diagnosed the problem further,
but I should mention already, that with only two variables the
procedure works.

For diagnosis I copied the relevant RooFit classes (RooFFTConvPdf) and
recompiled them with some cout statements. I follow the sequence of
methods called:

For two variables RooFit runs through

1- genContext
2- ceateCache
3- actualObservables
4- inputBaseName
5- actualObservables
6- inputBaseName
7- actualParameters
8- FFTCacheElem
9- fillCacheObject -> otherObs.siz() = 1
10- fillCacheSlice
11- scanPdf
12- scanPdf
INFO: Caching – RooAbsCachePdf:getCache(modelC) creating new cache XYZ
with PDF RooDecayRateFullModel_CONV_resolution …

Now, with 3 variables it crashes after 4-

Error: Symbol G__exception is not defined in current scope.

To debug, I hooked the GDB debugger.
This is the cout output with the error analysis of the GDB:

Inside genContext
—> number of variables besides the dectime = 2

Inside createCache

Inside actualObservables

—> total number of variables = 3

Inside inputBaseName

—> _pdf1.arg().GetName() = RooDecayRateFullModel
—> _pdf2.arg().GetName() = resolution
—> full name = RooDecayRateFullModel_CONV_resolution
terminate called after throwing an instance of 'std::bad_alloc’
what(): std::bad_alloc

I also tried with

-> ROOT version 5.22.00_x64 (including RooFit 2.91) - on 64bit machine

but the machine freezes right after the statement

—> full name = RooDecayRateFullModel_CONV_resolution

instead of terminating with ‘std::bad_alloc’

Do you know how to solve this problem to be able to use more than
two variables in my model (I actually depend on 4 right now).



What you want to do should work, but apparently doesn’t.
Would you be able to send me a tarball with some code that I can use to debug it?


Hi Wouter,
thanks for your reply.
In the folder there are two classes:

  • (function with 2 variables)
  • (function with 3 variables)
    that I call to generate MC.
    The main interface where you can switch from one model to another is
    In this interface there are fitData and toyGeneration. The latter is the one
    of our interesting.
    To compile, from the folder type

and then
root fit.C

Thanks a lot in advance
Wouter_64.rar (18.2 KB)

Hi Giordano,

I’ve run your code through the debugger, and I see what the problem is.
If you define an input p.d.f with three observables, the resulting output
p.d.f is also three-dimensional, and is cached in a three-dimensional
histogram. Here is where you start to run into trouble: 10000 x 100 x 100 bins
= 100 million bins, so that’s a lot of memory! I’m running on a dual-quad core
with 16G of real memory, and I see that memory consumption goes up to about
7.8 Gb, which will cause a crash (with std__badalloc) on most machines.

Now concerning the solution: I need to think a bit. I could easily provide an option
to cache less non-convolved dimensions in RooFFTConvPdf (a similar mechanism
to make this optional already exists for RooLinearMorph, which inherits as well
from RooAbsCachedReal). That will for sure reduce the memory footprint. It
comes however at the expense of CPU time. If I only cache the convolved dimension,
the cache validity will become dependent on the value of the other two observables,
which will likely change every event. If the total number of events to be generated
is nevertheless small compared to the number of bins in the other dimensions,
it should however be more efficient anyway.

I will provide this flag shortly in RooFFTConvPdf (will send you a private copy to try out).
Meanwhile you might see what happens if you reduce the binning granularity with
3 dimensions (e.g. 100 x 100 x 100), that will likely make it work out of the box
(I see that it works on my machine, but I did not let the entire study run to its end)

I also really should put out a warning in RooDataHist whenever a histogram with
more than 10M bins is allocated…


1 Like


(There have been some further private exchanges on this subject)

This posting is just to close out this thread with the solution:

I’ve made some changes to RooFFTConvPdf that change the default caching strategy that have a less dramatic memory footprint in the
default configuration.

Several other improvements have been made to the class (new features and robustness improvements). Please wait for the release notes of the next ROOT 5.23 series release for more details.


1 Like