Home | News | Documentation | Download

Issue with defining a custom PDF from an array of TF1 function

Hello everyone. I’m modelling a multiple slit interference experiment with a variable number of slits. From x I want to compute a distance r for each of the slits and then I want to compute the wave equation by summing the different contribution.
I have a TF1 function: f(x, par) which takes one parameter (the slit position), I want to create N PDF g(y_1)=g(f(x, par1))…g(y_N)=g(f(x, parN)) and then I want to sum these PDF in one final PDF. I tried:
Writing a c++ function:

double DistanceFunction(double *x, double *pos); //x and pos are pointers with one component

Creating the f(x,par) as a TF1 function

TF1 *DF = new TF1(“DF”,DistanceFunction, 0, (L_Def * L_Def), 1);

Creating another function as

TF1 SingleWave = new TF1(“SingleWave”, "1/rcos(2* M_PI* r / lambda)",-1,1);

Then I created an array in which to store g(f(x,par1))…g(y, parN)

RooGenericPdf **SingleWaveArr[NFenditure];

which I tried initialising:

for(int j=1; j<=N/2; j=j+1){

 pos.setVal(j);
 oss << "Name: " << j;
 str = oss.str();
 *SingleWaveArr[2*j-2] = new RooGenericPdf (str.c_str(),SingleWave,RooArgSet(*DF,x,pos)) ;
 oss << "Fenditura " << -j;
 str = oss.str();
 *SingleWaveArr[2*j-1] = new RooGenericPdf (str.c_str(),SingleWave,RooArgSet(*DF,x,pos)) ;
 }

And then I tried summing my array into one PDF:

RooAddPdf model(“TotalPDF”,“Signal”, RooArgList(*SingleWaveArr), RooArgList(*ParArr));

When I try to compile this code I get the following errors:

error: no matching constructor for initialization of ‘RooArgSet’
SingleWaveArr[2j-2] = new RooGenericPdf (str.c_str(),SingleWave,RooArgSet(*DF,x,pos)) ;

error: no matching constructor for initialization of ‘RooArgSet’
SingleWaveArr[2j-1] = new RooGenericPdf (str.c_str(),SingleWave,RooArgSet(*DF,x,pos)) ;

error: no matching conversion for functional-style cast from ‘RooGenericPdf **’ to ‘RooArgList’
RooAddPdf model(“TotalPDF”,“Signal”, RooArgList(*SingleWaveArr), RooArgList(*ParArr));

How do I make this work?


ROOT Version: 6.22/06
Platform: Ubuntu 20.10
Compiler: (Ubuntu 10.2.0-13ubuntu1) 10.2.0


Hi @zero1 ,
probably @moneta or @jonas can help.

Cheers,
Enrico

Hi @zero1, interesting experiment!

About your compilation errors.

The first two errors read:
error: no matching constructor for initialization of ‘RooArgSet’.

This is because of the *DF in the RooArgSet. The problem is that a TF1 can’t be used as a RooFit argument. You have to create a RooFormulaVar for that. Or maybe just another fixed RooRealVar that you assign the computed distance value, if that’s sufficient.

The second problem reads:
error: no matching conversion for functional-style cast from ‘RooGenericPdf **’ to ‘RooArgList’.

Here, you try to pass an array of RooGenericPdfs to the RooAddPdf constructor, but it expects a RooArgList. You can create the RooArgList youself and fill it from the array:

RooArgList pdfList{"pdfList"};            
                                              
for(int i = 0; i < NFenditure; ++i) {      
    pdfList.add(*(SingleWaveArr[i]));       
}

RooAddPdf model(“TotalPDF”,“Signal”, pdfList, RooArgList(*ParArr));

In general, I would advice you to not use these multidimensional pointer arrays. It’s easy to make mistakes. For example, I think you meant RooGenericPdf *SingleWaveArr[NFenditure] with one star, right? It should be an array of pointers, not an array of pointers to pointers. It’s better to use std::vector. Then you can also construct the RooArgList with this convenient constructor.

I hope these comments already help you, although I’m not sure if your code will do what you expect it to do in the end. If you have any further questions or comment, please feel free to ask again and don’t forget to attach your full source file so we can reproduce your problem and help you better :slight_smile: