Fitting a Polynomial over 2 Ranges (Sideband Fitting)

Hi ROOTERS,

This should be simple and straightforward. I am performing a fit to the sidebands of a polynomial. The way I do this is by naming the two ranges, e.g,
x.setRange(“SL”, 2.5, 2.8);
x.setRange(“SU”, 3.1, 3.5);

where x is defined to be: RooRealVar x(“x”, “x”, 2.5, 3.5);

I perform the fit to a 2nd order polynomial and plot the result. I also compute the normalization integral over the full range (this should, and is, 1) and over the two ranges defines above.

There are two signs that suggest something is wrong:

  1. When a fit range is specified and the pdf is plotted the pdf will, by default, only be plotted in the fit range. In my plot the pdf is plotted over the full range.

  2. The normalization integral over the fit range is greater than 1!!

This is troubling me and leads me to think either: there is a bug, or I am doing something incorrect.

Any help is greatly welcomed!!

This is how I perform the fit:
x.setRange(“SL”, 2.5, 2.8); x.setRange(“SU”, 3.1, 3.5);
poly.fitTo(*data, Save(kTRUE), Range(“SL, SU”));

Here is the result of the normalization integrals:
Normalization Integral over range[2.5, 2.8] and [3.1, 3.5]: 1.16514
Normalization Integral over x[2.5, 3.5]: 1

Below is the code

#ifndef __CINT__
#include "RooGlobalFunc.h"
#endif

#include "RooRealVar.h"
#include "RooPolynomial.h"
#include "RooPlot.h"
#include "RooNLLVar.h"
#include "RooAbsData.h"
#include "RooAbsPdf.h"
#include "RooAbsArg.h"
#include "RooAbsReal.h"
#include "RooDataSet.h"
#include "RooFitResult.h"
#include "RooAddPdf.h"
#include "RooArgList.h"
#include "RooMinuit.h"

using namespace RooFit;

RooDataSet* PolyData(){
  
  RooRealVar x("x", "x", 2.5, 3.5);
  
  RooRealVar c0("c0","c0", -2e+04, -1e5, -1e4);
  RooRealVar c1("c1","c1", 1e+04, 1e2, 1e5);
  RooPolynomial poly("poly","poly",x,RooArgList(c0,c1));
  RooDataSet* data = poly.generate(x, 2e+04);
  return data;
}

void PolyFit(){
  
  RooRealVar x("x", "x", 2.5, 3.5);
  
  RooRealVar c0("c0","c0", -1e5, -1e4);
  RooRealVar c1("c1","c1", 1e2, 1e5);
  RooPolynomial poly("poly","poly",x,RooArgList(c0,c1));
  
  RooDataSet* data = PolyData();
  
  x.setRange("SL", 2.5, 2.8);
  x.setRange("SU", 3.1, 3.5);
  
  RooFitResult* result = poly.fitTo(*data, Save(kTRUE), Range("SL, SU"));
  result->Print("v");
  
  RooAbsReal* isum1 = poly.createIntegral(x, NormSet(x), Range("SL, SU"));
  RooAbsReal* isum2 = poly.createIntegral(x, NormSet(x));
  cout << "Normalization Integral over range[2.5, 2.8] and [3.1, 3.5]: " << isum1->getVal() << endl;
  cout << "Normalization Integral over x[2.5, 3.5]: " << isum2->getVal() << endl;
  
  RooPlot* frame = x.frame();
  data->plotOn(frame);
  poly.plotOn(frame);
  frame->Draw();
}

By the way I am using ROOT 5.34.10, which is the latest version, I think

Hi guys, I found the cause of the problem that is quite interesting

When the range is defined in the fit with:
fitTo(*data, Range(“SL, SU”))
with a space after the comma then you get these strange behaviors but if you don’t leave a space like:
fitTo(*data, Range(“SL,SU”))
Then the normalization integral is now less than 1 and the fit line is only plotted in the specified range.

Maybe if someone runs into this problem in the future this will help