# Normalization on a side band fit

Hello,
I’m trying to fit the side band region of a 2D data set. The region of the data distribution is at x[-10,10] and y[-10,10]. The side band is defined to be -10<x<10 and -10<y<0 using

``````  x.setRange("SB1",-10,+10) ;
y.setRange("SB1",-10,0) ;
``````

The result of the fit is correct. But when I tried to plot out the data with the pdf model with`NormRange("SB1")`, the normalization of the model seems to be totally wrong. How should I plot the result of a side band fit with the correct normalization?
See the attachment:

``````

using namespace RooFit ;

void sideBandEx()
{

// C r e a t e   2 D   p d f   a n d   d a t a
// -------------------------------------------

// Define observables x,y
RooRealVar x("x","x",-10,10) ;
RooRealVar y("y","y",-10,10) ;

// Construct the signal pdf gauss(x)*gauss(y)
RooRealVar mx("mx","mx",1,-10,10) ;
RooRealVar my("my","my",1,-10,10) ;

RooGaussian gx("gx","gx",x,mx,RooConst(1)) ;
RooGaussian gy("gy","gy",y,my,RooConst(1)) ;

RooProdPdf sig("sig","sig",gx,gy) ;

// Construct the background pdf (flat in x,y)
RooPolynomial px("px","px",x) ;
RooPolynomial py("py","py",y) ;
RooProdPdf bkg("bkg","bkg",px,py) ;

// Construct the composite model sig+bkg
RooRealVar f("f","f",0.,1.) ;

// Sample 10000 events in (x,y) from the model
RooDataSet* modelData = model.generate(RooArgSet(x,y),10000) ;

x.setRange("SB1",-10,+10) ;
y.setRange("SB1",-10,0) ;

RooFitResult* r_sb12 = model.fitTo(*modelData,Range("SB1"),Save()) ;

// Plot the results
RooPlot* frame01 = x.frame(Title("x"));
modelData->plotOn(frame01,CutRange("SB1"));
model.plotOn(frame01,LineColor(1),LineWidth(2),ProjectionRange("SB1"),NormRange("SB1"));

RooPlot* frame02 = y.frame(Title("y"));
modelData->plotOn(frame02,CutRange("SB1"));
model.plotOn(frame02,LineColor(1),LineWidth(2),ProjectionRange("SB1"),NormRange("SB1"));

TCanvas *c1 = new TCanvas("c1","",1);
frame01->Draw();
TCanvas *c2 = new TCanvas("c2","",1);
frame02->Draw();

r_sb12->Print() ;

}

``````

The plots:

The output messages:

