Suppose I have a histogram which consist of Gaussian backround and Poisson signal. I want to construct composite model Signal+Background
p.d.f. and then fit it to a given data. The problem is my Poisson signal is shifted along x-axis. So I want to add shift
variable to RooPoisson
as a parameter. I know that there are many ways to do this. I think that it is a common problem with p.d.f.'s that have no shift in their nature (unlike those whicch already has it e.g. gaus, Cauchy and etc. ) although this seems to be simple. So I want to know what is the simplest way to add x
-shift as a parameter to an existing p.d.f. in RooFit
?
What do I mean by shifted argument is just Pois( (x - shift), lambda )
.
To complete the picture I provide my code below.
void ENoise( )
{
//Get data hist
TFile* f = TFile::Open( "ENoise/tree_noise.root" );
TTree* tree = (TTree*)f->Get( "tree_noise" );
Double_t xMin = -150.;
Double_t xMax = 300;
TH1* hist = new TH1F( "hist", "Histogram from noise tree", 100, xMin, xMax );
tree->Project( "hist", "integral", "mode == \"E1LSB\"" );
//Create a variable of interest
RooRealVar x( "x", "x", xMin, xMax );
//Build data from hist
RooDataHist data( "data", "Noise integral (1LSB)", x, hist );
//Construct gaussian bkg
RooRealVar mean( "mean", "Pedestal Mean", 0, -100, 100 );
RooRealVar sigma( "sigma", "Pedestal Sigma", 30, 0, 100 );
RooGaussian bkg( "bkg", "Backgroud", x, mean, sigma );
//Construct Poisson signal. Here's the problem!!!
RooRealVar lambda( "lambda", "Signal Mean", 1, 0, 10 );
RooPoisson sig( "sig", "Signal", x, lambda );
//signal fraction
RooRealVar fSig( "fsig", "Signal fraction", 0.5, 0, 1 );
//build composite model
RooAddPdf model( "model", "model", RooArgList( sig, bkg), fSig );
//Fit model to data in specific range
model.fitTo( data, Range( xMin, 200 ) );
//Draw the model and components
TCanvas* c = new TCanvas();
RooPlot* xFrame = x.frame();
data.plotOn( xFrame );
model.plotOn( xFrame );
model.plotOn( xFrame, Components("bkg"), LineStyle( kDashed ) );
model.plotOn( xFrame, Components("sig"), LineStyle( kDashed ) );
xFrame->Draw();
c->SetLogy();
}
WHAT HAVE I TRIED
I tried to use reparametrization trick in order to shift variable x
:
RooRealVar shift( "shift", "shift", 100. );
RooFormulaVar xShift( "xShift", "x - shift", RooArgList( x, shift) );
RooRealVar lambda( "lambda", "Signal Mean", 10, 0, 100 );
RooPoisson pois( "pois", "Poisson", xShift, lambda );
But during the minimization it is just freezing terminal. Doesn’t work.
Also I tried RooClassFactory::makePdf
in order to create my own p.d.f.
In the ROOT session
root [0] RooClassFactory::makePdf("ShiftedPoisson", "x,lambda,x0");
NOTE: there are no spaces between parameter names.
Then it is necessary to implement evaluate
method in ShiftedPoisson.cxx
file. In my case it is as follows:
Double_t ShiftedPoisson::evaluate() const
{
// ENTER EXPRESSION IN TERMS OF VARIABLE ARGUMENTS HERE
return TMath::Poisson( (x - x0), lambda );
}
Then I just include ShiftedPoisson.cxx
in my program and do
//x definded above
RooRealVar lambda( "lambda", "Signal Mean", 90, 1, 800 );
RooRealVar x0( "x0", "Shift in signal", 25, -600, 40 );
ShiftedPoisson sig( "sig", "Signal", x, lambda, x0 );
And it works pretty well.
Thank you in advance