User Tools

Site Tools


root:custompdfsandworkspace

Custom PDFs and Workspaces

Idea

In RooFit you can define a custom PDF shape in a C++ class. This is a good idea if the model is widely used and speed is an issue. A popular example is the class “RooExpAndGauss”, which is used for partly reconstructed background in B decays. However, you need to be careful when defining these if you also want to deal with RooWorkspaces.

Problem & Solution

You need to define a standard constructor in your Pdf-class, so it can be stored in (and retrieved from) a RooWorkspace. However, this standard constructor must initialize all the necessary variables, otherwise you will not be able to retrieve the pdf back from a RooWorkspace (it will end in an ugly segfault). For example for RooExpAndGauss:

#include <iostream> 
#include "RooExpAndGauss.h" 
#include "RooAbsReal.h" 
 
ClassImp(RooExpAndGauss) 
 
// ------------------------------------------------------------------
RooExpAndGauss::RooExpAndGauss(const char *name, const char *title, 
			       RooAbsReal& _x,
			       RooAbsReal& _sh_mean,
			       RooAbsReal& _sh_sigma,
			       RooAbsReal& _sh_trans) :
  RooAbsPdf(name,title), 
  x("x","x",this,_x),
  sh_mean("sh_mean","sh_mean",this,_sh_mean),
  sh_sigma("sh_sigma","sh_sigma",this,_sh_sigma),
  sh_trans("sh_trans","sh_trans",this,_sh_trans)
 
{ 
} 
 
// ------------------------------------------------------------------     
RooExpAndGauss::RooExpAndGauss(const RooExpAndGauss& other, const char* name) :  
     RooAbsPdf(other,name), 
     x("x",this,other.x),
     sh_mean("sh_mean",this,other.sh_mean),
     sh_sigma("sh_sigma",this,other.sh_sigma),
     sh_trans("sh_trans",this,other.sh_trans)
     { 
     } 
 
 
 
// ------------------------------------------------------------------
Double_t RooExpAndGauss::evaluate() const 
{ 
   // ENTER EXPRESSION IN TERMS OF VARIABLE ARGUMENTS HERE 
 double beta = (sh_mean - sh_trans)/(sh_sigma*sh_sigma);
 double c = exp(-0.5*pow((sh_trans-sh_mean)/sh_sigma,2))*exp(-beta*sh_trans);
 if (x <= sh_trans){ 
	 return c*exp(beta*x);
 };
 
 return exp(-0.5*pow((x-sh_mean)/sh_sigma,2)); //think a 1/2 was missed before BsMuMuPy v4.4
 
 } 

you need to define something like:

 RooExpAndGauss::RooExpAndGauss()
 {
   RooRealVar xRV("xRV","x", 0.0, 1.0);
   RooRealVar sh_meanRV("sh_meanRV", "sh_mean", 0.0, 1.0);
   RooRealVar sh_sigmaRV("sh_sigmaRV","sh_sigma", 0.0, 1.0);
   RooRealVar sh_transRV("sh_transRV","sh_trans", 0.0, 1.0);
 
   RooExpAndGauss("RooExpAndGauss", "RooExpAndGauss", xRV, sh_meanRV, sh_sigmaRV, sh_transRV);
}

to initialize the member variables (which are use in the evaluate-method).

You then can compile the class as all other private classes and add the library to you rootlogon to have it at hand.

Note: Make sure you have set the number in “ClassDef(myClass, number)” to something larger than 0. Otherwise the class won't allow I/O.

Note: Don't even think of using the constructor “x(“x”,”x“this,other.x)” in the copy constructor of your class. It will compile but will ever let you wonder why it segfaults afterwards (http://root.cern.ch/phpBB3/viewtopic.php?f=15&t=12788)

root/custompdfsandworkspace.txt · Last modified: 2012/04/25 20:07 by decianm