User Defined PDF

Hi
I have a file containing a very complicated numerical function. I want to define this in RooFit (actually one of the dimensions of the TF2 ends up being a parameter) as a RooAbsPdf. What I have is shown below. This actually works… you first have to compile the RooLS pdf (my user defined pdf), then load it using CINT into the code (similar to root.cern.ch/root/html/tutorials … ory.C.html). But, because it opens and closes the file each time, it is extremely slow. (though it does work). Any suggestions on speeding this up? If I could somehow pass a TF2 to the RooLS class, that would probably solve the problem. Evidently others have had similar issues (RooClassFactory passing additional objects to constructor)

An alternative which I explored was using bindPdf from a user defined TF1. However, the issue I have is that bindPdf from a TF1 does not seem to produce a Pdf with free parameters, as others have discovered (RooFit: fitting a TF1-binded function?).

Thanks
Ben Carlson

Double_t RooLS::evaluate() const { TFile *lineshape_file = new TFile("/Users/carlsonbt1/results/data_files/smearing_newbins_feb11.root","READ"); TF2 *LS1_shape = (TF2*)lineshape_file->FindObjectAny(LS_namew(1,0,0).c_str()); // ENTER EXPRESSION IN TERMS OF VARIABLE ARGUMENTS HERE Double_t LS= LS1_shape->Eval(x-deltaM, cw); delete LS1_shape; delete lineshape_file; return LS; }

Hi
I have found a work around to this problem I think.

If you want to make a TF1 (or TF2 or any root/C++ function) into a PDF, the following steps work:

1.) Define a C++ function:

double signal_shape(double *x, double *par){ return value;
}
2.) Define a TF1 from this function

TF1 SH = new TF1("SH",signal_shape,x1,x2,nPar); // Define TF1 SH->SetParameters(a,b,c...); // set parameters - my function has 2
3.) Bind the TF1 to a RooFit RooAbsReal, create a constant term, then use RooRealSumPdf (root.cern.ch/root/html/RooRealSumPdf.html) to create a PDF out of the function and the constant:
RooRealVar a0("a0","a0",0); a0.setConstant(kTRUE); //RooChebychev will make a first order polynomial, set to a constant RooChebychev bkg("bkg","bkg",m, RooArgList(a0)); //this is now a constant RooAbsReal *LSfcn = bindFunction(SH,m, RooArgList(deltaM,cw));//deltaM and cw are parameters RooAbsPdf *LSPdf = new RooRealSumPdf("LSPdf","LSPdf",*LSfcn,bkg,c1); //combine the constant term (bkg) and the term RooAbsReal (which is a function) into a PDF.

I’m not sure if this does anything odd in terms of normalization, but it seems to work. Now when you do a fit using LSPdf the parameters are correctly optimized by the fitter.

If there is a more direct way to do this, or if you see a problem I am overlooking with this method, please let me know!

It would probably be better if there were a way to directly take a root TF1 to a RooFit Pdf object with parameters. Perhaps this could be fixed in the next RooFit release.

Thanks
Ben

2 Likes