73 ClassImp(RooStats::BernsteinCorrection); ;
75 using namespace RooFit;
76 using namespace RooStats;
81 BernsteinCorrection::BernsteinCorrection(Double_t tolerance):
82 fMaxDegree(10), fMaxCorrection(100), fTolerance(tolerance){
89 Int_t BernsteinCorrection::ImportCorrectedPdf(RooWorkspace* wks,
90 const char* nominalName,
92 const char* dataName){
94 RooRealVar* x = wks->var(varName);
95 RooAbsPdf* nominal = wks->pdf(nominalName);
96 RooAbsData* data = wks->data(dataName);
98 if (!x || !nominal || !data) {
99 cout <<
"Error: wrong name for pdf or variable or dataset - return -1 " << std::endl;
103 std::cout <<
"BernsteinCorrection::ImportCorrectedPdf - Doing initial Fit with nominal model " << std::endl;
106 TString minimType = ROOT::Math::MinimizerOptions::DefaultMinimizerType();
107 int printLevel = ROOT::Math::MinimizerOptions::DefaultPrintLevel()-1;
109 RooFitResult* nominalResult = nominal->fitTo(*data,Save(),Minos(kFALSE), Hesse(kFALSE),PrintLevel(printLevel),Minimizer(minimType));
110 Double_t lastNll= nominalResult->minNll();
112 if (nominalResult->status() != 0 ) {
113 std::cout <<
"BernsteinCorrection::ImportCorrectedPdf - Error fit with nominal model failed - exit" << std::endl;
118 std::stringstream log;
119 log <<
"------ Begin Bernstein Correction Log --------" << endl;
123 vector<RooRealVar*> coefficients;
128 bool keepGoing =
true;
133 std::stringstream str;
136 RooRealVar* newCoef =
new RooRealVar((
"c"+str.str()).c_str(),
137 "Bernstein basis poly coefficient",
138 1.0, 0., fMaxCorrection);
140 coefficients.push_back(newCoef);
144 newCoef->setConstant(1);
149 RooBernstein* poly =
new RooBernstein(
"poly",
"Bernstein poly", *x, coeff);
152 RooEffProd* corrected =
new RooEffProd(
"corrected",
"",*nominal,*poly);
155 RooFitResult* result = corrected->fitTo(*data,Save(),Minos(kFALSE), Hesse(kFALSE),PrintLevel(printLevel),Minimizer(minimType));
157 if (result->status() != 0) {
158 std::cout <<
"BernsteinCorrection::ImportCorrectedPdf - Error fit with corrected model failed" << std::endl;
165 q = 2*(lastNll - result->minNll());
167 keepGoing = (degree < 1 || TMath::Prob(q,1) < fTolerance );
168 if (degree >= fMaxDegree) keepGoing =
false;
173 wks->import(*corrected);
183 log <<
"degree = " << degree
184 <<
" -log L("<<degree-1<<
") = " << lastNll
185 <<
" -log L(" << degree <<
") = " << result->minNll()
187 <<
" P(chi^2_1 > q) = " << TMath::Prob(q,1) << endl;;
191 lastNll = result->minNll();
196 log <<
"------ End Bernstein Correction Log --------" << endl;
206 void BernsteinCorrection::CreateQSamplingDist(RooWorkspace* wks,
207 const char* nominalName,
209 const char* dataName,
211 TH1F* samplingDistExtra,
215 RooRealVar* x = wks->var(varName);
216 RooAbsPdf* nominal = wks->pdf(nominalName);
217 RooAbsData* data = wks->data(dataName);
219 if (!x || !nominal || !data) {
220 cout <<
"Error: wrong name for pdf or variable or dataset ! " << std::endl;
225 std::stringstream log;
226 log <<
"------ Begin Bernstein Correction Log --------" << endl;
230 RooArgList coeffNull;
231 RooArgList coeffExtra;
232 vector<RooRealVar*> coefficients;
235 for(
int i = 0; i<=degree+1; ++i) {
237 std::stringstream str;
240 RooRealVar* newCoef =
new RooRealVar((
"c"+str.str()).c_str(),
241 "Bernstein basis poly coefficient",
242 1., 0., fMaxCorrection);
245 if(i<degree) coeffNull.add(*newCoef);
246 if(i<=degree) coeff.add(*newCoef);
247 coeffExtra.add(*newCoef);
248 coefficients.push_back(newCoef);
253 =
new RooBernstein(
"poly",
"Bernstein poly", *x, coeff);
256 RooBernstein* polyNull
257 =
new RooBernstein(
"polyNull",
"Bernstein poly", *x, coeffNull);
260 RooBernstein* polyExtra
261 =
new RooBernstein(
"polyExtra",
"Bernstein poly", *x, coeffExtra);
264 RooEffProd* corrected
265 =
new RooEffProd(
"corrected",
"",*nominal,*poly);
267 RooEffProd* correctedNull
268 =
new RooEffProd(
"correctedNull",
"",*nominal,*polyNull);
270 RooEffProd* correctedExtra
271 =
new RooEffProd(
"correctedExtra",
"",*nominal,*polyExtra);
274 cout <<
"made pdfs, make toy generator" << endl;
277 RooDataHist dataHist(
"dataHist",
"",*x,*data);
278 RooHistPdf toyGen(
"toyGen",
"",*x,dataHist);
280 TString minimType = ROOT::Math::MinimizerOptions::DefaultMinimizerType();
281 int printLevel = ROOT::Math::MinimizerOptions::DefaultPrintLevel()-1;
283 RooFit::MsgLevel msglevel = RooMsgService::instance().globalKillBelow();
284 if (printLevel < 0) {
285 RooMsgService::instance().setGlobalKillBelow(RooFit::FATAL);
290 Double_t q = 0, qExtra = 0;
292 for(
int i=0; i<nToys; ++i){
293 cout <<
"on toy " << i << endl;
295 RooDataSet* tmpData = toyGen.generate(*x,data->numEntries());
298 = corrected->fitTo(*tmpData,Save(),Minos(kFALSE),
299 Hesse(kFALSE),PrintLevel(printLevel),Minimizer(minimType));
301 RooFitResult* resultNull
302 = correctedNull->fitTo(*tmpData,Save(),Minos(kFALSE),
303 Hesse(kFALSE),PrintLevel(printLevel),Minimizer(minimType));
306 RooFitResult* resultExtra
307 = correctedExtra->fitTo(*tmpData,Save(),Minos(kFALSE),
308 Hesse(kFALSE),PrintLevel(printLevel),Minimizer(minimType));
313 q = 2*(resultNull->minNll() - result->minNll());
315 qExtra = 2*(result->minNll() - resultExtra->minNll());
317 samplingDist->Fill(q);
318 samplingDistExtra->Fill(qExtra);
320 cout <<
"NLL Results: null " << resultNull->minNll() <<
" ref = " << result->minNll() <<
" extra" << resultExtra->minNll() << endl;
329 RooMsgService::instance().setGlobalKillBelow(msglevel);