ROOT logo
//////////////////////////////////////////////////////////////////////////
//
// 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #609
// 
// Setting up a chi^2 fit to an unbinned dataset with X,Y,err(Y)
// values (and optionally err(X) values)
//
//
//
// 07/2008 - Wouter Verkerke 
// 
/////////////////////////////////////////////////////////////////////////

#ifndef __CINT__
#include "RooGlobalFunc.h"
#endif
#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooPolyVar.h"
#include "RooConstVar.h"
#include "RooChi2Var.h"
#include "RooMinuit.h"
#include "TCanvas.h"
#include "TAxis.h"
#include "RooPlot.h"
#include "TRandom.h"

using namespace RooFit ;


void rf609_xychi2fit()
{
  // C r e a t e   d a t a s e t   w i t h   X   a n d   Y   v a l u e s
  // -------------------------------------------------------------------

  // Make weighted XY dataset with asymmetric errors stored
  // The StoreError() argument is essential as it makes
  // the dataset store the error in addition to the values
  // of the observables. If errors on one or more observables
  // are asymmetric, one can store the asymmetric error
  // using the StoreAsymError() argument

  RooRealVar x("x","x",-11,11) ;
  RooRealVar y("y","y",-10,200) ;
  RooDataSet dxy("dxy","dxy",RooArgSet(x,y),StoreError(RooArgSet(x,y))) ;

  // Fill an example dataset with X,err(X),Y,err(Y) values
  for (int i=0 ; i<=10 ; i++) {

    // Set X value and error
    x = -10 + 2*i;
    x.setError( i<5 ? 0.5/1. : 1.0/1. ) ;
    
    // Set Y value and error 
    y = x.getVal() * x.getVal() + 4*fabs(gRandom->Gaus()) ;
    y.setError(sqrt(y.getVal())) ;

    dxy.add(RooArgSet(x,y)) ;    
  }



  // P e r f o r m   c h i 2   f i t   t o   X + / - d x   a n d   Y + / - d Y   v a l u e s
  // ---------------------------------------------------------------------------------------

  // Make fit function
  RooRealVar a("a","a",0.0,-10,10) ;
  RooRealVar b("b","b",0.0,-100,100) ;
  RooPolyVar f("f","f",x,RooArgList(b,a,RooConst(1))) ;

  // Plot dataset in X-Y interpretation
  RooPlot* frame = x.frame(Title("Chi^2 fit of function set of (X#pmdX,Y#pmdY) values")) ;
  dxy.plotOnXY(frame,YVar(y)) ;

  // Fit chi^2 using X and Y errors 
  f.chi2FitTo(dxy,YVar(y)) ;

  // Overlay fitted function
  f.plotOn(frame) ;
  
  // Alternative: fit chi^2 integrating f(x) over ranges defined by X errors, rather
  // than taking point at center of bin
  f.chi2FitTo(dxy,YVar(y),Integrate(kTRUE)) ;

  // Overlay alternate fit result
  f.plotOn(frame,LineStyle(kDashed),LineColor(kRed)) ;  


  // Draw the plot on a canvas
  new TCanvas("rf609_xychi2fit","rf609_xychi2fit",600,600) ;
  gPad->SetLeftMargin(0.15) ; frame->GetYaxis()->SetTitleOffset(1.4) ; frame->Draw() ;
  

}
 rf609_xychi2fit.C:1
 rf609_xychi2fit.C:2
 rf609_xychi2fit.C:3
 rf609_xychi2fit.C:4
 rf609_xychi2fit.C:5
 rf609_xychi2fit.C:6
 rf609_xychi2fit.C:7
 rf609_xychi2fit.C:8
 rf609_xychi2fit.C:9
 rf609_xychi2fit.C:10
 rf609_xychi2fit.C:11
 rf609_xychi2fit.C:12
 rf609_xychi2fit.C:13
 rf609_xychi2fit.C:14
 rf609_xychi2fit.C:15
 rf609_xychi2fit.C:16
 rf609_xychi2fit.C:17
 rf609_xychi2fit.C:18
 rf609_xychi2fit.C:19
 rf609_xychi2fit.C:20
 rf609_xychi2fit.C:21
 rf609_xychi2fit.C:22
 rf609_xychi2fit.C:23
 rf609_xychi2fit.C:24
 rf609_xychi2fit.C:25
 rf609_xychi2fit.C:26
 rf609_xychi2fit.C:27
 rf609_xychi2fit.C:28
 rf609_xychi2fit.C:29
 rf609_xychi2fit.C:30
 rf609_xychi2fit.C:31
 rf609_xychi2fit.C:32
 rf609_xychi2fit.C:33
 rf609_xychi2fit.C:34
 rf609_xychi2fit.C:35
 rf609_xychi2fit.C:36
 rf609_xychi2fit.C:37
 rf609_xychi2fit.C:38
 rf609_xychi2fit.C:39
 rf609_xychi2fit.C:40
 rf609_xychi2fit.C:41
 rf609_xychi2fit.C:42
 rf609_xychi2fit.C:43
 rf609_xychi2fit.C:44
 rf609_xychi2fit.C:45
 rf609_xychi2fit.C:46
 rf609_xychi2fit.C:47
 rf609_xychi2fit.C:48
 rf609_xychi2fit.C:49
 rf609_xychi2fit.C:50
 rf609_xychi2fit.C:51
 rf609_xychi2fit.C:52
 rf609_xychi2fit.C:53
 rf609_xychi2fit.C:54
 rf609_xychi2fit.C:55
 rf609_xychi2fit.C:56
 rf609_xychi2fit.C:57
 rf609_xychi2fit.C:58
 rf609_xychi2fit.C:59
 rf609_xychi2fit.C:60
 rf609_xychi2fit.C:61
 rf609_xychi2fit.C:62
 rf609_xychi2fit.C:63
 rf609_xychi2fit.C:64
 rf609_xychi2fit.C:65
 rf609_xychi2fit.C:66
 rf609_xychi2fit.C:67
 rf609_xychi2fit.C:68
 rf609_xychi2fit.C:69
 rf609_xychi2fit.C:70
 rf609_xychi2fit.C:71
 rf609_xychi2fit.C:72
 rf609_xychi2fit.C:73
 rf609_xychi2fit.C:74
 rf609_xychi2fit.C:75
 rf609_xychi2fit.C:76
 rf609_xychi2fit.C:77
 rf609_xychi2fit.C:78
 rf609_xychi2fit.C:79
 rf609_xychi2fit.C:80
 rf609_xychi2fit.C:81
 rf609_xychi2fit.C:82
 rf609_xychi2fit.C:83
 rf609_xychi2fit.C:84
 rf609_xychi2fit.C:85
 rf609_xychi2fit.C:86
 rf609_xychi2fit.C:87
 rf609_xychi2fit.C:88
 rf609_xychi2fit.C:89
 rf609_xychi2fit.C:90
 rf609_xychi2fit.C:91
 rf609_xychi2fit.C:92
 rf609_xychi2fit.C:93
 rf609_xychi2fit.C:94
 rf609_xychi2fit.C:95