Multiple fit regions in RooFit

Guys…

 Well, I would like to fit a histogram using two regions (sideband regions).  I have looked on the web, the forums, and underneath my desk for information on how to do this using RooFit.  I have put together the following code based on the information that I was able to put together.  
#include <iostream>
#include <string>
#include <TFile.h>
#include <TH1D.h>
#include <RooGlobalFunc.h>
#include <RooPlot.h>
#include <RooDataHist.h>
#include <RooRealVar.h>
#include <TCanvas.h>
#include "roothreshold.h"
#include <RooFitResult.h>
#include <RooCategory.h>

using namespace std;
using namespace RooFit;

typedef struct {
  double delta;
  double exp;
  double exp_err;
  double pull;
  int fit_status;
} Result;

Result doFit(TH1*);

int main() {
  TFile input("output_histos.root");
  TH1D *input_hist = (TH1D*) input.FindObjectAny("data_0tag_rev1_nocuts_jj");

  // Ok, lets make a RooFit thingy here

  Result tmpres = doFit(input_hist);

  cout << "The exp is: " << tmpres.exp << endl;
}

Result doFit(TH1 *input_histo) {
  Result res;

  double signal_count = input_histo->Integral(input_histo->FindBin(50), input_histo->FindBin(100));

  RooRealVar x("x", "M(jj)", 0, 400, "GeV/c^{2}");

  RooRealVar norm("norm", "norm", 1.0, 0.0, 100.0);
  RooRealVar offset("offset", "offset", 10.849, 0, 30);
  RooRealVar power("power", "power", 2.4653, 0, 10);
  RooRealVar coeff1("coeff1", "coeff1", -0.0829876, -2, 2);
  RooRealVar coeff2("coeff2", "coeff2", 0.000133946, -1, 1);
  RooThreshold thresh("thresh", "MN_FIT Threshold Function", x, norm, offset, power, coeff1, coeff2);

  RooDataHist data("data", "Yhea", x, input_histo);

  RooCategory modes("modes","modes");
  modes.defineType("1", 1);
  modes.defineType("2", 2);

  // Set the regions
  x.setRange("low", 0, 50);
  x.setRange("signal", 50, 100);
  x.setRange("high", 100, 300);

  x.setRange("fit_1", 30, 50);
  x.setRange("fit_2", 100, 200);

  // Get the original integral
  RooAbsReal *preInt         = thresh.createIntegral(x);
  RooAbsReal *preIntSignal   = thresh.createIntegral(x, Range("signal"));
  RooAbsReal *preIntSideband = thresh.createIntegral(x, Range("low"), Range("high"));

  preInt->Print();

  cout << "The int is: " << preInt->getVal() << endl;
  cout << "The signal region is: " << preIntSignal->getVal() << endl;
  cout << "The sideband region is: " << preIntSideband->getVal() << endl;
  cout << "The sum of the two is: " << preIntSignal->getVal() + preIntSideband->getVal() << endl;

  // Do the fit
  RooFitResult *fitResult = thresh.fitTo(data, Range("fit"), SplitRange(kTRUE), Verbose(kTRUE), Save(kTRUE), PrintLevel(3));

  int status = fitResult->status();
  int covQual = fitResult->covQual();
  cout << "The fit status was: " << status << " with a covariance quality code of: " << covQual << endl;

  RooAbsReal *postInt         = thresh.createIntegral(x);
  RooAbsReal *postIntSignal   = thresh.createIntegral(x, Range("signal"));
  RooAbsReal *postIntSideband = thresh.createIntegral(x, Range("low"), Range("high"));

  cout << "The post fit signal integral is: " << postIntSignal->getVal() << endl;
  cout << "The number of signal events is : " << signal_count << endl;

  TCanvas *can = new TCanvas("mycanvas");

  RooPlot *frame = x.frame();
  data.plotOn(frame);
  thresh.plotOn(frame);
  frame->SetTitle("M(jj) Fit with a Threshold Function");
  frame->Draw();

  can->SaveAs("test.eps");
}

I have been looking in the output but I can not seem to find a way to verify that it is using just the fit_* regions. It looks like it is using the entire region. Thanks for any help here. I may have this right, if I do please let me know. I am using root version 5.18/00d.

Justace

Hi,

This is in principle relatively straightforward to do in ROOT >= 5.20.

In the upcoming ROOT 5.21 release (out in 2 days) I have provided a couple of
example on how to fit in subranges and on how to fit in multiple disjoint regions in roofit
they are

$ROOTSYS/tutorials/roofit/rf203_ranges.C
$ROOTSYS/tutorials/roofit/rf312_multirangefit.C

You can already find them in the SVN head of the repository. These macro will very likely also run with 5.20 but probably not with 5.18.

Wouter