``````[#1] INFO:Minization -- RooMinimizer::optimizeConst: deactivating const optimization
[#1] INFO:Plotting -- RooTreeData::plotOn: plotting 3335 events out of 10000 total events
[#1] INFO:Plotting -- RooAbsPdf::plotOn(model) p.d.f was fitted in range and no explicit plot range was specified, using fit range as default
[#1] INFO:Plotting -- RooAbsPdf::plotOn(model) only plotting range 'fit_nll_model_modelData,fit_nll_model_modelData'
[#1] INFO:Plotting -- RooAbsPdf::plotOn(model) p.d.f. curve is normalized using explicit choice of ranges 'SB1'
[#0] WARNING:Plotting -- RooHist::getFitRangeNEvt() WARNING: Number of normalization events associated to histogram is not equal to number of events in histogram
due cut made in RooAbsData::plotOn() call. Automatic normalization over sub-range of plot variable assumes
that the effect of that cut is uniform across the plot, which may be an incorrect assumption. To be sure of
correct normalization explicit pass normalization information to RooAbsPdf::plotOn() call using Normalization()
[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on x integrates over variables (y) in range SB1
[#0] ERROR:InputArguments -- RooArgSet::checkForDup: ERROR argument with name model_Int[x,y|fit_nll_model_modelData]_Norm[x,y] is already in this set
[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on x integrates over variables (y) in range SB1
[#0] ERROR:InputArguments -- RooArgSet::checkForDup: ERROR argument with name model_Int[x,y|fit_nll_model_modelData]_Norm[x,y] is already in this set
[#1] INFO:Plotting -- RooTreeData::plotOn: plotting 3335 events out of 10000 total events
[#1] INFO:Plotting -- RooAbsPdf::plotOn(model) p.d.f was fitted in range and no explicit plot range was specified, using fit range as default
[#1] INFO:Plotting -- RooAbsPdf::plotOn(model) only plotting range 'fit_nll_model_modelData,fit_nll_model_modelData'
[#1] INFO:Plotting -- RooAbsPdf::plotOn(model) p.d.f. curve is normalized using explicit choice of ranges 'SB1'
[#0] WARNING:Plotting -- RooHist::getFitRangeNEvt() WARNING: Number of normalization events associated to histogram is not equal to number of events in histogram
due cut made in RooAbsData::plotOn() call. Automatic normalization over sub-range of plot variable assumes
that the effect of that cut is uniform across the plot, which may be an incorrect assumption. To be sure of
correct normalization explicit pass normalization information to RooAbsPdf::plotOn() call using Normalization()
[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on y integrates over variables (x) in range SB1
[#0] ERROR:InputArguments -- RooArgSet::checkForDup: ERROR argument with name model_Int[x,y|fit_nll_model_modelData]_Norm[x,y] is already in this set
[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on y integrates over variables (x) in range SB1
[#0] ERROR:InputArguments -- RooArgSet::checkForDup: ERROR argument with name model_Int[x,y|fit_nll_model_modelData]_Norm[x,y] is already in this set
``````

Hi @andychin912,

did you try to simply use `Range(...)`? It should set the plotting and the norm range to the range given in `(...)`. Maybe this is not what you want because you want to see the function in the other regions, as well.

In this case, the warning message that you posted is probably interesting:

As you can see, RooFit warns that plotting only a part of the data can lead to surprising results, because the histogram knows that it originated from `N` events, but it only contains `M < N` events. This could be the reason for the odd normalisation.

The message also tells you how to fix this.

Thank you @StephanH,

``````Normalization(M,  RooAbsReal::NumEvent)
``````

solves the problem when there is only one side band.
I’m trying to define two segments of side band with

``````  x.setRange("SB1",-10,+10) ;
y.setRange("SB1",-10,0) ;
x.setRange("SB2",-10,+10) ;
y.setRange("SB2",4,10) ;
``````

and fit them with:

`````` RooFitResult* r_sb12 = model.fitTo(*modelData,Range("SB1,SB2"),Save()) ;
``````

Then the normalization on the x dimension becomes incorrect.
Do you know what might cause this to happen?

How did you normalise this one? Explicitly or did you try to use automatic normalisation?

I guess that here you basically have to do the same trick, but instead of
`M = NumEvent(SB1)`,
you have to use
`M+N = NumEvent(SB1) + NumEvent(SB2)`

Yes, I used

``````model.plotOn(frame,LineColor(1),LineWidth(2),ProjectionRange("SB1,SB2"),Normalization(4841,RooAbsReal::NumEvent));//In this case N+M = NumEvent(SB1) + NumEvent(SB2) = 4841
``````

And for the x dimension the normalization failed.

I wonder if it would work without `ProjectionRange`. Can you try?

Nope, I removed the `ProjectionRange("SB1,SB2")`. It doesn’t work.

EDIT:
I just saw that we already were at this step. In dealing with other questions, I forgot that we already tried this. I will give it another try tomorrow.

Hi @andychin912,

I ran your script again and found this:

``````[#0] WARNING:Plotting -- RooHist::getFitRangeNEvt() WARNING: Number of normalization events associated to histogram is not equal to number of events in histogram
due cut made in RooAbsData::plotOn() call. Automatic normalization over sub-range of plot variable assumes
that the effect of that cut is uniform across the plot, which may be an incorrect assumption. To be sure of
correct normalization explicit pass normalization information to RooAbsPdf::plotOn() call using Normalization()
``````

As the warning says, the automatic computation of normalisation cannot work out the number of data events. Like this I got it to work:

``````  // Plot the results
RooPlot* frame01 = x.frame(Title("x"));
modelData->plotOn(frame01,CutRange("SB1"));
const double nData = modelData->sumEntries("", "SB1");

// Make clear that the target normalisation is nData. The enumerator NumEvent
// is needed to switch between relative and absolute scaling.
model.plotOn(frame01,LineColor(1),LineWidth(2), Normalization(nData, RooAbsReal::NumEvent),
ProjectionRange("SB1"));

RooPlot* frame02 = y.frame(Title("y"));
modelData->plotOn(frame02);

// Here, all data are plotted. It is therefore not necessary to adapt the normalisation
model.plotOn(frame02,LineColor(1),LineWidth(2),Range("SB1"), NormRange("SB1"));
``````

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.