Logo ROOT   6.18/05
Reference Guide
AsymptoticCalculator.cxx
Go to the documentation of this file.
1// @(#)root/roostats:$Id$
2// Author: Kyle Cranmer, Sven Kreiss 23/05/10
3/*************************************************************************
4 * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11/** \class RooStats::AsymptoticCalculator
12 \ingroup Roostats
13
14Hypothesis Test Calculator based on the asymptotic formulae for the profile
15likelihood ratio.
16
17It performs hypothesis tests using the asymptotic formula for the profile likelihood, and
18uses the Asimov data set to compute expected significances or limits.
19
20See G. Cowan, K. Cranmer, E. Gross and O. Vitells: Asymptotic formulae for
21likelihood- based tests of new physics. Eur. Phys. J., C71:1–19, 2011.
22It provides methods to perform hypothesis tests using the likelihood function,
23and computes the \f$p\f$-values for the null and the alternate hypothesis using the asymptotic
24formulae for the profile likelihood ratio described in the given paper.
25
26The calculator provides methods to produce the Asimov dataset, *i.e.* a dataset
27generated where the observed values are equal to the expected ones.
28The Asimov data set is then used to compute the observed asymptotic \f$p\f$-value for
29the alternate hypothesis and the asymptotic expected \f$p\f$-values.
30
31The asymptotic formulae are valid only for one POI (parameter of interest). So
32the calculator works only for one-dimensional (one POI) models.
33If more than one POI exists, only the first one is used.
34
35The calculator can generate Asimov datasets from two kinds of PDFs:
36- "Counting" distributions: RooPoisson, RooGaussian, or products of RooPoissons.
37- Extended, *i.e.* number of events can be read off from extended likelihood term.
38*/
39
40
46
47#include "RooArgSet.h"
48#include "RooArgList.h"
49#include "RooProdPdf.h"
50#include "RooSimultaneous.h"
51#include "RooDataSet.h"
52#include "RooCategory.h"
53#include "RooRealVar.h"
54#include "RooMinimizer.h"
55#include "RooFitResult.h"
56#include "RooNLLVar.h"
58#include "RooPoisson.h"
59#include "RooUniform.h"
60#include "RooGamma.h"
61#include "RooGaussian.h"
62#include "RooBifurGauss.h"
63#include "RooLognormal.h"
64#include "RooDataHist.h"
65#include <cmath>
66#include <typeinfo>
67
70
71#include "TStopwatch.h"
72
73using namespace RooStats;
74using namespace std;
75
76
78
79int AsymptoticCalculator::fgPrintLevel = 1;
80
81////////////////////////////////////////////////////////////////////////////////
82/// set print level (static function)
83///
84/// - 0 minimal,
85/// - 1 normal,
86/// - 2 debug
87
88void AsymptoticCalculator::SetPrintLevel(int level) {
89 fgPrintLevel = level;
90}
91
92////////////////////////////////////////////////////////////////////////////////
93/// constructor for asymptotic calculator from Data set and ModelConfig
94
96 RooAbsData &data,
97 const ModelConfig &altModel,
98 const ModelConfig &nullModel, bool nominalAsimov) :
99 HypoTestCalculatorGeneric(data, altModel, nullModel, 0),
100 fOneSided(false), fOneSidedDiscovery(false), fNominalAsimov(nominalAsimov),
101 fUseQTilde(-1),
102 fNLLObs(0), fNLLAsimov(0),
103 fAsimovData(0)
104{
105 if (!Initialize()) return;
106
107 int verbose = fgPrintLevel;
108 // try to guess default configuration
109 // (this part should be only in constructor because the null snapshot might change during HypoTestInversion
110 const RooArgSet * nullSnapshot = GetNullModel()->GetSnapshot();
111 assert(nullSnapshot);
112 RooRealVar * muNull = dynamic_cast<RooRealVar*>( nullSnapshot->first() );
113 assert(muNull);
114 if (muNull->getVal() == muNull->getMin()) {
115 fOneSidedDiscovery = true;
116 if (verbose > 0)
117 oocoutI((TObject*)0,InputArguments) << "AsymptotiCalculator: Minimum of POI is " << muNull->getMin() << " corresponds to null snapshot - default configuration is one-sided discovery formulae " << std::endl;
118 }
119
120}
121
122////////////////////////////////////////////////////////////////////////////////
123/// Initialize the calculator
124/// The initialization will perform a global fit of the model to the data
125/// and build an Asimov data set.
126/// It will then also fit the model to the Asimov data set to find the likelihood value
127/// of the Asimov data set
128/// nominalAsimov is an option for using Asimov data set obtained using nominal nuisance parameter values
129/// By default the nuisance parameters are fitted to the data
130/// NOTE: If a fit has been done before, one for speeding up could set all the initial parameters
131/// to the fit value and in addition set the null snapshot to the best fit
132
134
135 int verbose = fgPrintLevel;
136 if (verbose >= 0)
137 oocoutP((TObject*)0,Eval) << "AsymptoticCalculator::Initialize...." << std::endl;
138
139
140 RooAbsPdf * nullPdf = GetNullModel()->GetPdf();
141 if (!nullPdf) {
142 oocoutE((TObject*)0,InputArguments) << "AsymptoticCalculator::Initialize - ModelConfig has not a pdf defined" << std::endl;
143 return false;
144 }
145 RooAbsData * obsData = const_cast<RooAbsData *>(GetData() );
146 if (!obsData ) {
147 oocoutE((TObject*)0,InputArguments) << "AsymptoticCalculator::Initialize - data set has not been defined" << std::endl;
148 return false;
149 }
150 RooAbsData & data = *obsData;
151
152
153
155 if (!poi || poi->getSize() == 0) {
156 oocoutE((TObject*)0,InputArguments) << "AsymptoticCalculator::Initialize - ModelConfig has not POI defined." << endl;
157 return false;
158 }
159 if (poi->getSize() > 1) {
160 oocoutW((TObject*)0,InputArguments) << "AsymptoticCalculator::Initialize - ModelConfig has more than one POI defined \n\t"
161 << "The asymptotic calculator works for only one POI - consider as POI only the first parameter"
162 << std::endl;
163 }
164
165
166 // This will set the poi value to the null snapshot value in the ModelConfig
167 const RooArgSet * nullSnapshot = GetNullModel()->GetSnapshot();
168 if(nullSnapshot == NULL || nullSnapshot->getSize() == 0) {
169 oocoutE((TObject*)0,InputArguments) << "AsymptoticCalculator::Initialize - Null model needs a snapshot. Set using modelconfig->SetSnapshot(poi)." << endl;
170 return false;
171 }
172
173 // GetNullModel()->Print();
174 // printf("ASymptotic calc: null snapshot\n");
175 // nullSnapshot->Print("v");
176 // printf("PDF variables " );
177 // nullPdf->getVariables()->Print("v");
178
179 // keep snapshot for the initial parameter values (need for nominal Asimov)
180 RooArgSet nominalParams;
181 RooArgSet * allParams = nullPdf->getParameters(data);
182 RemoveConstantParameters(allParams);
183 if (fNominalAsimov) {
184 allParams->snapshot(nominalParams);
185 }
189
190 // evaluate the unconditional nll for the full model on the observed data
191 if (verbose >= 0)
192 oocoutP((TObject*)0,Eval) << "AsymptoticCalculator::Initialize - Find best unconditional NLL on observed data" << endl;
193 fNLLObs = EvaluateNLL( *nullPdf, data, GetNullModel()->GetConditionalObservables(),GetNullModel()->GetGlobalObservables());
194 // fill also snapshot of best poi
195 poi->snapshot(fBestFitPoi);
196 RooRealVar * muBest = dynamic_cast<RooRealVar*>(fBestFitPoi.first());
197 assert(muBest);
198 if (verbose >= 0)
199 oocoutP((TObject*)0,Eval) << "Best fitted POI value = " << muBest->getVal() << " +/- " << muBest->getError() << std::endl;
200 // keep snapshot of all best fit parameters
201 allParams->snapshot(fBestFitParams);
202 delete allParams;
203
204 // compute Asimov data set for the background (alt poi ) value
205 const RooArgSet * altSnapshot = GetAlternateModel()->GetSnapshot();
206 if(altSnapshot == NULL || altSnapshot->getSize() == 0) {
207 oocoutE((TObject*)0,InputArguments) << "Alt (Background) model needs a snapshot. Set using modelconfig->SetSnapshot(poi)." << endl;
208 return false;
209 }
210
211 RooArgSet poiAlt(*altSnapshot); // this is the poi snapshot of B (i.e. for mu=0)
212
213 oocoutP((TObject*)0,Eval) << "AsymptoticCalculator: Building Asimov data Set" << endl;
214
215 // check that in case of binned models the n number of bins of the observables are consistent
216 // with the number of bins in the observed data
217 // This number will be used for making the Asimov data set so it will be more consistent with the
218 // observed data
219 int prevBins = 0;
220 RooRealVar * xobs = 0;
221 if (GetNullModel()->GetObservables() && GetNullModel()->GetObservables()->getSize() == 1 ) {
222 xobs = (RooRealVar*) (GetNullModel()->GetObservables())->first();
223 if (data.IsA() == RooDataHist::Class() ) {
224 if (data.numEntries() != xobs->getBins() ) {
225 prevBins = xobs->getBins();
226 oocoutW((TObject*)0,InputArguments) << "AsymptoticCalculator: number of bins in " << xobs->GetName() << " are different than data bins "
227 << " set the same data bins " << data.numEntries() << " in range "
228 << " [ " << xobs->getMin() << " , " << xobs->getMax() << " ]" << std::endl;
229 xobs->setBins(data.numEntries());
230 }
231 }
232 }
233
234 if (!fNominalAsimov) {
235 if (verbose >= 0)
236 oocoutI((TObject*)0,InputArguments) << "AsymptoticCalculator: Asimov data will be generated using fitted nuisance parameter values" << endl;
237 RooArgSet * tmp = (RooArgSet*) poiAlt.snapshot();
238 fAsimovData = MakeAsimovData( data, *GetNullModel(), poiAlt, fAsimovGlobObs,tmp);
239 }
240
241 else {
242 // assume use current value of nuisance as nominal ones
243 if (verbose >= 0)
244 oocoutI((TObject*)0,InputArguments) << "AsymptoticCalculator: Asimovdata set will be generated using nominal (current) nuisance parameter values" << endl;
245 nominalParams = poiAlt; // set poi to alt value but keep nuisance at the nominal one
247 }
248
249 if (!fAsimovData) {
250 oocoutE((TObject*)0,InputArguments) << "AsymptoticCalculator: Error : Asimov data set could not be generated " << endl;
251 return false;
252 }
253
254 // set global observables to their Asimov values
255 RooArgSet globObs;
256 RooArgSet globObsSnapshot;
257 if (GetNullModel()->GetGlobalObservables() ) {
258 globObs.add(*GetNullModel()->GetGlobalObservables());
259 assert(globObs.getSize() == fAsimovGlobObs.getSize() );
260 // store previous snapshot value
261 globObs.snapshot(globObsSnapshot);
262 globObs = fAsimovGlobObs;
263 }
264
265
266 // evaluate the likelihood. Since we use on Asimov data , conditional and unconditional values should be the same
267 // do conditional fit since is faster
268
269 RooRealVar * muAlt = (RooRealVar*) poiAlt.first();
270 assert(muAlt);
271 if (verbose>=0)
272 oocoutP((TObject*)0,Eval) << "AsymptoticCalculator::Initialize Find best conditional NLL on ASIMOV data set for given alt POI ( " <<
273 muAlt->GetName() << " ) = " << muAlt->getVal() << std::endl;
274
275 fNLLAsimov = EvaluateNLL( *nullPdf, *fAsimovData, GetNullModel()->GetConditionalObservables(), GetNullModel()->GetGlobalObservables(), &poiAlt );
276 // for unconditional fit
277 //fNLLAsimov = EvaluateNLL( *nullPdf, *fAsimovData);
278 //poi->Print("v");
279
280 // restore previous value
281 globObs = globObsSnapshot;
282
283 // restore number of bins
284 if (prevBins > 0 && xobs) xobs->setBins(prevBins);
285
286 fIsInitialized = true;
287 return true;
288}
289
290////////////////////////////////////////////////////////////////////////////////
291
292Double_t AsymptoticCalculator::EvaluateNLL(RooAbsPdf & pdf, RooAbsData& data, const RooArgSet * condObs, const RooArgSet * globObs, const RooArgSet *poiSet) {
293 int verbose = fgPrintLevel;
294
295
298
299
300 RooArgSet* allParams = pdf.getParameters(data);
302 // add constraint terms for all non-constant parameters
303
304 RooArgSet conditionalObs;
305 if (condObs) conditionalObs.add(*condObs);
306 RooArgSet globalObs;
307 if (globObs) globalObs.add(*globObs);
308
309 // need to call constrain for RooSimultaneous until stripDisconnected problem fixed
311
312 RooArgSet* attachedSet = nll->getVariables();
313
314 // if poi are specified - do a conditional fit
315 RooArgSet paramsSetConstant;
316 // support now only one POI
317 if (poiSet && poiSet->getSize() > 0) {
318 RooRealVar * muTest = (RooRealVar*) (poiSet->first());
319 RooRealVar * poiVar = dynamic_cast<RooRealVar*>( attachedSet->find( muTest->GetName() ) );
320 if (poiVar && !poiVar->isConstant() ) {
321 poiVar->setVal( muTest->getVal() );
322 poiVar->setConstant();
323 paramsSetConstant.add(*poiVar);
324 }
325 if (poiSet->getSize() > 1)
326 std::cout << "Model with more than one POI are not supported - ignore extra parameters, consider only first one" << std::endl;
327
328
329
330 // This for more than one POI (not yet supported)
331 //
332 // RooLinkedListIter it = poiSet->iterator();
333 // RooRealVar* tmpPar = NULL, *tmpParA=NULL;
334 // while((tmpPar = (RooRealVar*)it.Next())){
335 // tmpParA = ((RooRealVar*)attachedSet->find(tmpPar->GetName()));
336 // tmpParA->setVal( tmpPar->getVal() );
337 // if (!tmpParA->isConstant() ) {
338 // tmpParA->setConstant();
339 // paramsSetConstant.add(*tmpParA);
340 // }
341 // }
342
343 // check if there are non-const parameters so it is worth to do the minimization
344
345 }
346
347 TStopwatch tw;
348 tw.Start();
349 double val = -1;
350
351 //check if needed to skip the fit
352 RooArgSet nllParams(*attachedSet);
354 delete attachedSet;
355 bool skipFit = (nllParams.getSize() == 0);
356
357 if (skipFit)
358 val = nll->getVal(); // just evaluate nll in conditional fits with model without nuisance params
359 else {
360
361
362 int minimPrintLevel = verbose;
363
364 RooMinimizer minim(*nll);
366 minim.setStrategy( strategy);
367 // use tolerance - but never smaller than 1 (default in RooMinimizer)
369 tol = std::max(tol,1.0); // 1.0 is the minimum value used in RooMinimizer
370 minim.setEps( tol );
371 //LM: RooMinimizer.setPrintLevel has +1 offset - so subtract here -1
372 minim.setPrintLevel(minimPrintLevel-1);
373 int status = -1;
374 minim.optimizeConst(2);
377
378 if (verbose > 0 )
379 std::cout << "AsymptoticCalculator::EvaluateNLL ........ using " << minimizer << " / " << algorithm
380 << " with strategy " << strategy << " and tolerance " << tol << std::endl;
381
382
383 for (int tries = 1, maxtries = 4; tries <= maxtries; ++tries) {
384 // status = minim.minimize(fMinimizer, ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo().c_str());
385 status = minim.minimize(minimizer, algorithm);
386 // RooMinimizer::minimize returns -1 when the fit fails
387 if (status >= 0) {
388 break;
389 } else {
390 if (tries == 1) {
391 printf(" ----> Doing a re-scan first\n");
392 minim.minimize(minimizer,"Scan");
393 }
394 if (tries == 2) {
396 printf(" ----> trying with strategy = 1\n");
397 minim.setStrategy(1);
398 }
399 else
400 tries++; // skip this trial if strategy is already 1
401 }
402 if (tries == 3) {
403 printf(" ----> trying with improve\n");
404 minimizer = "Minuit";
405 algorithm = "migradimproved";
406 }
407 }
408 }
409
410 RooFitResult * result = 0;
411
412 // ignore errors in Hesse or in Improve and also when matrix was made pos def (status returned = 1)
413 if (status >= 0) {
414 result = minim.save();
415 }
416 if (result){
417 if (!RooStats::IsNLLOffset() )
418 val = result->minNll();
419 else {
420 bool previous = RooAbsReal::hideOffset();
422 val = nll->getVal();
423 if (!previous) RooAbsReal::setHideOffset(kFALSE) ;
424 }
425
426 }
427 else {
428 oocoutE((TObject*)0,Fitting) << "FIT FAILED !- return a NaN NLL " << std::endl;
429 val = TMath::QuietNaN();
430 }
431
432 minim.optimizeConst(false);
433 if (result) delete result;
434
435
436 }
437
438 double muTest = 0;
439 if (verbose > 0) {
440 std::cout << "AsymptoticCalculator::EvaluateNLL - value = " << val;
441 if (poiSet) {
442 muTest = ( (RooRealVar*) poiSet->first() )->getVal();
443 std::cout << " for poi fixed at = " << muTest;
444 }
445 if (!skipFit) {
446 std::cout << "\tfit time : ";
447 tw.Print();
448 }
449 else
450 std::cout << std::endl;
451 }
452
453 // reset the parameter free which where set as constant
454 if (poiSet && paramsSetConstant.getSize() > 0) SetAllConstant(paramsSetConstant,false);
455
456
458
459 delete allParams;
460 delete nll;
461
462 return val;
463}
464
465////////////////////////////////////////////////////////////////////////////////
466/// It performs an hypothesis tests using the likelihood function
467/// and computes the p values for the null and the alternate using the asymptotic
468/// formulae for the profile likelihood ratio.
469/// See G. Cowan, K. Cranmer, E. Gross and O. Vitells.
470/// Asymptotic formulae for likelihood- based tests of new physics. Eur. Phys. J., C71:1–19, 2011.
471/// The formulae are valid only for one POI. If more than one POI exists consider as POI only the
472/// first one
473
475 int verbose = fgPrintLevel;
476
477 // re-initialized the calculator in case it is needed (pdf or data modified)
478 if (!fIsInitialized) {
479 if (!Initialize() ) {
480 oocoutE((TObject*)0,InputArguments) << "AsymptoticCalculator::GetHypoTest - Error initializing Asymptotic calculator - return NULL result " << endl;
481 return 0;
482 }
483 }
484
485 if (!fAsimovData) {
486 oocoutE((TObject*)0,InputArguments) << "AsymptoticCalculator::GetHypoTest - Asimov data set has not been generated - return NULL result " << endl;
487 return 0;
488 }
489
490 assert(GetNullModel() );
491 assert(GetData() );
492
493 RooAbsPdf * nullPdf = GetNullModel()->GetPdf();
494 assert(nullPdf);
495
496 // make conditional fit on null snapshot of poi
497
498 const RooArgSet * nullSnapshot = GetNullModel()->GetSnapshot();
499 assert(nullSnapshot && nullSnapshot->getSize() > 0);
500
501 // use as POI the nullSnapshot
502 // if more than one POI exists, consider only the first one
503 RooArgSet poiTest(*nullSnapshot);
504
505 if (poiTest.getSize() > 1) {
506 oocoutW((TObject*)0,InputArguments) << "AsymptoticCalculator::GetHypoTest: snapshot has more than one POI - assume as POI first parameter " << std::endl;
507 }
508
509 RooArgSet * allParams = nullPdf->getParameters(*GetData() );
510 *allParams = fBestFitParams;
511 delete allParams;
512
513 // set the one-side condition
514 // (this works when we have only one params of interest
515 RooRealVar * muHat = dynamic_cast<RooRealVar*> ( fBestFitPoi.first() );
516 assert(muHat && "no best fit parameter defined");
517 RooRealVar * muTest = dynamic_cast<RooRealVar*> ( nullSnapshot->find(muHat->GetName() ) );
518 assert(muTest && "poi snapshot is not existing");
519
520
521
522 if (verbose> 0) {
523 std::cout << std::endl;
524 oocoutI((TObject*)0,Eval) << "AsymptoticCalculator::GetHypoTest: - perform an hypothesis test for POI ( " << muTest->GetName() << " ) = " << muTest->getVal() << std::endl;
525 oocoutP((TObject*)0,Eval) << "AsymptoticCalculator::GetHypoTest - Find best conditional NLL on OBSERVED data set ..... " << std::endl;
526 }
527
528 // evaluate the conditional NLL on the observed data for the snapshot value
529 double condNLL = EvaluateNLL( *nullPdf, const_cast<RooAbsData&>(*GetData()), GetNullModel()->GetConditionalObservables(), GetNullModel()->GetGlobalObservables(), &poiTest);
530
531 double qmu = 2.*(condNLL - fNLLObs);
532
533
534
535 if (verbose > 0)
536 oocoutP((TObject*)0,Eval) << "\t OBSERVED DATA : qmu = " << qmu << " condNLL = " << condNLL << " uncond " << fNLLObs << std::endl;
537
538
539 // this tolerance is used to avoid having negative qmu due to numerical errors
540 double tol = 2.E-3 * std::max(1.,ROOT::Math::MinimizerOptions::DefaultTolerance());
541 if (qmu < -tol || TMath::IsNaN(fNLLObs) ) {
542
543 if (qmu < 0)
544 oocoutW((TObject*)0,Minimization) << "AsymptoticCalculator: Found a negative value of the qmu - retry to do the unconditional fit "
545 << std::endl;
546 else
547 oocoutW((TObject*)0,Minimization) << "AsymptoticCalculator: unconditional fit failed before - retry to do it now "
548 << std::endl;
549
550
551 double nll = EvaluateNLL( *nullPdf, const_cast<RooAbsData&>(*GetData()),GetNullModel()->GetConditionalObservables(),GetNullModel()->GetGlobalObservables());
552
553 if (nll < fNLLObs || (TMath::IsNaN(fNLLObs) && !TMath::IsNaN(nll) ) ) {
554 oocoutW((TObject*)0,Minimization) << "AsymptoticCalculator: Found a better unconditional minimum "
555 << " old NLL = " << fNLLObs << " old muHat " << muHat->getVal() << std::endl;
556
557 // update values
558 fNLLObs = nll;
560 assert(poi);
562 poi->snapshot(fBestFitPoi);
563 // restore also muHad since previous pointer has been deleted
564 muHat = dynamic_cast<RooRealVar*> ( fBestFitPoi.first() );
565 assert(muHat);
566
567 oocoutW((TObject*)0,Minimization) << "AsymptoticCalculator: New minimum found for "
568 << " NLL = " << fNLLObs << " muHat " << muHat->getVal() << std::endl;
569
570
571 qmu = 2.*(condNLL - fNLLObs);
572
573 if (verbose > 0)
574 oocoutP((TObject*)0,Eval) << "After unconditional refit, new qmu value is " << qmu << std::endl;
575
576 }
577 }
578
579 if (qmu < -tol ) {
580 oocoutE((TObject*)0,Minimization) << "AsymptoticCalculator: qmu is still < 0 for mu = "
581 << muTest->getVal() << " return a dummy result "
582 << std::endl;
583 return new HypoTestResult();
584 }
585 if (TMath::IsNaN(qmu) ) {
586 oocoutE((TObject*)0,Minimization) << "AsymptoticCalculator: failure in fitting for qmu or qmuA "
587 << muTest->getVal() << " return a dummy result "
588 << std::endl;
589 return new HypoTestResult();
590 }
591
592
593
594
595
596 // compute conditional ML on Asimov data set
597 // (need to const cast because it uses fitTo which is a non const method
598 // RooArgSet asimovGlobObs;
599 // RooAbsData * asimovData = (const_cast<AsymptoticCalculator*>(this))->MakeAsimovData( poi, asimovGlobObs);
600 // set global observables to their Asimov values
601 RooArgSet globObs;
602 RooArgSet globObsSnapshot;
603 if (GetNullModel()->GetGlobalObservables() ) {
604 globObs.add(*GetNullModel()->GetGlobalObservables());
605 // store previous snapshot value
606 globObs.snapshot(globObsSnapshot);
607 globObs = fAsimovGlobObs;
608 }
609
610
611 if (verbose > 0) oocoutP((TObject*)0,Eval) << "AsymptoticCalculator::GetHypoTest -- Find best conditional NLL on ASIMOV data set .... " << std::endl;
612
613 double condNLL_A = EvaluateNLL( *nullPdf, *fAsimovData, GetNullModel()->GetConditionalObservables(), GetNullModel()->GetGlobalObservables(), &poiTest);
614
615
616 double qmu_A = 2.*(condNLL_A - fNLLAsimov );
617
618 if (verbose > 0)
619 oocoutP((TObject*)0,Eval) << "\t ASIMOV data qmu_A = " << qmu_A << " condNLL = " << condNLL_A << " uncond " << fNLLAsimov << std::endl;
620
621 if (qmu_A < -tol || TMath::IsNaN(fNLLAsimov) ) {
622
623 if (qmu_A < 0)
624 oocoutW((TObject*)0,Minimization) << "AsymptoticCalculator: Found a negative value of the qmu Asimov- retry to do the unconditional fit "
625 << std::endl;
626 else
627 oocoutW((TObject*)0,Minimization) << "AsymptoticCalculator: Fit failed for unconditional the qmu Asimov- retry unconditional fit "
628 << std::endl;
629
630
631 double nll = EvaluateNLL( *nullPdf, *fAsimovData, GetNullModel()->GetConditionalObservables(), GetNullModel()->GetGlobalObservables() );
632
633 if (nll < fNLLAsimov || (TMath::IsNaN(fNLLAsimov) && !TMath::IsNaN(nll) )) {
634 oocoutW((TObject*)0,Minimization) << "AsymptoticCalculator: Found a better unconditional minimum for Asimov data set"
635 << " old NLL = " << fNLLAsimov << std::endl;
636
637 // update values
638 fNLLAsimov = nll;
639
640 oocoutW((TObject*)0,Minimization) << "AsymptoticCalculator: New minimum found for "
641 << " NLL = " << fNLLAsimov << std::endl;
642 qmu_A = 2.*(condNLL_A - fNLLAsimov);
643
644 if (verbose > 0)
645 oocoutP((TObject*)0,Eval) << "After unconditional Asimov refit, new qmu_A value is " << qmu_A << std::endl;
646
647 }
648 }
649
650 if (qmu_A < - tol) {
651 oocoutE((TObject*)0,Minimization) << "AsymptoticCalculator: qmu_A is still < 0 for mu = "
652 << muTest->getVal() << " return a dummy result "
653 << std::endl;
654 return new HypoTestResult();
655 }
656 if (TMath::IsNaN(qmu) ) {
657 oocoutE((TObject*)0,Minimization) << "AsymptoticCalculator: failure in fitting for qmu or qmuA "
658 << muTest->getVal() << " return a dummy result "
659 << std::endl;
660 return new HypoTestResult();
661 }
662
663
664 // restore previous value of global observables
665 globObs = globObsSnapshot;
666
667 // now we compute p-values using the asymptotic formulae
668 // described in the paper
669 // Cowan et al, Eur.Phys.J. C (2011) 71:1554
670
671 // first try to guess automatically if needed to use qtilde (or ttilde in case of two sided)
672 // if explicitly fUseQTilde this was not set
673 // qtilde is in this case used if poi is bounded at the value of the alt hypothesis
674 // for Qtilde (need to distinguish case when qmu > qmuA = mu^2/ sigma^2)
675 // (see Cowan et al, Eur.Phys.J. C(2011) 71:1554 paper equations 64 and 65
676 // (remember qmu_A = mu^2/sigma^2 )
677 bool useQTilde = false;
678 // default case (check if poi is limited or not to a zero value)
679 if (!fOneSidedDiscovery) { // qtilde is not a discovery test
680 if (fUseQTilde == -1 && !fOneSidedDiscovery) {
681 // alternate snapshot is value for which background is zero (for limits)
682 RooRealVar * muAlt = dynamic_cast<RooRealVar*>( GetAlternateModel()->GetSnapshot()->first() );
683 // null snapshot is value for which background is zero (for discovery)
684 //RooRealVar * muNull = dynamic_cast<RooRealVar*>( GetNullModel()->GetSnapshot()->first() );
685 assert(muAlt != 0 );
686 if (muTest->getMin() == muAlt->getVal() ) {
687 fUseQTilde = 1;
688 oocoutI((TObject*)0,InputArguments) << "Minimum of POI is " << muTest->getMin() << " corresponds to alt snapshot - using qtilde asymptotic formulae " << std::endl;
689 } else {
690 fUseQTilde = 0;
691 oocoutI((TObject*)0,InputArguments) << "Minimum of POI is " << muTest->getMin() << " is different to alt snapshot " << muAlt->getVal()
692 << " - using standard q asymptotic formulae " << std::endl;
693 }
694 }
695 useQTilde = fUseQTilde;
696 }
697
698
699 //check for one side condition (remember this is valid only for one poi)
700 if (fOneSided ) {
701 if ( muHat->getVal() > muTest->getVal() ) {
702 oocoutI((TObject*)0,Eval) << "Using one-sided qmu - setting qmu to zero muHat = " << muHat->getVal()
703 << " muTest = " << muTest->getVal() << std::endl;
704 qmu = 0;
705 }
706 }
707 if (fOneSidedDiscovery ) {
708 if ( muHat->getVal() < muTest->getVal() ) {
709 oocoutI((TObject*)0,Eval) << "Using one-sided discovery qmu - setting qmu to zero muHat = " << muHat->getVal()
710 << " muTest = " << muTest->getVal() << std::endl;
711 qmu = 0;
712 }
713 }
714
715 // fix for negative qmu values due to numerical errors
716 if (qmu < 0 && qmu > -tol) qmu = 0;
717 if (qmu_A < 0 && qmu_A > -tol) qmu_A = 0;
718
719 // asymptotic formula for pnull and from paper Eur.Phys.J C 2011 71:1554
720 // we have 4 different cases:
721 // t(mu), t_tilde(mu) for the 2-sided
722 // q(mu) and q_tilde(mu) for the one -sided test statistics
723
724 double pnull = -1, palt = -1;
725
726 // asymptotic formula for pnull (for only one POI)
727 // From fact that qmu is a chi2 with ndf=1
728
729 double sqrtqmu = (qmu > 0) ? std::sqrt(qmu) : 0;
730 double sqrtqmu_A = (qmu_A > 0) ? std::sqrt(qmu_A) : 0;
731
732
734 // for one-sided PL (q_mu : equations 56,57)
735 if (verbose>2) {
736 if (fOneSided)
737 oocoutI((TObject*)0,Eval) << "Using one-sided limit asymptotic formula (qmu)" << endl;
738 else
739 oocoutI((TObject*)0,Eval) << "Using one-sided discovery asymptotic formula (q0)" << endl;
740 }
741 pnull = ROOT::Math::normal_cdf_c( sqrtqmu, 1.);
742 palt = ROOT::Math::normal_cdf( sqrtqmu_A - sqrtqmu, 1.);
743 }
744 else {
745 // for 2-sided PL (t_mu : equations 35,36 in asymptotic paper)
746 if (verbose > 2) oocoutI((TObject*)0,Eval) << "Using two-sided asymptotic formula (tmu)" << endl;
747 pnull = 2.*ROOT::Math::normal_cdf_c( sqrtqmu, 1.);
748 palt = ROOT::Math::normal_cdf_c( sqrtqmu + sqrtqmu_A, 1.) +
749 ROOT::Math::normal_cdf_c( sqrtqmu - sqrtqmu_A, 1.);
750
751 }
752
753 if (useQTilde ) {
754 if (fOneSided) {
755 // for bounded one-sided (q_mu_tilde: equations 64,65)
756 if ( qmu > qmu_A && (qmu_A > 0 || qmu > tol) ) { // to avoid case 0/0
757 if (verbose > 2) oocoutI((TObject*)0,Eval) << "Using qmu_tilde (qmu is greater than qmu_A)" << endl;
758 pnull = ROOT::Math::normal_cdf_c( (qmu + qmu_A)/(2 * sqrtqmu_A), 1.);
759 palt = ROOT::Math::normal_cdf_c( (qmu - qmu_A)/(2 * sqrtqmu_A), 1.);
760 }
761 }
762 else {
763 // for 2 sided bounded test statistic (N.B there is no one sided discovery qtilde)
764 // t_mu_tilde: equations 43,44 in asymptotic paper
765 if ( qmu > qmu_A && (qmu_A > 0 || qmu > tol) ) {
766 if (verbose > 2) oocoutI((TObject*)0,Eval) << "Using tmu_tilde (qmu is greater than qmu_A)" << endl;
767 pnull = ROOT::Math::normal_cdf_c(sqrtqmu,1.) +
768 ROOT::Math::normal_cdf_c( (qmu + qmu_A)/(2 * sqrtqmu_A), 1.);
769 palt = ROOT::Math::normal_cdf_c( sqrtqmu_A + sqrtqmu, 1.) +
770 ROOT::Math::normal_cdf_c( (qmu - qmu_A)/(2 * sqrtqmu_A), 1.);
771 }
772 }
773 }
774
775
776
777 // create an HypoTest result but where the sampling distributions are set to zero
778 string resultname = "HypoTestAsymptotic_result";
779 HypoTestResult* res = new HypoTestResult(resultname.c_str(), pnull, palt);
780
781 if (verbose > 0)
782 //std::cout
783 oocoutP((TObject*)0,Eval)
784 << "poi = " << muTest->getVal() << " qmu = " << qmu << " qmu_A = " << qmu_A
785 << " sigma = " << muTest->getVal()/sqrtqmu_A
786 << " CLsplusb = " << pnull << " CLb = " << palt << " CLs = " << res->CLs() << std::endl;
787
788 return res;
789
790}
791
792struct PaltFunction {
793 PaltFunction( double offset, double pval, int icase) :
794 fOffset(offset), fPval(pval), fCase(icase) {}
795 double operator() (double x) const {
796 return ROOT::Math::normal_cdf_c(x + fOffset) + ROOT::Math::normal_cdf_c(fCase*(x - fOffset)) - fPval;
797 }
798 double fOffset;
799 double fPval;
800 int fCase;
801};
802
803////////////////////////////////////////////////////////////////////////////////
804/// function given the null and the alt p value - return the expected one given the N - sigma value
805
806double AsymptoticCalculator::GetExpectedPValues(double pnull, double palt, double nsigma, bool useCls, bool oneSided ) {
807 if (oneSided) {
808 double sqrtqmu = ROOT::Math::normal_quantile_c( pnull,1.);
809 double sqrtqmu_A = ROOT::Math::normal_quantile( palt,1.) + sqrtqmu;
810 double clsplusb = ROOT::Math::normal_cdf_c( sqrtqmu_A - nsigma, 1.);
811 if (!useCls) return clsplusb;
812 double clb = ROOT::Math::normal_cdf( nsigma, 1.);
813 return (clb == 0) ? -1 : clsplusb / clb;
814 }
815
816 // case of 2 sided test statistic
817 // need to compute numerically
818 double sqrttmu = ROOT::Math::normal_quantile_c( 0.5*pnull,1.);
819 if (sqrttmu == 0) {
820 // here cannot invert the function - skip the point
821 return -1;
822 }
823 // invert formula for palt to get sqrttmu_A
824 PaltFunction f( sqrttmu, palt, -1);
827 brf.SetFunction( wf, 0, 20);
828 bool ret = brf.Solve();
829 if (!ret) {
830 oocoutE((TObject*)0,Eval) << "Error finding expected p-values - return -1" << std::endl;
831 return -1;
832 }
833 double sqrttmu_A = brf.Root();
834
835 // now invert for expected value
836 PaltFunction f2( sqrttmu_A, ROOT::Math::normal_cdf( nsigma, 1.), 1);
838 brf.SetFunction(wf2,0,20);
839 ret = brf.Solve();
840 if (!ret) {
841 oocoutE((TObject*)0,Eval) << "Error finding expected p-values - return -1" << std::endl;
842 return -1;
843 }
844 return 2*ROOT::Math::normal_cdf_c( brf.Root(),1.);
845}
846
847// void GetExpectedLimit(double nsigma, double alpha, double &clsblimit, double &clslimit) {
848// // get expected limit
849// double
850// }
851
852////////////////////////////////////////////////////////////////////////////////
853/// fill bins by looping recursively on observables
854
855void AsymptoticCalculator::FillBins(const RooAbsPdf & pdf, const RooArgList &obs, RooAbsData & data, int &index, double &binVolume, int &ibin) {
856
857 bool debug = (fgPrintLevel >= 2);
858
859 RooRealVar * v = dynamic_cast<RooRealVar*>( &(obs[index]) );
860 if (!v) return;
861
862 RooArgSet obstmp(obs);
863 double expectedEvents = pdf.expectedEvents(obstmp);
864 // if (debug) {
865 // std::cout << "expected events = " << expectedEvents << std::endl;
866 // }
867
868 if (debug) cout << "looping on observable " << v->GetName() << endl;
869 for (int i = 0; i < v->getBins(); ++i) {
870 v->setBin(i);
871 if (index < obs.getSize() -1) {
872 index++; // increase index
873 double prevBinVolume = binVolume;
874 binVolume *= v->getBinWidth(i); // increase bin volume
875 FillBins(pdf, obs, data, index, binVolume, ibin);
876 index--; // decrease index
877 binVolume = prevBinVolume; // decrease also bin volume
878 }
879 else {
880
881 // this is now a new bin - compute the pdf in this bin
882 double totBinVolume = binVolume * v->getBinWidth(i);
883 double fval = pdf.getVal(&obstmp)*totBinVolume;
884
885 //if (debug) std::cout << "pdf value in the bin " << fval << " bin volume = " << totBinVolume << " " << fval*expectedEvents << std::endl;
886 if (fval*expectedEvents <= 0)
887 {
888 if (fval*expectedEvents < 0)
889 cout << "WARNING::Detected a bin with negative expected events! Please check your inputs." << endl;
890 else
891 cout << "WARNING::Detected a bin with zero expected events- skip it" << endl;
892 }
893 // have a cut off for overflows ??
894 else
895 data.add(obs, fval*expectedEvents);
896
897 if (debug) {
898 cout << "bin " << ibin << "\t";
899 for (int j=0; j < obs.getSize(); ++j) { cout << " " << ((RooRealVar&) obs[j]).getVal(); }
900 cout << " w = " << fval*expectedEvents;
901 cout << endl;
902 }
903 // RooArgSet xxx(obs);
904 // h3->Fill(((RooRealVar&) obs[0]).getVal(), ((RooRealVar&) obs[1]).getVal(), ((RooRealVar&) obs[2]).getVal() ,
905 // pdf->getVal(&xxx) );
906 ibin++;
907 }
908 }
909 //reset bin values
910 if (debug)
911 cout << "ending loop on .. " << v->GetName() << endl;
912
913 v->setBin(0);
914
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// Inpspect a product pdf to find all the Poisson or Gaussian parts to set the observed
919/// values to expected ones.
920
922{
923 RooLinkedListIter iter(prod.pdfList().iterator());
924 bool ret = true;
925 for (RooAbsArg *a = (RooAbsArg *) iter.Next(); a != 0; a = (RooAbsArg *) iter.Next()) {
926 if (!a->dependsOn(obs)) continue;
927 RooPoisson *pois = 0;
928 RooGaussian * gaus = 0;
929 if ((pois = dynamic_cast<RooPoisson *>(a)) != 0) {
930 ret &= SetObsToExpected(*pois, obs);
931 pois->setNoRounding(true); //needed since expected value is not an integer
932 } else if ((gaus = dynamic_cast<RooGaussian *>(a)) != 0) {
933 ret &= SetObsToExpected(*gaus, obs);
934 } else {
935 // should try to add also lognormal case ?
936 RooProdPdf *subprod = dynamic_cast<RooProdPdf *>(a);
937 if (subprod)
938 ret &= SetObsToExpected(*subprod, obs);
939 else {
940 oocoutE((TObject*)0,InputArguments) << "Illegal term in counting model: "
941 << "the PDF " << a->GetName()
942 << " depends on the observables, but is not a Poisson, Gaussian or Product"
943 << endl;
944 return false;
945 }
946 }
947 }
948
949 return ret;
950}
951
952////////////////////////////////////////////////////////////////////////////////
953/// set observed value to the expected one
954/// works for Gaussian, Poisson or LogNormal
955/// assumes mean parameter value is the argument not constant and not depending on observables
956/// (if more than two arguments are not constant will use first one but print a warning !)
957/// need to iterate on the components of the Poisson to get n and nu (nu can be a RooAbsReal)
958/// (code from G. Petrucciani and extended by L.M.)
959
961{
962 RooRealVar *myobs = 0;
963 RooAbsReal *myexp = 0;
964 const char * pdfName = pdf.IsA()->GetName();
965 RooFIter iter(pdf.serverMIterator());
966 for (RooAbsArg *a = iter.next(); a != 0; a = iter.next()) {
967 if (obs.contains(*a)) {
968 if (myobs != 0) {
969 oocoutF((TObject*)0,Generation) << "AsymptoticCalculator::SetObsExpected( " << pdfName << " ) : Has two observables ?? " << endl;
970 return false;
971 }
972 myobs = dynamic_cast<RooRealVar *>(a);
973 if (myobs == 0) {
974 oocoutF((TObject*)0,Generation) << "AsymptoticCalculator::SetObsExpected( " << pdfName << " ) : Observable is not a RooRealVar??" << endl;
975 return false;
976 }
977 } else {
978 if (!a->isConstant() ) {
979 if (myexp != 0) {
980 oocoutE((TObject*)0,Generation) << "AsymptoticCalculator::SetObsExpected( " << pdfName << " ) : Has two non-const arguments " << endl;
981 return false;
982 }
983 myexp = dynamic_cast<RooAbsReal *>(a);
984 if (myexp == 0) {
985 oocoutF((TObject*)0,Generation) << "AsymptoticCalculator::SetObsExpected( " << pdfName << " ) : Expected is not a RooAbsReal??" << endl;
986 return false;
987 }
988 }
989 }
990 }
991 if (myobs == 0) {
992 oocoutF((TObject*)0,Generation) << "AsymptoticCalculator::SetObsExpected( " << pdfName << " ) : No observable?" << endl;
993 return false;
994 }
995 if (myexp == 0) {
996 oocoutF((TObject*)0,Generation) << "AsymptoticCalculator::SetObsExpected( " << pdfName << " ) : No observable?" << endl;
997 return false;
998 }
999
1000 myobs->setVal(myexp->getVal());
1001
1002 if (fgPrintLevel > 2) {
1003 std::cout << "SetObsToExpected : setting " << myobs->GetName() << " to expected value " << myexp->getVal() << " of " << myexp->GetName() << std::endl;
1004 }
1005
1006 return true;
1007}
1008
1009////////////////////////////////////////////////////////////////////////////////
1010/// Generate counting Asimov data for the case when the pdf cannot be extended.
1011/// This function assumes that the pdf is a RooPoisson or can be decomposed in a product of RooPoisson,
1012/// or is a RooGaussian. Otherwise, we cannot know how to make the Asimov data sets.
1013
1015 RooArgSet obs(observables);
1016 RooProdPdf *prod = dynamic_cast<RooProdPdf *>(&pdf);
1017 RooPoisson *pois = 0;
1018 RooGaussian *gaus = 0;
1019
1020 if (fgPrintLevel > 1)
1021 std::cout << "generate counting Asimov data for pdf of type " << pdf.IsA()->GetName() << std::endl;
1022
1023 bool r = false;
1024 if (prod != 0) {
1025 r = SetObsToExpected(*prod, observables);
1026 } else if ((pois = dynamic_cast<RooPoisson *>(&pdf)) != 0) {
1027 r = SetObsToExpected(*pois, observables);
1028 // we need in this case to set Poisson to real values
1029 pois->setNoRounding(true);
1030 } else if ((gaus = dynamic_cast<RooGaussian *>(&pdf)) != 0) {
1031 r = SetObsToExpected(*gaus, observables);
1032 } else {
1033 oocoutE((TObject*)0,InputArguments) << "A counting model pdf must be either a RooProdPdf or a RooPoisson or a RooGaussian" << endl;
1034 }
1035 if (!r) return 0;
1036 int icat = 0;
1037 if (channelCat) {
1038 icat = channelCat->getIndex();
1039 }
1040
1041 RooDataSet *ret = new RooDataSet(TString::Format("CountingAsimovData%d",icat),TString::Format("CountingAsimovData%d",icat), obs);
1042 ret->add(obs);
1043 return ret;
1044}
1045
1046////////////////////////////////////////////////////////////////////////////////
1047/// Compute the asimov data set for an observable of a pdf.
1048/// It generates binned data following the binning of the observables.
1049// TODO: (possibility to change number of bins)
1050// TODO: implement integration over bin content
1051
1052RooAbsData * AsymptoticCalculator::GenerateAsimovDataSinglePdf(const RooAbsPdf & pdf, const RooArgSet & allobs, const RooRealVar & weightVar, RooCategory * channelCat) {
1053
1054 int printLevel = fgPrintLevel;
1055
1056 // Get observables defined by the pdf associated with this state
1057 std::unique_ptr<RooArgSet> obs(pdf.getObservables(allobs) );
1058
1059
1060 // if pdf cannot be extended assume is then a counting experiment
1061 if (!pdf.canBeExtended() ) return GenerateCountingAsimovData(const_cast<RooAbsPdf&>(pdf), *obs, weightVar, channelCat);
1062
1063 RooArgSet obsAndWeight(*obs);
1064 obsAndWeight.add(weightVar);
1065
1066 RooDataSet* asimovData = 0;
1067 if (channelCat) {
1068 int icat = channelCat->getIndex();
1069 asimovData = new RooDataSet(TString::Format("AsimovData%d",icat),TString::Format("combAsimovData%d",icat),
1070 RooArgSet(obsAndWeight,*channelCat),RooFit::WeightVar(weightVar));
1071 }
1072 else
1073 asimovData = new RooDataSet("AsimovData","AsimovData",RooArgSet(obsAndWeight),RooFit::WeightVar(weightVar));
1074
1075 // This works only for 1D observables
1076 //RooRealVar* thisObs = ((RooRealVar*)obstmp->first());
1077
1078 RooArgList obsList(*obs);
1079
1080 // loop on observables and on the bins
1081 if (printLevel >= 2) {
1082 cout << "Generating Asimov data for pdf " << pdf.GetName() << endl;
1083 cout << "list of observables " << endl;
1084 obsList.Print();
1085 }
1086
1087 int obsIndex = 0;
1088 double binVolume = 1;
1089 int nbins = 0;
1090 FillBins(pdf, obsList, *asimovData, obsIndex, binVolume, nbins);
1091 if (printLevel >= 2)
1092 cout << "filled from " << pdf.GetName() << " " << nbins << " nbins " << " volume is " << binVolume << endl;
1093
1094 // for (int iobs = 0; iobs < obsList.getSize(); ++iobs) {
1095 // RooRealVar * thisObs = dynamic_cast<RooRealVar*> &obsList[i];
1096 // if (thisObs == 0) continue;
1097 // // loop on the bin contents
1098 // for(int ibin=0; ibin<thisObs->numBins(); ++ibin){
1099 // thisObs->setBin(ibin);
1100
1101 // thisNorm=pdftmp->getVal(obstmp)*thisObs->getBinWidth(jj);
1102 // if (thisNorm*expectedEvents <= 0)
1103 // {
1104 // cout << "WARNING::Detected bin with zero expected events! Please check your inputs." << endl;
1105 // }
1106 // // have a cut off for overflows ??
1107 // obsDataUnbinned->add(*mc->GetObservables(), thisNorm*expectedEvents);
1108 // }
1109
1110 if (printLevel >= 1)
1111 {
1112 asimovData->Print();
1113 //cout <<"sum entries "<< asimovData->sumEntries()<<endl;
1114 }
1115 if( TMath::IsNaN(asimovData->sumEntries()) ){
1116 cout << "sum entries is nan"<<endl;
1117 assert(0);
1118 delete asimovData;
1119 asimovData = 0;
1120 }
1121
1122 return asimovData;
1123
1124}
1125
1126////////////////////////////////////////////////////////////////////////////////
1127/// generate the asimov data for the observables (not the global ones)
1128/// need to deal with the case of a sim pdf
1129
1131
1132 int printLevel = fgPrintLevel;
1133
1134 unique_ptr<RooRealVar> weightVar (new RooRealVar("binWeightAsimov", "binWeightAsimov", 1, 0, 1.E30 ));
1135
1136 if (printLevel > 1) cout <<" Generate Asimov data for observables"<<endl;
1137 //RooDataSet* simData=NULL;
1138 const RooSimultaneous* simPdf = dynamic_cast<const RooSimultaneous*>(&pdf);
1139 if (!simPdf) {
1140 // generate data for non sim pdf
1141 return GenerateAsimovDataSinglePdf( pdf, observables, *weightVar, 0);
1142 }
1143
1144 std::map<std::string, RooDataSet*> asimovDataMap;
1145
1146 //look at category of simpdf
1147 RooCategory& channelCat = (RooCategory&)simPdf->indexCat();
1148 int nrIndices = channelCat.numTypes();
1149 if( nrIndices == 0 ) {
1150 oocoutW((TObject*)0,Generation) << "Simultaneous pdf does not contain any categories." << endl;
1151 }
1152 for (int i=0;i<nrIndices;i++){
1153 channelCat.setIndex(i);
1154 //iFrame++;
1155 // Get pdf associated with state from simpdf
1156 RooAbsPdf* pdftmp = simPdf->getPdf(channelCat.getLabel()) ;
1157 assert(pdftmp != 0);
1158
1159 if (printLevel > 1)
1160 {
1161 cout << "on type " << channelCat.getLabel() << " " << channelCat.getIndex() << endl;
1162 }
1163
1164 RooAbsData * dataSinglePdf = GenerateAsimovDataSinglePdf( *pdftmp, observables, *weightVar, &channelCat);
1165 //((RooRealVar*)obstmp->first())->Print();
1166 //cout << "expected events " << pdftmp->expectedEvents(*obstmp) << endl;
1167 if (!dataSinglePdf) {
1168 oocoutE((TObject*)0,Generation) << "Error generating an Asimov data set for pdf " << pdftmp->GetName() << endl;
1169 return 0;
1170 }
1171
1172 if (asimovDataMap.count(string(channelCat.getLabel())) != 0) {
1173 oocoutE((TObject*)0,Generation) << "AsymptoticCalculator::GenerateAsimovData(): The PDF for " << channelCat.getLabel()
1174 << " was already defined. It will be overridden. The faulty category definitions follow:" << endl;
1175 channelCat.Print("V");
1176 }
1177
1178 asimovDataMap[string(channelCat.getLabel())] = (RooDataSet*) dataSinglePdf;
1179
1180 if (printLevel > 1)
1181 {
1182 cout << "channel: " << channelCat.getLabel() << ", data: ";
1183 dataSinglePdf->Print();
1184 cout << endl;
1185 }
1186 }
1187
1188 RooArgSet obsAndWeight(observables);
1189 obsAndWeight.add(*weightVar);
1190
1191
1192 RooDataSet* asimovData = new RooDataSet("asimovDataFullModel","asimovDataFullModel",RooArgSet(obsAndWeight,channelCat),
1193 RooFit::Index(channelCat),RooFit::Import(asimovDataMap),RooFit::WeightVar(*weightVar));
1194
1195 for (auto element : asimovDataMap) {
1196 delete element.second;
1197 }
1198
1199 return asimovData;
1200
1201}
1202
1203////////////////////////////////////////////////////////////////////////////////
1204/// Make the Asimov data from the ModelConfig and list of poi
1205/// \param realData Real data
1206/// \param model Model config defining the pdf and the parameters
1207/// \param paramValues The snapshot of POI and parameters used for finding the best nuisance parameter values (conditioned at these values)
1208/// \param[out] asimovGlobObs Global observables set to values satisfying the constraints
1209/// \param genPoiValues Optional. A different set of POI values used for generating. By default the same POI are used for generating and for finding the nuisance parameters
1210/// given an observed data set, a model and a snapshot of the poi.
1211/// \return The asimov data set. The user takes ownership.
1212///
1213
1214RooAbsData * AsymptoticCalculator::MakeAsimovData(RooAbsData & realData, const ModelConfig & model, const RooArgSet & paramValues, RooArgSet & asimovGlobObs, const RooArgSet * genPoiValues ) {
1215
1216 int verbose = fgPrintLevel;
1217
1218
1219 RooArgSet poi(*model.GetParametersOfInterest());
1220 poi = paramValues;
1221 //RooRealVar *r = dynamic_cast<RooRealVar *>(poi.first());
1222 // set poi constant for conditional MLE
1223 // need to fit nuisance parameters at their conditional MLE value
1224 RooLinkedListIter it = poi.iterator();
1225 RooRealVar* tmpPar = NULL;
1226 RooArgSet paramsSetConstant;
1227 while((tmpPar = (RooRealVar*)it.Next())){
1228 tmpPar->setConstant();
1229 if (verbose>0)
1230 std::cout << "MakeAsimov: Setting poi " << tmpPar->GetName() << " to a constant value = " << tmpPar->getVal() << std::endl;
1231 paramsSetConstant.add(*tmpPar);
1232 }
1233
1234 // find conditional value of the nuisance parameters
1235 bool hasFloatParams = false;
1236 RooArgSet constrainParams;
1237 if (model.GetNuisanceParameters()) {
1238 constrainParams.add(*model.GetNuisanceParameters());
1239 RooStats::RemoveConstantParameters(&constrainParams);
1240 if (constrainParams.getSize() > 0) hasFloatParams = true;
1241
1242 } else {
1243 // Do we have free parameters anyway that need fitting?
1244 std::unique_ptr<RooArgSet> params(model.GetPdf()->getParameters(realData));
1245 RooLinkedListIter iter(params->iterator());
1246 for (RooAbsArg *a = (RooAbsArg *) iter.Next(); a != 0; a = (RooAbsArg *) iter.Next()) {
1247 RooRealVar *rrv = dynamic_cast<RooRealVar *>(a);
1248 if ( rrv != 0 && rrv->isConstant() == false ) { hasFloatParams = true; break; }
1249 }
1250 }
1251 if (hasFloatParams) {
1252 // models need to be fitted to find best nuisance parameter values
1253
1254 TStopwatch tw2; tw2.Start();
1256 if (verbose>0) {
1257 std::cout << "MakeAsimov: doing a conditional fit for finding best nuisance values " << std::endl;
1258 minimPrintLevel = verbose;
1259 if (verbose>1) {
1260 std::cout << "POI values:\n"; poi.Print("v");
1261 if (verbose > 2) {
1262 std::cout << "Nuis param values:\n";
1263 constrainParams.Print("v");
1264 }
1265 }
1266 }
1269
1270 RooArgSet conditionalObs;
1271 if (model.GetConditionalObservables()) conditionalObs.add(*model.GetConditionalObservables());
1272 RooArgSet globalObs;
1273 if (model.GetGlobalObservables()) globalObs.add(*model.GetGlobalObservables());
1274
1275 std::string minimizerType = ROOT::Math::MinimizerOptions::DefaultMinimizerType();
1276 std::string minimizerAlgo = ROOT::Math::MinimizerOptions::DefaultMinimizerAlgo();
1277 model.GetPdf()->fitTo(realData, RooFit::Minimizer(minimizerType.c_str(),minimizerAlgo.c_str()),
1279 RooFit::PrintLevel(minimPrintLevel-1), RooFit::Hesse(false),
1280 RooFit::Constrain(constrainParams),RooFit::GlobalObservables(globalObs),
1282 if (verbose>0) { std::cout << "fit time "; tw2.Print();}
1283 if (verbose > 1) {
1284 // after the fit the nuisance parameters will have their best fit value
1285 if (model.GetNuisanceParameters() ) {
1286 std::cout << "Nuisance parameters after fit for asimov dataset: " << std::endl;
1287 model.GetNuisanceParameters()->Print("V");
1288 }
1289 }
1290
1292
1293 }
1294
1295 // restore the parameters which were set constant
1296 SetAllConstant(paramsSetConstant, false);
1297
1298
1299 RooArgSet * allParams = model.GetPdf()->getParameters(realData);
1301
1302 // if a RooArgSet of poi is passed , different poi will be used for generating the Asimov data set
1303 if (genPoiValues) *allParams = *genPoiValues;
1304
1305 // now do the actual generation of the AsimovData Set
1306 // no need to pass parameters values since we have set them before
1307 RooAbsData * asimovData = MakeAsimovData(model, *allParams, asimovGlobObs);
1308
1309 delete allParams;
1310
1311 return asimovData;
1312
1313}
1314
1315////////////////////////////////////////////////////////////////////////////////
1316/// \param model ModelConfig that contains the model pdf and the model parameters
1317/// \param allParamValues The parameters fo the model will be set to the values given in this set
1318/// \param[out] asimovGlobObs Global observables set to values satisfying the constraints
1319/// \return Asimov data set. The user takes ownership.
1320///
1321/// The parameter values (including the nuisance parameter) can result from a fit to data or be at the nominal values.
1322///
1323
1324RooAbsData * AsymptoticCalculator::MakeAsimovData(const ModelConfig & model, const RooArgSet & allParamValues, RooArgSet & asimovGlobObs) {
1325
1326 int verbose = fgPrintLevel;
1327
1328 TStopwatch tw;
1329 tw.Start();
1330
1331 // set the parameter values (do I need the poi to be constant ? )
1332 // the nuisance parameter values could be set at their fitted value (the MLE)
1333 if (allParamValues.getSize() > 0) {
1334 RooArgSet * allVars = model.GetPdf()->getVariables();
1335 *allVars = allParamValues;
1336 delete allVars;
1337 }
1338
1339
1340 // generate the Asimov data set for the observables
1341 RooAbsData * asimov = GenerateAsimovData(*model.GetPdf() , *model.GetObservables() );
1342
1343 if (verbose>0) {
1344 std::cout << "Generated Asimov data for observables "; (model.GetObservables() )->Print();
1345 if (verbose > 1) {
1346 if (asimov->numEntries() == 1 ) {
1347 std::cout << "--- Asimov data values \n";
1348 asimov->get()->Print("v");
1349 }
1350 else {
1351 std::cout << "--- Asimov data numEntries = " << asimov->numEntries() << " sumOfEntries = " << asimov->sumEntries() << std::endl;
1352 }
1353 std::cout << "\ttime for generating : "; tw.Print();
1354 }
1355 }
1356
1357
1358 // Now need to have in ASIMOV the data sets also the global observables
1359 // Their values must be the one satisfying the constraint.
1360 // to do it make a nuisance pdf with all product of constraints and then
1361 // assign to each constraint a glob observable value = to the current fitted nuisance parameter value
1362 // IN general one should solve in general the system of equations f( gobs| nuispar ) = 0 where f are the
1363 // derivatives of the constraint with respect the nuisance parameter and they are evaluated at the best fit nuisance
1364 // parameter points
1365 // As simple solution assume that constrain has a direct dependence on the nuisance parameter, i.e.
1366 // Constraint (gobs, func( nuispar) ) and the condition is satisfied for
1367 // gobs = func( nuispar) where nunispar is at the MLE value
1368
1369
1370 if (model.GetGlobalObservables() && model.GetGlobalObservables()->getSize() > 0) {
1371
1372 if (verbose>1) {
1373 std::cout << "Generating Asimov data for global observables " << std::endl;
1374 }
1375
1376 RooArgSet gobs(*model.GetGlobalObservables());
1377
1378 // snapshot data global observables
1379 RooArgSet snapGlobalObsData;
1380 SetAllConstant(gobs, true);
1381 gobs.snapshot(snapGlobalObsData);
1382
1383
1384 RooArgSet nuis;
1385 if (model.GetNuisanceParameters()) nuis.add(*model.GetNuisanceParameters());
1386 if (nuis.getSize() == 0) {
1387 oocoutW((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData: model does not have nuisance parameters but has global observables"
1388 << " set global observables to model values " << endl;
1389 asimovGlobObs = gobs;
1390 return asimov;
1391 }
1392
1393 // part 1: create the nuisance pdf
1394 std::unique_ptr<RooAbsPdf> nuispdf(RooStats::MakeNuisancePdf(model,"TempNuisPdf") );
1395 if (nuispdf.get() == 0) {
1396 oocoutF((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData: model has nuisance parameters and global obs but no nuisance pdf "
1397 << std::endl;
1398 }
1399 // unfold the nuisance pdf if it is a prod pdf
1400 RooArgList pdfList;
1401 RooProdPdf *prod = dynamic_cast<RooProdPdf *>(nuispdf.get());
1402 if (prod ) {
1403 pdfList.add(prod->pdfList());
1404 }
1405 else
1406 // nothing to unfold - just use the pdf
1407 pdfList.add(*nuispdf.get());
1408
1409 RooLinkedListIter iter(pdfList.iterator());
1410 for (RooAbsArg *a = (RooAbsArg *) iter.Next(); a != 0; a = (RooAbsArg *) iter.Next()) {
1411 RooAbsPdf *cterm = dynamic_cast<RooAbsPdf *>(a);
1412 assert(cterm && "AsimovUtils: a factor of the nuisance pdf is not a Pdf!");
1413 if (!cterm->dependsOn(nuis)) continue; // dummy constraints
1414 // skip also the case of uniform components
1415 if (typeid(*cterm) == typeid(RooUniform)) continue;
1416
1417 std::unique_ptr<RooArgSet> cpars(cterm->getParameters(&gobs));
1418 std::unique_ptr<RooArgSet> cgobs(cterm->getObservables(&gobs));
1419 if (cgobs->getSize() > 1) {
1420 oocoutE((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData: constraint term " << cterm->GetName()
1421 << " has multiple global observables -cannot generate - skip it" << std::endl;
1422 continue;
1423 }
1424 else if (cgobs->getSize() == 0) {
1425 oocoutW((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData: constraint term " << cterm->GetName()
1426 << " has no global observables - skip it" << std::endl;
1427 continue;
1428 }
1429 // the variable representing the global observable
1430 RooRealVar &rrv = dynamic_cast<RooRealVar &>(*cgobs->first());
1431
1432 // remove the constant parameters in cpars
1434 if (cpars->getSize() != 1) {
1435 oocoutE((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData:constraint term "
1436 << cterm->GetName() << " has multiple floating params - cannot generate - skip it " << std::endl;
1437 continue;
1438 }
1439
1440 bool foundServer = false;
1441 // note : this will work only for this type of constraints
1442 // expressed as RooPoisson, RooGaussian, RooLognormal, RooGamma
1443 TClass * cClass = cterm->IsA();
1444 if (verbose > 2) std::cout << "Constraint " << cterm->GetName() << " of type " << cClass->GetName() << std::endl;
1445 if ( cClass != RooGaussian::Class() && cClass != RooPoisson::Class() &&
1446 cClass != RooGamma::Class() && cClass != RooLognormal::Class() &&
1447 cClass != RooBifurGauss::Class() ) {
1448 TString className = (cClass) ? cClass->GetName() : "undefined";
1449 oocoutW((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData:constraint term "
1450 << cterm->GetName() << " of type " << className
1451 << " is a non-supported type - result might be not correct " << std::endl;
1452 }
1453
1454 // in case of a Poisson constraint make sure the rounding is not set
1455 if (cClass == RooPoisson::Class() ) {
1456 RooPoisson * pois = dynamic_cast<RooPoisson*>(cterm);
1457 assert(pois);
1458 pois->setNoRounding(true);
1459 }
1460
1461 // look at server of the constraint term and check if the global observable is part of the server
1462 RooAbsArg * arg = cterm->findServer(rrv);
1463 if (!arg) {
1464 // special case is for the Gamma where one might define the global observable n and you have a Gamma(b, n+1, ...._
1465 // in this case n+1 is the server and we don;t have a direct dependency, but we want to set n to the b value
1466 // so in case of the Gamma ignore this test
1467 if ( cClass != RooGamma::Class() ) {
1468 oocoutE((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData:constraint term "
1469 << cterm->GetName() << " has no direct dependence on global observable- cannot generate it " << std::endl;
1470 continue;
1471 }
1472 }
1473
1474 // loop on the server of the constraint term
1475 // need to treat the Gamma as a special case
1476 // the mode of the Gamma is (k-1)*theta where theta is the inverse of the rate parameter.
1477 // we assume that the global observable is defined as ngobs = k-1 and the theta parameter has the name theta otherwise we use other procedure which might be wrong
1478 RooAbsReal * thetaGamma = 0;
1479 if ( cClass == RooGamma::Class() ) {
1480 RooFIter itc(cterm->serverMIterator() );
1481 for (RooAbsArg *a2 = itc.next(); a2 != 0; a2 = itc.next()) {
1482 if (TString(a2->GetName()).Contains("theta") ) {
1483 thetaGamma = dynamic_cast<RooAbsReal*>(a2);
1484 break;
1485 }
1486 }
1487 if (thetaGamma == 0) {
1488 oocoutI((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData:constraint term "
1489 << cterm->GetName() << " is a Gamma distribution and no server named theta is found. Assume that the Gamma scale is 1 " << std::endl;
1490 }
1491 else {
1492 if (verbose>2)
1493 std::cout << "Gamma constraint has a scale " << thetaGamma->GetName() << " = " << thetaGamma->getVal() << std::endl;
1494 }
1495 }
1496 RooFIter iter2(cterm->serverMIterator() );
1497 for (RooAbsArg *a2 = iter2.next(); a2 != 0; a2 = iter2.next()) {
1498 RooAbsReal * rrv2 = dynamic_cast<RooAbsReal *>(a2);
1499 if (verbose > 2) std::cout << "Loop on constraint server term " << a2->GetName() << std::endl;
1500 if (rrv2 && rrv2->dependsOn(nuis) ) {
1501
1502
1503 // found server depending on nuisance
1504 if (foundServer) {
1505 oocoutE((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData:constraint term "
1506 << cterm->GetName() << " constraint term has more server depending on nuisance- cannot generate it " <<
1507 std::endl;
1508 foundServer = false;
1509 break;
1510 }
1511 if (thetaGamma && thetaGamma->getVal() > 0)
1512 rrv.setVal( rrv2->getVal() / thetaGamma->getVal() );
1513 else
1514 rrv.setVal( rrv2->getVal() );
1515 foundServer = true;
1516
1517 if (verbose>2)
1518 std::cout << "setting global observable "<< rrv.GetName() << " to value " << rrv.getVal()
1519 << " which comes from " << rrv2->GetName() << std::endl;
1520 }
1521 }
1522
1523 if (!foundServer) {
1524 oocoutE((TObject*)0,Generation) << "AsymptoticCalculator::MakeAsimovData - can't find nuisance for constraint term - global observables will not be set to Asimov value " << cterm->GetName() << std::endl;
1525 std::cerr << "Parameters: " << std::endl;
1526 cpars->Print("V");
1527 std::cerr << "Observables: " << std::endl;
1528 cgobs->Print("V");
1529 }
1530// rrv.setVal(match->getVal());
1531 }
1532
1533 // make a snapshot of global observables
1534 // needed this ?? (LM)
1535
1536 asimovGlobObs.removeAll();
1537 SetAllConstant(gobs, true);
1538 gobs.snapshot(asimovGlobObs);
1539
1540 // revert global observables to the data value
1541 gobs = snapGlobalObsData;
1542
1543 if (verbose>0) {
1544 std::cout << "Generated Asimov data for global observables ";
1545 if (verbose == 1) gobs.Print();
1546 }
1547
1548 if (verbose > 1) {
1549 std::cout << "\nGlobal observables for data: " << std::endl;
1550 gobs.Print("V");
1551 std::cout << "\nGlobal observables for asimov: " << std::endl;
1552 asimovGlobObs.Print("V");
1553 }
1554
1555
1556 }
1557
1558 return asimov;
1559
1560}
void Class()
Definition: Class.C:29
SVector< double, 2 > v
Definition: Dict.h:5
ROOT::R::TRInterface & r
Definition: Object.C:4
#define f(i)
Definition: RSha256.hxx:104
#define oocoutW(o, a)
Definition: RooMsgService.h:46
#define oocoutE(o, a)
Definition: RooMsgService.h:47
#define oocoutF(o, a)
Definition: RooMsgService.h:48
#define oocoutI(o, a)
Definition: RooMsgService.h:44
#define oocoutP(o, a)
Definition: RooMsgService.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:88
double Double_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
double sqrt(double)
TRObject operator()(const T1 &t1) const
Class for finding the root of a one dimensional function using the Brent algorithm.
double Root() const
Returns root value.
bool Solve(int maxIter=100, double absTol=1E-8, double relTol=1E-10)
Returns the X value corresponding to the function value fy for (xmin<x<xmax).
bool SetFunction(const ROOT::Math::IGenFunction &f, double xlow, double xup)
Sets the function for the rest of the algorithms.
static const std::string & DefaultMinimizerType()
static const std::string & DefaultMinimizerAlgo()
Template class to wrap any C++ callable object which takes one argument i.e.
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:70
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Return the observables of this pdf given a set of observables.
Definition: RooAbsArg.h:240
Bool_t dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=0, Bool_t valueOnly=kFALSE) const
Test whether we depend on (ie, are served by) any object in the specified collection.
Definition: RooAbsArg.cxx:729
RooFIter serverMIterator() const R__SUGGEST_ALTERNATIVE("Use shapeClients() and begin()
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooAbsArg.h:272
RooArgSet * getParameters(const RooAbsData *data, Bool_t stripDisconnected=kTRUE) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
Definition: RooAbsArg.cxx:543
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2034
Bool_t isConstant() const
Definition: RooAbsArg.h:311
RooAbsArg * findServer(const char *name) const
Definition: RooAbsArg.h:165
Int_t numTypes(const char *=0) const
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
Int_t getSize() const
Bool_t contains(const RooAbsArg &var) const
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
RooAbsArg * first() const
RooLinkedListIter iterator(Bool_t dir=kIterForward) const R__SUGGEST_ALTERNATIVE("begin()
TIterator-style iteration over contained elements.
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:37
virtual const RooArgSet * get() const
Definition: RooAbsData.h:80
virtual Double_t sumEntries() const =0
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooAbsData.h:162
virtual void add(const RooArgSet &row, Double_t weight=1, Double_t weightError=0)=0
virtual Int_t numEntries() const
Definition: RooAbsData.cxx:306
virtual RooAbsReal * createNLL(RooAbsData &data, const RooLinkedList &cmdList)
Construct representation of -log(L) of PDFwith given dataset.
Definition: RooAbsPdf.cxx:800
Bool_t canBeExtended() const
Definition: RooAbsPdf.h:230
virtual RooFitResult * fitTo(RooAbsData &data, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none())
Fit PDF to given dataset.
Definition: RooAbsPdf.cxx:1119
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return expected number of events from this p.d.f for use in extended likelihood calculations.
Definition: RooAbsPdf.cxx:2920
virtual Double_t getMax(const char *name=0) const
Get maximum of currently defined range.
virtual Int_t getBins(const char *name=0) const
Get number of bins of currently defined range.
void setConstant(Bool_t value=kTRUE)
virtual Double_t getMin(const char *name=0) const
Get miniminum of currently defined range.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
static void setHideOffset(Bool_t flag)
Definition: RooAbsReal.cxx:117
static Bool_t hideOffset()
Definition: RooAbsReal.cxx:118
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:81
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:21
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:134
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:88
RooCategory represents a fundamental (non-derived) discrete value object.
Definition: RooCategory.h:24
virtual const char * getLabel() const
Return label string of current state.
Definition: RooCategory.h:39
virtual Int_t getIndex() const
Return index number of current state.
Definition: RooCategory.h:34
virtual Bool_t setIndex(Int_t index, Bool_t printError=kTRUE)
Set value by specifying the index code of the desired state.
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:31
virtual Double_t sumEntries() const
virtual void add(const RooArgSet &row, Double_t weight=1.0, Double_t weightError=0)
Add a data point, with its coordinates specified in the 'data' argset, to the data set.
A one-time forward iterator working on RooLinkedList or RooAbsCollection.
RooAbsArg * next()
Return next element or nullptr if at end.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Definition: RooFitResult.h:40
Double_t minNll() const
Definition: RooFitResult.h:98
Plain Gaussian p.d.f.
Definition: RooGaussian.h:25
A wrapper around TIterator derivatives.
TObject * Next() override
RooMinimizer is a wrapper class around ROOT::Fit:Fitter that provides a seamless interface between th...
Definition: RooMinimizer.h:38
RooFitResult * save(const char *name=0, const char *title=0)
Save and return a RooFitResult snaphot of current minimizer status.
Int_t minimize(const char *type, const char *alg=0)
void setEps(Double_t eps)
Change MINUIT epsilon.
Int_t setPrintLevel(Int_t newLevel)
Change the MINUIT internal printing level.
void optimizeConst(Int_t flag)
If flag is true, perform constant term optimization on function being minimized.
void setStrategy(Int_t strat)
Change MINUIT strategy to istrat.
static RooMsgService & instance()
Return reference to singleton instance.
void setGlobalKillBelow(RooFit::MsgLevel level)
RooFit::MsgLevel globalKillBelow() const
Poisson pdf.
Definition: RooPoisson.h:19
void setNoRounding(bool flag=kTRUE)
Definition: RooPoisson.h:33
RooProdPdf is an efficient implementation of a product of PDFs of the form.
Definition: RooProdPdf.h:31
const RooArgList & pdfList() const
Definition: RooProdPdf.h:69
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:36
void setBins(Int_t nBins, const char *name=0)
Definition: RooRealVar.h:78
Double_t getError() const
Definition: RooRealVar.h:54
virtual void setVal(Double_t value)
Set value of variable to 'value'.
Definition: RooRealVar.cxx:233
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
const RooAbsCategoryLValue & indexCat() const
RooAbsPdf * getPdf(const char *catName) const
Return the p.d.f associated with the given index category name.
Hypothesis Test Calculator based on the asymptotic formulae for the profile likelihood ratio.
static RooAbsData * GenerateAsimovDataSinglePdf(const RooAbsPdf &pdf, const RooArgSet &obs, const RooRealVar &weightVar, RooCategory *channelCat=0)
Compute the asimov data set for an observable of a pdf.
virtual HypoTestResult * GetHypoTest() const
re-implement HypoTest computation using the asymptotic
static double GetExpectedPValues(double pnull, double palt, double nsigma, bool usecls, bool oneSided=true)
function given the null and the alt p value - return the expected one given the N - sigma value
static RooAbsData * MakeAsimovData(RooAbsData &data, const ModelConfig &model, const RooArgSet &poiValues, RooArgSet &globObs, const RooArgSet *genPoiValues=0)
Make Asimov data.
static bool SetObsToExpected(RooAbsPdf &pdf, const RooArgSet &obs)
set observed value to the expected one works for Gaussian, Poisson or LogNormal assumes mean paramete...
static RooAbsData * GenerateAsimovData(const RooAbsPdf &pdf, const RooArgSet &observables)
generate the asimov data for the observables (not the global ones) need to deal with the case of a si...
static RooAbsData * GenerateCountingAsimovData(RooAbsPdf &pdf, const RooArgSet &obs, const RooRealVar &weightVar, RooCategory *channelCat=0)
Generate counting Asimov data for the case when the pdf cannot be extended.
int fUseQTilde
flag to check if calculator is initialized
AsymptoticCalculator(RooAbsData &data, const ModelConfig &altModel, const ModelConfig &nullModel, bool nominalAsimov=false)
constructor for asymptotic calculator from Data set and ModelConfig
static void FillBins(const RooAbsPdf &pdf, const RooArgList &obs, RooAbsData &data, int &index, double &binVolume, int &ibin)
fill bins by looping recursively on observables
static double EvaluateNLL(RooAbsPdf &pdf, RooAbsData &data, const RooArgSet *condObs, const RooArgSet *globObs, const RooArgSet *poiSet=0)
bool Initialize() const
initialize the calculator by performing a global fit and make the Asimov data set
Common base class for the Hypothesis Test Calculators.
const ModelConfig * GetNullModel(void) const
const ModelConfig * GetAlternateModel(void) const
const RooAbsData * GetData(void) const
HypoTestResult is a base class for results from hypothesis tests.
virtual Double_t CLs() const
is simply (not a method, but a quantity)
ModelConfig is a simple class that holds configuration information specifying how a model should be u...
Definition: ModelConfig.h:30
const RooArgSet * GetConditionalObservables() const
get RooArgSet for conditional observables (return NULL if not existing)
Definition: ModelConfig.h:246
const RooArgSet * GetGlobalObservables() const
get RooArgSet for global observables (return NULL if not existing)
Definition: ModelConfig.h:249
const RooArgSet * GetParametersOfInterest() const
get RooArgSet containing the parameter of interest (return NULL if not existing)
Definition: ModelConfig.h:231
const RooArgSet * GetNuisanceParameters() const
get RooArgSet containing the nuisance parameters (return NULL if not existing)
Definition: ModelConfig.h:234
const RooArgSet * GetObservables() const
get RooArgSet for observables (return NULL if not existing)
Definition: ModelConfig.h:243
const RooArgSet * GetSnapshot() const
get RooArgSet for parameters for a particular hypothesis (return NULL if not existing)
RooAbsPdf * GetPdf() const
get model PDF (return NULL if pdf has not been specified or does not exist)
Definition: ModelConfig.h:228
Flat p.d.f.
Definition: RooUniform.h:24
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
Stopwatch class.
Definition: TStopwatch.h:28
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
Definition: TStopwatch.cxx:58
void Print(Option_t *option="") const
Print the real and cpu time passed between the start and stop events.
Definition: TStopwatch.cxx:219
Basic string class.
Definition: TString.h:131
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2311
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
double normal_cdf_c(double x, double sigma=1, double x0=0)
Complement of the cumulative distribution function of the normal (Gaussian) distribution (upper tail)...
double normal_cdf(double x, double sigma=1, double x0=0)
Cumulative distribution function of the normal (Gaussian) distribution (lower tail).
double normal_quantile(double z, double sigma)
Inverse ( ) of the cumulative distribution function of the lower tail of the normal (Gaussian) distri...
double normal_quantile_c(double z, double sigma)
Inverse ( ) of the cumulative distribution function of the upper tail of the normal (Gaussian) distri...
Double_t x[n]
Definition: legend1.C:17
void Print(std::ostream &os, const OptionType &opt)
RooCmdArg WeightVar(const char *name, Bool_t reinterpretAsWeight=kFALSE)
RooCmdArg Constrain(const RooArgSet &params)
RooCmdArg Strategy(Int_t code)
RooCmdArg Index(RooCategory &icat)
RooCmdArg GlobalObservables(const RooArgSet &globs)
RooCmdArg Hesse(Bool_t flag=kTRUE)
@ Minimization
Definition: RooGlobalFunc.h:57
@ Generation
Definition: RooGlobalFunc.h:57
@ InputArguments
Definition: RooGlobalFunc.h:58
RooCmdArg CloneData(Bool_t flag)
RooCmdArg PrintLevel(Int_t code)
RooCmdArg Import(const char *state, TH1 &histo)
RooCmdArg ConditionalObservables(const RooArgSet &set)
RooCmdArg Offset(Bool_t flag=kTRUE)
RooCmdArg Minimizer(const char *type, const char *alg=0)
Namespace for the RooStats classes.
Definition: Asimov.h:20
bool SetAllConstant(const RooAbsCollection &coll, bool constant=true)
Definition: RooStatsUtils.h:82
void RemoveConstantParameters(RooArgSet *set)
Definition: RooStatsUtils.h:62
RooAbsPdf * MakeNuisancePdf(RooAbsPdf &pdf, const RooArgSet &observables, const char *name)
bool IsNLLOffset()
Bool_t IsNaN(Double_t x)
Definition: TMath.h:880
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754
Definition: TMath.h:889
Definition: first.py:1
auto * a
Definition: textangle.C:12