00001 ////////////////////////////////////////////////////////////////////////// 00002 // 00003 // 'LIKELIHOOD AND MINIMIZATION' RooFit tutorial macro #606 00004 // 00005 // Understanding and customizing error handling in likelihood evaluations 00006 // 00007 // 00008 // 00009 // 07/2008 - Wouter Verkerke 00010 // 00011 ///////////////////////////////////////////////////////////////////////// 00012 00013 #ifndef __CINT__ 00014 #include "RooGlobalFunc.h" 00015 #endif 00016 #include "RooRealVar.h" 00017 #include "RooDataSet.h" 00018 #include "RooArgusBG.h" 00019 #include "RooNLLVar.h" 00020 #include "TCanvas.h" 00021 #include "TAxis.h" 00022 #include "RooPlot.h" 00023 using namespace RooFit ; 00024 00025 00026 void rf606_nllerrorhandling() 00027 { 00028 // C r e a t e m o d e l a n d d a t a s e t 00029 // ---------------------------------------------- 00030 00031 // Observable 00032 RooRealVar m("m","m",5.20,5.30) ; 00033 00034 // Parameters 00035 RooRealVar m0("m0","m0",5.291,5.20,5.30) ; 00036 RooRealVar k("k","k",-30,-50,-10) ; 00037 00038 // Pdf 00039 RooArgusBG argus("argus","argus",m,m0,k) ; 00040 00041 // Sample 1000 events in m from argus 00042 RooDataSet* data = argus.generate(m,1000) ; 00043 00044 00045 00046 // P l o t m o d e l a n d d a t a 00047 // -------------------------------------- 00048 00049 RooPlot* frame1 = m.frame(Bins(40),Title("Argus model and data")) ; 00050 data->plotOn(frame1) ; 00051 argus.plotOn(frame1) ; 00052 00053 00054 00055 // F i t m o d e l t o d a t a 00056 // --------------------------------- 00057 00058 // The ARGUS background shape has a sharp kinematic cutoff at m=m0 00059 // and is prone to evaluation errors if the cutoff parameter m0 00060 // is floated: when the pdf cutoff value is lower than that in data 00061 // events with m>m0 will have zero probability 00062 00063 // Perform unbinned ML fit. Print detailed error messages for up to 00064 // 10 events per likelihood evaluation. The default error handling strategy 00065 // is to return a very high value of the likelihood to MINUIT if errors occur, 00066 // which will force MINUIT to retreat from the problematic area 00067 00068 argus.fitTo(*data,PrintEvalErrors(10)) ; 00069 00070 // Peform another fit. In this configuration only the number of errors per 00071 // likelihood evaluation is shown, if it is greater than zero. The 00072 // EvalErrorWall(kFALSE) arguments disables the default error handling strategy 00073 // and will cause the actual (problematic) value of the likelihood to be passed 00074 // to MINUIT. 00075 // 00076 // NB: Use of this option is NOT recommended as default strategt as broken -log(L) values 00077 // can often be lower than 'good' ones because offending events are removed. 00078 // This may effectively create a false minimum in problem areas. This is clearly 00079 // illustrated in the second plot 00080 00081 m0.setError(0.1) ; 00082 argus.fitTo(*data,PrintEvalErrors(0),EvalErrorWall(kFALSE)) ; 00083 00084 00085 00086 // P l o t l i k e l i h o o d a s f u n c t i o n o f m 0 00087 // ------------------------------------------------------------------ 00088 00089 // Construct likelihood function of model and data 00090 RooNLLVar nll("nll","nll",argus,*data) ; 00091 00092 // Plot likelihood in m0 in range that includes problematic values 00093 // In this configuration the number of errors per likelihood point 00094 // evaluated for the curve is shown. A positive number in PrintEvalErrors(N) 00095 // will show details for up to N events. By default the values for likelihood 00096 // evaluations with errors are shown normally (unlike fitting), but the shape 00097 // of the curve can be erratic in these regions. 00098 00099 RooPlot* frame2 = m0.frame(Range(5.288,5.293),Title("-log(L) scan vs m0")) ; 00100 nll.plotOn(frame2,PrintEvalErrors(0),ShiftToZero(),LineColor(kRed),Precision(1e-4)) ; 00101 frame2->SetMaximum(15) ; 00102 frame2->SetMinimum(0) ; 00103 00104 00105 // Plot likelihood in m0 in range that includes problematic values 00106 // In this configuration no messages are printed for likelihood evaluation errors, 00107 // but if an likelihood value evaluates with error, the corresponding value 00108 // on the curve will be set to the value given in EvalErrorValue(). 00109 00110 RooPlot* frame3 = m0.frame(Range(5.288,5.293),Title("-log(L) scan vs m0, problematic regions masked")) ; 00111 nll.plotOn(frame3,PrintEvalErrors(-1),ShiftToZero(),EvalErrorValue(nll.getVal()+10),LineColor(kRed)) ; 00112 frame3->SetMaximum(15) ; 00113 frame3->SetMinimum(0) ; 00114 00115 00116 TCanvas* c = new TCanvas("rf606_nllerrorhandling","rf606_nllerrorhandling",1200,400) ; 00117 c->Divide(3) ; 00118 c->cd(1) ; gPad->SetLeftMargin(0.15) ; frame1->GetYaxis()->SetTitleOffset(1.4) ; frame1->Draw() ; 00119 c->cd(2) ; gPad->SetLeftMargin(0.15) ; frame2->GetYaxis()->SetTitleOffset(1.4) ; frame2->Draw() ; 00120 c->cd(3) ; gPad->SetLeftMargin(0.15) ; frame3->GetYaxis()->SetTitleOffset(1.4) ; frame3->Draw() ; 00121 00122 }