Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooMCStudy.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17/**
18\file RooMCStudy.cxx
19\class RooMCStudy
20\ingroup Roofitcore
21
22Helper class to facilitate Monte Carlo studies
23such as 'goodness-of-fit' studies, that involve fitting a PDF
24to multiple toy Monte Carlo sets. These may be generated from either same PDF
25or from a different PDF with similar parameters.
26
27Given a fit and a generator PDF (they might be identical), RooMCStudy can produce
28toyMC samples and/or fit these.
29It accumulates the post-fit parameters of each iteration in a dataset. These can be
30retrieved using fitParams() or fitParDataSet(). This dataset additionally contains the
31variables
32- NLL: The value of the negative log-likelihood for each run.
33- ngen: The number of events generated for each run.
34
35Additional plotting routines simplify the task of plotting
36the distribution of the minimized likelihood, the fitted parameter values,
37fitted error and pull distribution.
38
39RooMCStudy provides the option to insert add-in modules
40that modify the generate-and-fit cycle and allow to perform
41extra steps in the cycle. Output of these modules can be stored
42alongside the fit results in the aggregate results dataset.
43These study modules should derive from the class RooAbsMCStudyModule.
44
45Check the RooFit tutorials
46- rf801_mcstudy.C
47- rf802_mcstudy_addons.C
48- rf803_mcstudy_addons2.C
49- rf804_mcstudy_constr.C
50for usage examples.
51**/
52
53
54#include <RooMCStudy.h>
55
56#include <RooAbsMCStudyModule.h>
57#include <RooAbsPdf.h>
58#include <RooArgList.h>
59#include <RooCmdConfig.h>
60#include <RooDataHist.h>
61#include <RooDataSet.h>
62#include <RooErrorVar.h>
63#include <RooFitResult.h>
64#include <RooFormulaVar.h>
65#include <RooGenContext.h>
66#include <RooGlobalFunc.h>
67#include <RooMsgService.h>
68#include <RooPlot.h>
69#include <RooProdPdf.h>
70#include <RooPullVar.h>
71#include <RooRandom.h>
72#include <RooRealVar.h>
73#include <RooWorkspace.h>
74
75#include <TAxis.h>
76
77
78#include <cstdio>
79#include <algorithm>
80#include <iostream>
81
82
83/**
84Construct Monte Carlo Study Manager. This class automates generating data from a given PDF,
85fitting the PDF to data and accumulating the fit statistics.
86
87\param[in] model The PDF to be studied
88\param[in] observables The variables of the PDF to be considered observables
89\param[in] arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8 Optional arguments according to table below.
90
91<table>
92<tr><th> Optional arguments <th>
93<tr><td> Silence() <td> Suppress all RooFit messages during running below PROGRESS level
94<tr><td> FitModel(const RooAbsPdf&) <td> The PDF for fitting if it is different from the PDF for generating.
95<tr><td> ConditionalObservables(const RooArgSet& set) <td> The set of observables that the PDF should _not_ be normalized over
96<tr><td> Binned(bool flag) <td> Bin the dataset before fitting it. Speeds up fitting of large data samples
97<tr><td> FitOptions(....) <td> Options to be used for fitting. All named arguments inside FitOptions() are passed to RooAbsPdf::fitTo().
98 `Save()` is especially interesting to be able to retrieve fit results of each run using fitResult().
99<tr><td> Verbose(bool flag) <td> Activate informational messages in event generation phase
100<tr><td> Extended(bool flag) <td> Determine number of events for each sample anew from a Poisson distribution
101<tr><td> Constrain(const RooArgSet& pars) <td> Apply internal constraints on given parameters in fit and sample constrained parameter values from constraint p.d.f for each toy.
102<tr><td> ExternalConstraints(const RooArgSet& cpdfs) <td> Apply given external constraint p.d.f.s in fit and sample values of the parameters they constrain from them for each toy.
103 To apply the constraints in the fit only, without the per-toy sampling, pass them inside FitOptions() instead.
104<tr><td> ProtoData(const RooDataSet&, bool randOrder)
105 <td> Prototype data for the event generation. If the randOrder flag is set, the order of the dataset will be re-randomized for each generation
106 cycle to protect against systematic biases if the number of generated events does not exactly match the number of events in the prototype dataset
107 at the cost of reduced precision with mu equal to the specified number of events
108</table>
109*/
110RooMCStudy::RooMCStudy(const RooAbsPdf& model, const RooArgSet& observables,
111 const RooCmdArg& arg1, const RooCmdArg& arg2,
112 const RooCmdArg& arg3,const RooCmdArg& arg4,const RooCmdArg& arg5,
113 const RooCmdArg& arg6,const RooCmdArg& arg7,const RooCmdArg& arg8) : TNamed("mcstudy","mcstudy")
114
115{
116 // Stuff all arguments in a list
118 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
119 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
120 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
121 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
122
123 // Select the pdf-specific commands
124 RooCmdConfig pc("RooMCStudy::RooMCStudy(" + std::string(model.GetName()) + ")");
125
126 pc.defineObject("fitModel","FitModel",0,nullptr) ;
127 pc.defineSet("condObs","ProjectedObservables",0,nullptr) ;
128 pc.defineObject("protoData","PrototypeData",0,nullptr) ;
129 pc.defineSet("cPars","Constrain",0,nullptr) ;
130 pc.defineSet("extCons","ExternalConstraints",0,nullptr) ;
131 pc.defineInt("silence","Silence",0,0) ;
132 pc.defineInt("randProtoData","PrototypeData",0,0) ;
133 pc.defineInt("verboseGen","Verbose",0,0) ;
134 pc.defineInt("extendedGen","Extended",0,0) ;
135 pc.defineInt("binGenData","Binned",0,0) ;
136 pc.defineInt("dummy","FitOptArgs",0,0) ;
137
138 // Process and check varargs
139 pc.process(cmdList) ;
140 if (!pc.ok(true)) {
141 // WVE do something here
142 throw std::string("RooMCStudy::RooMCStudy() Error in parsing arguments passed to constructor") ;
143 return ;
144 }
145
146 // Save fit command options
147 if (pc.hasProcessed("FitOptArgs")) {
148 RooCmdArg* fitOptArg = static_cast<RooCmdArg*>(cmdList.FindObject("FitOptArgs")) ;
149 for (int i=0 ; i<fitOptArg->subArgs().GetSize() ;i++) {
150 _fitOptList.Add(new RooCmdArg(static_cast<RooCmdArg&>(*fitOptArg->subArgs().At(i)))) ;
151 }
152 }
153
154 // Decode command line arguments
155 _silence = pc.getInt("silence") ;
156 _verboseGen = pc.getInt("verboseGen") ;
157 _extendedGen = pc.getInt("extendedGen") ;
158 _binGenData = pc.getInt("binGenData") ;
159 _randProto = pc.getInt("randProtoData") ;
160
161 // Process constraints specifications
162 const RooArgSet* cParsTmp = pc.getSet("cPars") ;
163 const RooArgSet* extCons = pc.getSet("extCons") ;
164
165 auto cPars = std::make_unique<RooArgSet>();
166 if (cParsTmp) {
167 cPars->add(*cParsTmp) ;
168 }
169
170 // If constraints are specified, add to fit options
171 if (cPars) {
173 }
174 if (extCons) {
176 }
177
178 // Make list of all constraints and of the parameters they constrain
181 if (cPars) {
182 if (std::unique_ptr<RooArgSet> constraints{model.getAllConstraints(observables,*cPars,true)}) {
183 allConstraints.add(*constraints) ;
184 }
185 consPars.add(*cPars) ;
186 }
187 if (extCons) {
188 // External constraint p.d.f.s are not part of the model, so the parameters
189 // they constrain are found among their observables instead
190 allConstraints.add(*extCons) ;
191 RooArgSet params;
192 model.getParameters(&observables, params);
193 for (RooAbsArg const* con : *extCons) {
195 con->getObservables(&params, cparams);
196 consPars.add(cparams, /*silent=*/true) ;
197 }
198 }
199
200 // Construct constraint p.d.f
201 if (!allConstraints.empty()) {
202 _constrPdf = std::make_unique<RooProdPdf>("mcs_constr_prod","RooMCStudy constraints product",allConstraints);
203 _constrGenContext.reset(_constrPdf->genContext(consPars,nullptr,nullptr,_verboseGen));
204
206
207 coutI(Generation) << "RooMCStudy::RooMCStudy: INFO have pdf with constraints, will generate parameters from constraint pdf for each experiment" << std::endl ;
208 }
209
210
211 // Extract generator and fit models
212 _genModel = const_cast<RooAbsPdf*>(&model) ;
213 RooAbsPdf* fitModel = static_cast<RooAbsPdf*>(pc.getObject("fitModel",nullptr)) ;
214 _fitModel = fitModel ? fitModel : _genModel ;
215
216 // Extract conditional observables and prototype data
217 _genProtoData = static_cast<RooDataSet*>(pc.getObject("protoData",nullptr)) ;
218 if (auto condObs = pc.getSet("condObs",nullptr)) {
220 }
221
222 _dependents.add(observables) ;
223
226
228 oocoutW(_fitModel,Generation) << "RooMCStudy::RooMCStudy: WARNING Using generator option 'e' (Poisson distribution of #events) together " << std::endl
229 << " with a prototype dataset implies incomplete sampling or oversampling of proto data." << std::endl
230 << " Use option \"r\" to randomize prototype dataset order and thus to randomize" << std::endl
231 << " the set of over/undersampled prototype events for each generation cycle." << std::endl ;
232 }
233
235 if (!_binGenData) {
237 _genContext->attach(_genParams) ;
238 }
239
241
242 // Store list of parameters and save initial values separately
245
247
248 // Place holder for NLL
249 _nllVar = std::make_unique<RooRealVar>("NLL","-log(Likelihood)",0);
250
251 // Place holder for number of generated events
252 _ngenVar = std::make_unique<RooRealVar>("ngen","number of generated events",0);
253
254 // Create data set containing parameter values, errors and pulls
256 tmp2.add(*_nllVar) ;
257 tmp2.add(*_ngenVar) ;
258
259 // Mark all variable to store their errors in the dataset
260 tmp2.setAttribAll("StoreError",true) ;
261 tmp2.setAttribAll("StoreAsymError",true) ;
262 std::string fpdName;
263 if (_fitModel==_genModel) {
264 fpdName = "fitParData_" + std::string(_fitModel->GetName());
265 } else {
266 fpdName= "fitParData_" + std::string(_fitModel->GetName()) + "_" + std::string(_genModel->GetName());
267 }
268
269 _fitParData = std::make_unique<RooDataSet>(fpdName,"Fit Parameters DataSet",tmp2);
270 tmp2.setAttribAll("StoreError",false) ;
271 tmp2.setAttribAll("StoreAsymError",false) ;
272
273 _genParData = std::make_unique<RooDataSet>("genParData","Generated Parameters dataset",_genParams);
274
275 // Append proto variables to allDependents
276 if (_genProtoData) {
277 _allDependents.add(*_genProtoData->get(),true) ;
278 }
279
280 // Call module initializers
281 for (auto iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
282 bool ok = (*iter)->doInitializeInstance(*this) ;
283 if (!ok) {
284 oocoutE(_fitModel,Generation) << "RooMCStudy::ctor: removing study module " << (*iter)->GetName() << " from analysis chain because initialization failed" << std::endl ;
285 iter = _modList.erase(iter) ;
286 }
287 }
288
289}
290
291
292////////////////////////////////////////////////////////////////////////////////
293
299
300
301
302////////////////////////////////////////////////////////////////////////////////
303/// Insert given RooMCStudy add-on module to the processing chain
304/// of this MCStudy object
305
307{
308 module.doInitializeInstance(*this) ;
309 _modList.push_back(&module) ;
310}
311
312
313
314////////////////////////////////////////////////////////////////////////////////
315/// Run engine method. Generate and/or fit, according to flags, 'nSamples' samples of 'nEvtPerSample' events.
316/// If keepGenData is set, all generated data sets will be kept in memory and can be accessed
317/// later via genData().
318///
319/// When generating, the generator parameter values used for each sample are recorded in the
320/// dataset returned by genParDataSet(). When constraints are used and the run both generates
321/// and fits, the sampled parameter values are in addition merged into the fit parameter
322/// dataset as `<name>_gen` columns for each toy whose fit converged.
323///
324/// When generating, data sets will be written out in ascii form if the pattern string is supplied
325/// The pattern, which is a template for snprintf, should look something like "data/toymc_%04d.dat"
326/// and should contain one integer field that encodes the sample serial number.
327///
328/// When fitting only, data sets may optionally be read from ascii files, using the same file
329/// pattern.
330///
331
332bool RooMCStudy::run(bool doGenerate, bool DoFit, Int_t nSamples, Int_t nEvtPerSample, bool keepGenData, const char* asciiFilePat)
333{
335 if (_silence) {
336 oldLevel = RooMsgService::instance().globalKillBelow() ;
337 RooMsgService::instance().setGlobalKillBelow(RooFit::PROGRESS) ;
338 }
339
341 mod->initializeRun(nSamples) ;
342 }
343
344 if (DoFit && !doGenerate && _perExptGenParams) {
345 coutW(Generation) << "RooMCStudy::run: WARNING fitting previously generated samples in a separate run:"
346 " the per-toy sampled generator parameters are not merged into the fit parameter dataset,"
347 " so pulls are computed with respect to the initial parameter values instead of the sampled ones" << std::endl ;
348 }
349
350 int prescale = nSamples>100 ? int(nSamples/100) : 1 ;
351
352 // Generator parameter values of the toys whose fit converged, filled in the
353 // same order as _fitParData so that the two datasets can be merged after the
354 // loop. Only done when the parameters are sampled from constraint p.d.f.s:
355 // otherwise the values are the constant initial ones, and study modules like
356 // RooRandomizeParamMCSModule publish their own "<name>_gen" columns that
357 // must not be overwritten by the merge.
358 std::unique_ptr<RooDataSet> genParDataForMerge;
359 if (doGenerate && DoFit && _perExptGenParams && _genParData) {
360 genParDataForMerge = std::make_unique<RooDataSet>("genParDataForMerge","Generated Parameters dataset",*_genParData->get());
361 }
362
363 while(nSamples--) {
364
365 if (nSamples%prescale==0) {
366 oocoutP(_fitModel,Generation) << "RooMCStudy::run: " ;
367 if (doGenerate) ooccoutI(_fitModel,Generation) << "Generating " ;
368 if (doGenerate && DoFit) ooccoutI(_fitModel,Generation) << "and " ;
369 if (DoFit) ooccoutI(_fitModel,Generation) << "fitting " ;
370 ooccoutP(_fitModel,Generation) << "sample " << nSamples << std::endl ;
371 }
372
373 std::unique_ptr<RooAbsData> ownedGenSample;
374 _genSample = nullptr;
375 bool existingData = false ;
376 if (doGenerate) {
377 // Generate sample
378 int nEvt(nEvtPerSample) ;
379
380 // Reset generator parameters to initial values
382
383 // If constraints are present, sample generator values from constraints
384 if (_constrPdf) {
385 _genParams.assign(*std::unique_ptr<RooDataSet>{_constrGenContext->generate(1)}->get());
386 }
387
388 // Call module before-generation hook
390 mod->processBeforeGen(nSamples) ;
391 }
392
393 // Save the generator parameters used for this toy, including any
394 // modification applied by the study modules above
395 if (_genParData) {
396 _genParData->add(_genParams) ;
397 }
398
399 if (_binGenData) {
400
401 // Calculate the number of (extended) events for this run
402 if (_extendedGen) {
405 }
406
407 // Binned generation
408 ownedGenSample = std::unique_ptr<RooDataHist>{_genModel->generateBinned(_dependents,nEvt)};
409
410 } else {
411
412 // Calculate the number of (extended) events for this run
413 if (_extendedGen) {
416 }
417
418 // Optional randomization of protodata for this run
419 if (_randProto && _genProtoData && _genProtoData->numEntries()!=nEvt) {
420 oocoutI(_fitModel,Generation) << "RooMCStudy: (Re)randomizing event order in prototype dataset (Nevt=" << nEvt << ")" << std::endl ;
422 _genContext->setProtoDataOrder(newOrder) ;
423 delete[] newOrder ;
424 }
425
426 // Actual generation of events
427 if (nEvt>0) {
428 ownedGenSample = std::unique_ptr<RooAbsData>{_genContext->generate(nEvt)};
429 } else {
430 // Make empty dataset
431 ownedGenSample = std::make_unique<RooDataSet>("emptySample","emptySample",_dependents);
432 }
433 }
434
436
437 //} else if (asciiFilePat && &asciiFilePat) { //warning: the address of 'asciiFilePat' will always evaluate as 'true'
438 } else if (asciiFilePat) {
439
440 // Load sample from ASCII file
441 char asciiFile[1024] ;
442 snprintf(asciiFile,1024,asciiFilePat,nSamples) ;
444 ownedGenSample = std::unique_ptr<RooDataSet>{RooDataSet::read(asciiFile,depList,"q")};
446
447 } else {
448
449 // Load sample from internal list
450 _genSample = static_cast<RooDataSet*>(_genDataList.At(nSamples)) ;
452 if (!_genSample) {
453 oocoutW(_fitModel,Generation) << "RooMCStudy::run: WARNING: Sample #" << nSamples << " not loaded, skipping" << std::endl ;
454 continue ;
455 }
456 }
457
458 // Save number of generated events
459 _ngenVar->setVal(_genSample->sumEntries()) ;
460
461 // Call module between generation and fitting hook
463 mod->processBetweenGenAndFit(nSamples) ;
464 }
465
466 bool fitOk = true;
467 if (DoFit) fitOk = !fitSample(_genSample) ;
468
469 // Keep the generator parameters of this toy for merging into the fit
470 // parameter dataset. Only converged fits get an entry in _fitParData, so
471 // the toys with failed fits have to be skipped here as well. The values
472 // are taken from _genParData because the fit changes the parameters.
474 genParDataForMerge->add(*_genParData->get(_genParData->numEntries()-1)) ;
475 }
476
477 // Call module between generation and fitting hook
479 mod->processAfterFit(fitOk) ;
480 }
481
482 // Optionally write to ascii file
484 char asciiFile[1024] ;
485 snprintf(asciiFile,1024,asciiFilePat,nSamples) ;
486 if (RooDataSet* unbinnedData = dynamic_cast<RooDataSet*>(_genSample)) {
487 unbinnedData->write(asciiFile) ;
488 } else {
489 coutE(InputArguments) << "RooMCStudy::run(" << GetName() << ") ERROR: ASCII writing of binned datasets is not supported" << std::endl ;
490 }
491 }
492
493 // Add to list or delete
494 if (!existingData) {
495 if (keepGenData) {
496 _genDataList.Add(ownedGenSample.release()) ;
497 }
498 }
499 }
500
502 if (RooDataSet* auxData = mod->finalizeRun()) {
503 _fitParData->merge(auxData) ;
504 }
505 }
506
508
509 if (genParDataForMerge) {
510 // Append the generator parameter values as additional "<name>_gen"
511 // columns to the fit parameter dataset
512 for(RooAbsArg * arg : *genParDataForMerge->get()) {
513 genParDataForMerge->changeObservableName(arg->GetName(),(std::string(arg->GetName()) + "_gen").c_str());
514 }
515
516 _fitParData->merge(genParDataForMerge.get());
517 }
518
519 if (DoFit) calcPulls() ;
520
521 if (_silence) {
522 RooMsgService::instance().setGlobalKillBelow(oldLevel) ;
523 }
524
525 return false ;
526}
527
528
529
530
531
532
533////////////////////////////////////////////////////////////////////////////////
534/// Generate and fit 'nSamples' samples of 'nEvtPerSample' events.
535/// If keepGenData is set, all generated data sets will be kept in memory and can be accessed
536/// later via genData().
537///
538/// Data sets will be written out in ascii form if the pattern string is supplied.
539/// The pattern, which is a template for snprintf, should look something like "data/toymc_%04d.dat"
540/// and should contain one integer field that encodes the sample serial number.
541///
542
544{
545 // Clear any previous data in memory
546 _fitResList.Delete() ; // even though the fit results are owned by gROOT, we still want to scratch them here.
548 _fitParData->reset() ;
549 if (_genParData) _genParData->reset() ;
550
551 return run(true,true,nSamples,nEvtPerSample,keepGenData,asciiFilePat) ;
552}
553
554
555
556////////////////////////////////////////////////////////////////////////////////
557/// Generate 'nSamples' samples of 'nEvtPerSample' events.
558/// If keepGenData is set, all generated data sets will be kept in memory
559/// and can be accessed later via genData().
560///
561/// Data sets will be written out in ascii form if the pattern string is supplied.
562/// The pattern, which is a template for snprintf, should look something like "data/toymc_%04d.dat"
563/// and should contain one integer field that encodes the sample serial number.
564///
565
567{
568 // Clear any previous data in memory
570 if (_genParData) _genParData->reset() ;
571
572 return run(true,false,nSamples,nEvtPerSample,keepGenData,asciiFilePat) ;
573}
574
575
576
577////////////////////////////////////////////////////////////////////////////////
578/// Fit 'nSamples' datasets, which are read from ASCII files.
579///
580/// The ascii file pattern, which is a template for snprintf, should look something like "data/toymc_%04d.dat"
581/// and should contain one integer field that encodes the sample serial number.
582///
583
584bool RooMCStudy::fit(Int_t nSamples, const char* asciiFilePat)
585{
586 // Clear any previous data in memory
587 _fitResList.Delete() ; // even though the fit results are owned by gROOT, we still want to scratch them here.
588 _fitParData->reset() ;
589
590 return run(false,true,nSamples,0,false,asciiFilePat) ;
591}
592
593
594
595////////////////////////////////////////////////////////////////////////////////
596/// Fit 'nSamples' datasets, as supplied in 'dataSetList'
597///
598
600{
601 // Clear any previous data in memory
602 _fitResList.Delete() ; // even though the fit results are owned by gROOT, we still want to scratch them here.
604 _fitParData->reset() ;
605
606 // Load list of data sets
609 }
610
611 return run(false,true,nSamples,0,true,nullptr) ;
612}
613
614
615
616////////////////////////////////////////////////////////////////////////////////
617/// Reset all fit parameters to the initial model
618/// parameters at the time of the RooMCStudy constructor
619
624
625
626
627////////////////////////////////////////////////////////////////////////////////
628/// Internal function. Performs actual fit according to specifications
629
631{
632 // Optionally bin dataset before fitting
633 std::unique_ptr<RooDataHist> ownedDataHist;
635 if (_binGenData) {
637 _fitModel->getObservables(genSample->get(), depList);
638 ownedDataHist = std::make_unique<RooDataHist>(genSample->GetName(),genSample->GetTitle(),depList,*genSample) ;
639 data = ownedDataHist.get();
640 } else {
641 data = genSample ;
642 }
643
644 RooCmdArg save = RooFit::Save() ;
647
648 RooLinkedList fitOptList(_fitOptList) ;
649 fitOptList.Add(&save) ;
650 if (!_projDeps.empty()) {
651 fitOptList.Add(&condo) ;
652 }
653 fitOptList.Add(&plevel) ;
654 return _fitModel->fitTo(*data,fitOptList);
655}
656
657
658
659////////////////////////////////////////////////////////////////////////////////
660/// Redo fit on 'current' toy sample, or if genSample is not nullptr
661/// do fit on given sample instead
662
664{
665 if (!genSample) {
666 genSample = _genSample ;
667 }
668
669 std::unique_ptr<RooFitResult> fr;
670 if (genSample->sumEntries()>0) {
671 fr = std::unique_ptr<RooFitResult>{doFit(genSample)};
672 }
673
674 return RooFit::makeOwningPtr(std::move(fr));
675}
676
677
678
679////////////////////////////////////////////////////////////////////////////////
680/// Internal method. Fit given dataset with fit model. If fit
681/// converges (TMinuit status code zero) The fit results are appended
682/// to the fit results dataset
683///
684/// If the fit option "r" is supplied, the RooFitResult
685/// objects will always be saved, regardless of the
686/// fit status. RooFitResults objects can be retrieved
687/// later via fitResult().
688///
689
691{
692 // Reset all fit parameters to their initial values
694
695 // Perform actual fit
696 bool ok ;
697 std::unique_ptr<RooFitResult> fr;
698 if (genSample->sumEntries()>0) {
699 fr = std::unique_ptr<RooFitResult>{doFit(genSample)};
700 ok = (fr->status()==0) ;
701 } else {
702 ok = false ;
703 }
704
705 // If fit converged, store parameters and NLL
706 if (ok) {
707 _nllVar->setVal(fr->minNll()) ;
709 tmp.add(*_nllVar) ;
710 tmp.add(*_ngenVar) ;
711
712 _fitParData->add(tmp) ;
713 }
714
715 // Store fit result if requested by user
716 if (_fitOptList.FindObject("Save")) {
717 _fitResList.Add(fr.release()) ;
718 }
719
720 return !ok ;
721}
722
723
724
725////////////////////////////////////////////////////////////////////////////////
726/// Utility function to add fit result from external fit to this RooMCStudy
727/// and process its results through the standard RooMCStudy statistics gathering tools.
728/// This function allows users to run the toy MC generation and/or fitting
729/// in a distributed way and to collect and analyze the results in a RooMCStudy
730/// as if they were run locally.
731///
732/// This method is only functional if this RooMCStudy object is cleanm, i.e. it was not used
733/// to generate and/or fit any samples.
734
736{
737 if (!_canAddFitResults) {
738 oocoutE(_fitModel,InputArguments) << "RooMCStudy::addFitResult: ERROR cannot add fit results in current state" << std::endl ;
739 return true ;
740 }
741
742 // Transfer contents of fit result to fitParams ;
744
745 // If fit converged, store parameters and NLL
746 bool ok = (fr.status()==0) ;
747 if (ok) {
748 _nllVar->setVal(fr.minNll()) ;
750 tmp.add(*_nllVar) ;
751 tmp.add(*_ngenVar) ;
752 _fitParData->add(tmp) ;
753 }
754
755 // Store fit result if requested by user
756 if (_fitOptList.FindObject("Save")) {
757 _fitResList.Add((TObject*)&fr) ;
758 }
759
760 return false ;
761}
762
763
764
765////////////////////////////////////////////////////////////////////////////////
766/// Calculate the pulls for all fit parameters in
767/// the fit results data set, and add them to that dataset.
768
770{
771 for (auto it = _fitParams.begin(); it != _fitParams.end(); ++it) {
772 const auto par = static_cast<RooRealVar*>(*it);
773 _fitParData->addColumn(*std::unique_ptr<RooErrorVar>{par->errorVar()});
774
775 TString name(par->GetName());
776 TString title(par->GetTitle());
777 name.Append("pull") ;
778 title.Append(" Pull") ;
779
780 if (!par->hasError(false)) {
781 coutW(Generation) << "Fit parameter '" << par->GetName() << "' does not have an error."
782 " A pull distribution cannot be generated. This might be caused by the parameter being constant or"
783 " because the fits were not run." << std::endl;
784 continue;
785 }
786
787 // First look in fitParDataset to see if per-experiment generated value has been stored
788 auto genParOrig = static_cast<RooAbsReal*>(_fitParData->get()->find(Form("%s_gen",par->GetName())));
790
791 RooPullVar pull(name,title,*par,*genParOrig) ;
792 _fitParData->addColumn(pull,false) ;
793
794 } else {
795 // If not use fixed generator value
796 genParOrig = static_cast<RooAbsReal*>(_genInitParams.find(par->GetName()));
797
798 if (!genParOrig) {
799 std::size_t index = it - _fitParams.begin();
801 static_cast<RooAbsReal*>(_genInitParams[index]) :
802 nullptr;
803
804 if (genParOrig) {
805 coutW(Generation) << "The fit parameter '" << par->GetName() << "' is not in the model that was used to generate toy data. "
806 "The parameter '" << genParOrig->GetName() << "'=" << genParOrig->getVal() << " was found at the same position in the generator model."
807 " It will be used to compute pulls."
808 "\nIf this is not desired, the parameters of the generator model need to be renamed or reordered." << std::endl;
809 }
810 }
811
812 if (genParOrig) {
813 std::unique_ptr<RooAbsReal> genPar(static_cast<RooAbsReal*>(genParOrig->Clone("truth")));
814 RooPullVar pull(name,title,*par,*genPar);
815
816 _fitParData->addColumn(pull,false) ;
817 } else {
818 coutE(Generation) << "Cannot generate pull distribution for the fit parameter '" << par->GetName() << "'."
819 "\nNo similar parameter was found in the set of parameters that were used to generate toy data." << std::endl;
820 }
821 }
822 }
823}
824
825
826
827
828////////////////////////////////////////////////////////////////////////////////
829/// Return a RooDataSet containing the post-fit parameters of each toy cycle.
830/// This dataset also contains any additional output that was generated
831/// by study modules that were added to this RooMCStudy.
832/// By default, the two following variables are added (apart from fit parameters):
833/// - NLL: The value of the negative log-likelihood for each run.
834/// - ngen: Number of events generated for each run.
836{
837 if (_canAddFitResults) {
838 calcPulls() ;
840 }
841
842 return *_fitParData ;
843}
844
845
846
847////////////////////////////////////////////////////////////////////////////////
848/// Return an argset with the fit parameters for the given sample number
849///
850/// NB: The fit parameters are only stored for successful fits,
851/// thus the maximum sampleNum can be less that the number
852/// of generated samples and if so, the indices will
853/// be out of synch with genData() and fitResult()
854
856{
857 // Check if sampleNum is in range
858 if (sampleNum<0 || sampleNum>=_fitParData->numEntries()) {
859 oocoutE(_fitModel,InputArguments) << "RooMCStudy::fitParams: ERROR, invalid sample number: " << sampleNum << std::endl ;
860 return nullptr ;
861 }
862
863 return _fitParData->get(sampleNum) ;
864}
865
866
867
868////////////////////////////////////////////////////////////////////////////////
869/// Return the RooFitResult of the fit with the given run number.
870///
871/// \note Fit results are not saved by default. This requires passing `FitOptions(Save(), ...)`
872/// to the constructor.
874{
875 // Check if sampleNum is in range
877 oocoutE(_fitModel,InputArguments) << "RooMCStudy::fitResult: ERROR, invalid sample number: " << sampleNum << std::endl ;
878 return nullptr ;
879 }
880
881 // Retrieve fit result object
882 const RooFitResult* fr = static_cast<RooFitResult*>(_fitResList.At(sampleNum)) ;
883 if (fr) {
884 return fr ;
885 } else {
886 oocoutE(_fitModel,InputArguments) << "RooMCStudy::fitResult: ERROR, no fit result saved for sample "
887 << sampleNum << ", did you use the 'r; fit option?" << std::endl ;
888 }
889 return nullptr ;
890}
891
892
893
894////////////////////////////////////////////////////////////////////////////////
895/// Return the given generated dataset. This method will only return datasets
896/// if during the run cycle it was indicated that generator data should be saved.
897
899{
900 // Check that generated data was saved
901 if (_genDataList.GetSize()==0) {
902 oocoutE(_fitModel,InputArguments) << "RooMCStudy::genData() ERROR, generated data was not saved" << std::endl ;
903 return nullptr ;
904 }
905
906 // Check if sampleNum is in range
908 oocoutE(_fitModel,InputArguments) << "RooMCStudy::genData() ERROR, invalid sample number: " << sampleNum << std::endl ;
909 return nullptr ;
910 }
911
912 return static_cast<RooAbsData*>(_genDataList.At(sampleNum)) ;
913}
914
915namespace {
916
917// Fits a Gaussian p.d.f. to the distribution of the frame's plot variable in
918// the given dataset, overlays the fitted p.d.f. on the frame and adds a box
919// with the fitted mean and sigma. Implementation detail of RooMCStudy.
922{
924 gauss.plotOn(&frame);
925
926 // Instead of using paramOn() without command arguments to plot the fit
927 // parameters, we are building the parameter label ourselves for more
928 // flexibility and pass this together with an appropriate layout
929 // parametrization to paramOn().
930 const int sigDigits = 2;
931 const char *options = "ELU";
932 std::stringstream ss;
933 ss << "Fit parameters:\n"
934 << "#mu: " << mean.format(sigDigits, options) << "\n#sigma: " << sigma.format(sigDigits, options);
935 // We set the parameters constant to disable the default label. Still, we
936 // use param() on as a wrapper for the text box generation.
937 mean.setConstant(true);
938 sigma.setConstant(true);
939 gauss.paramOn(&frame, RooFit::Label(ss.str().c_str()), RooFit::Layout(0.60, 0.9, 0.9));
940}
941
942// Fits a Gaussian to the distribution of the variable plotted in the frame.
943// The initial values of the Gaussian parameters are taken from the moments of
944// the plotted distribution. Implementation detail of RooMCStudy::plotParam(),
945// which is also used by RooMCStudy::plotError() and RooMCStudy::plotNLL().
947{
948 // Build the Gaussian fit model for the plotted variable, then fit it and
949 // plot it. We have to use the RooWorkspace factory here, because different
950 // from the RooMCStudy class, the RooGaussian is not in RooFitCore.
951 RooWorkspace ws;
952 auto plotVar = frame.getPlotVar();
953 const std::string plotVarName = plotVar->GetName();
954 ws.import(*plotVar);
955 ws.factory("Gaussian::frameGauss(" + plotVarName + ", frameMean[0.0, 0.0, 1.0], frameSigma[1.0, 0.1, 10.0])");
956
957 RooRealVar &mean = *ws.var("frameMean");
958 RooRealVar &sigma = *ws.var("frameSigma");
959
960 // Seed the Gaussian with the moments of the plotted distribution, so that
961 // the fit also converges for distributions that are much narrower than the
962 // frame range. The values are set here and not passed via the factory
963 // string above, because the limited precision of the string representation
964 // would matter for variables with large absolute values.
965 auto const *dataVar = static_cast<RooRealVar const *>(fitParData.get()->find(plotVarName.c_str()));
966 if (!dataVar) {
967 oocoutE(nullptr, Plotting) << "RooMCStudy: no Gaussian fit for '" << plotVarName
968 << "', which is not in the dataset of fit parameters." << std::endl;
969 return;
970 }
971 const double dataMean = fitParData.mean(*dataVar);
972 const double dataSigma = fitParData.sigma(*dataVar);
973
974 // The mean is limited to the plotted range, extended if necessary such that
975 // it also covers the seed value.
976 mean.setRange(std::min(frame.GetXaxis()->GetXmin(), dataMean), std::max(frame.GetXaxis()->GetXmax(), dataMean));
977 mean.setVal(dataMean);
978
979 // Fall back to the frame range if the distribution has no spread at all,
980 // which can happen for example if there is only a single successful fit.
981 const double sigmaSeed =
982 dataSigma > 0.0 ? dataSigma : 0.05 * (frame.GetXaxis()->GetXmax() - frame.GetXaxis()->GetXmin());
983 sigma.setRange(0.01 * sigmaSeed, 10. * sigmaSeed);
984 sigma.setVal(sigmaSeed);
985
986 fitGaussAndPlotOnFrame(frame, fitParData, *ws.pdf("frameGauss"), mean, sigma);
987}
988
989// Fits a Gaussian to the pull distribution, plots the fit and prints the fit
990// parameters on the canvas. Implementation detail of RooMCStudy::plotPull().
992{
993 // Build the Gaussian fit mode for the pulls, then fit it and plot it. We
994 // have to use the RooWorkspace factory here, because different from the
995 // RooMCStudy class, the RooGaussian is not in RooFitCore.
996 RooWorkspace ws;
997 auto plotVar = frame.getPlotVar();
998 const std::string plotVarName = plotVar->GetName();
999 ws.import(*plotVar);
1000 ws.factory("Gaussian::pullGauss(" + plotVarName + ", pullMean[0.0, -10.0, 10.0], pullSigma[1.0, 0.1, 5.0])");
1001
1002 fitGaussAndPlotOnFrame(frame, fitParData, *ws.pdf("pullGauss"), *ws.var("pullMean"), *ws.var("pullSigma"));
1003}
1004
1005} // namespace
1006
1007
1008
1009////////////////////////////////////////////////////////////////////////////////
1010/// Plot the distribution of fitted values of a parameter. The parameter shown is the one from which the RooPlot
1011/// was created, e.g.
1012///
1013/// RooPlot* frame = param.frame(100,-10,10) ;
1014/// mcstudy.paramOn(frame,LineStyle(kDashed)) ;
1015///
1016/// Any named arguments passed to plotParamOn() are forwarded to the underlying plotOn() call
1017
1019 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1020{
1021 _fitParData->plotOn(frame,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1022 return frame ;
1023}
1024
1025
1026
1027////////////////////////////////////////////////////////////////////////////////
1028/// Plot the distribution of the fitted value of the given parameter on a newly created frame.
1029///
1030/// <table>
1031/// <tr><th> Optional arguments <th>
1032/// <tr><td> FrameRange(double lo, double hi) <td> Set range of frame to given specification
1033/// <tr><td> FrameBins(int bins) <td> Set default number of bins of frame to given number
1034/// <tr><td> Frame() <td> Pass supplied named arguments to RooAbsRealLValue::frame() function. See there
1035/// for list of allowed arguments
1036/// <tr><td> FitGauss(bool flag) <td> Add a gaussian fit to the frame
1037/// </table>
1038/// If no frame specifications are given, the AutoRange() feature will be used to set the range
1039/// Any other named argument is passed to the RooAbsData::plotOn() call. See that function for allowed options
1040
1042 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1043{
1044
1045 // Find parameter in fitParDataSet
1046 RooRealVar* param = static_cast<RooRealVar*>(_fitParData->get()->find(paramName)) ;
1047 if (!param) {
1048 oocoutE(_fitModel,InputArguments) << "RooMCStudy::plotParam: ERROR: no parameter defined with name " << paramName << std::endl ;
1049 return nullptr ;
1050 }
1051
1052 // Forward to implementation below
1053 return plotParam(*param,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1054}
1055
1056
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Plot the distribution of the fitted value of the given parameter on a newly created frame.
1060/// \copydetails RooMCStudy::plotParam(const char* paramName, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
1061/// const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1062
1064 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1065{
1066 // Stuff all arguments in a list
1068 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
1069 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
1070 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
1071 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
1072
1073 RooPlot* frame = makeFrameAndPlotCmd(param, cmdList) ;
1074 if (frame) {
1075
1076 // Pick up optional FitGauss command from list
1077 RooCmdConfig pc("RooMCStudy::plotParam(" + std::string(_genModel->GetName()) + ")");
1078 pc.defineInt("fitGauss","FitGauss",0,0) ;
1079 pc.allowUndefined() ;
1080 pc.process(cmdList) ;
1081 bool fitGauss=pc.getInt("fitGauss") ;
1082
1083 // Pass stripped command list to plotOn()
1085 _fitParData->plotOn(frame, cmdList) ;
1086
1087 // Add Gaussian fit if requested
1088 if (fitGauss) {
1089 fitGaussToFrame(*frame, *_fitParData);
1090 }
1091 }
1092
1093 return frame ;
1094}
1095
1096
1097
1098////////////////////////////////////////////////////////////////////////////////
1099/// Plot the distribution of the -log(L) values on a newly created frame.
1100///
1101/// <table>
1102/// <tr><th> Optional arguments <th>
1103/// <tr><td> FrameRange(double lo, double hi) <td> Set range of frame to given specification
1104/// <tr><td> FrameBins(int bins) <td> Set default number of bins of frame to given number
1105/// <tr><td> Frame() <td> Pass supplied named arguments to RooAbsRealLValue::frame() function. See there
1106/// for list of allowed arguments
1107/// <tr><td> FitGauss(bool flag) <td> Add a gaussian fit to the frame
1108/// </table>
1109///
1110/// If no frame specifications are given, the AutoRange() feature will be used to set the range.
1111/// Any other named argument is passed to the RooAbsData::plotOn() call. See that function for allowed options
1112
1114 const RooCmdArg& arg3, const RooCmdArg& arg4,
1115 const RooCmdArg& arg5, const RooCmdArg& arg6,
1116 const RooCmdArg& arg7, const RooCmdArg& arg8)
1117{
1119}
1120
1121
1122
1123////////////////////////////////////////////////////////////////////////////////
1124/// Plot the distribution of the fit errors for the specified parameter on a newly created frame.
1125///
1126/// <table>
1127/// <tr><th> Optional arguments <th>
1128/// <tr><td> FrameRange(double lo, double hi) <td> Set range of frame to given specification
1129/// <tr><td> FrameBins(int bins) <td> Set default number of bins of frame to given number
1130/// <tr><td> Frame() <td> Pass supplied named arguments to RooAbsRealLValue::frame() function. See there
1131/// for list of allowed arguments
1132/// <tr><td> FitGauss(bool flag) <td> Add a gaussian fit to the frame
1133/// </table>
1134///
1135/// If no frame specifications are given, the AutoRange() feature will be used to set a default range.
1136/// Any other named argument is passed to the RooAbsData::plotOn() call. See that function for allowed options.
1137
1139 const RooCmdArg& arg3, const RooCmdArg& arg4,
1140 const RooCmdArg& arg5, const RooCmdArg& arg6,
1141 const RooCmdArg& arg7, const RooCmdArg& arg8)
1142{
1143 if (_canAddFitResults) {
1144 calcPulls() ;
1146 }
1147
1148 std::unique_ptr<RooErrorVar> evar{param.errorVar()};
1149 std::unique_ptr<RooAbsArg> evar_rrv{evar->createFundamental()};
1150 RooPlot* frame = plotParam(static_cast<RooRealVar&>(*evar_rrv),arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1151
1152 // To make sure the frame has no dangling pointer to evar_rrv.
1154
1155 return frame ;
1156}
1157
1158
1159
1160////////////////////////////////////////////////////////////////////////////////
1161/// Plot the distribution of pull values for the specified parameter on a newly created frame. If asymmetric
1162/// errors are calculated in the fit (by MINOS) those will be used in the pull calculation.
1163///
1164/// If the parameters of the models for generation and fit differ, simple heuristics are used to find the
1165/// corresponding parameters:
1166/// - Parameters have the same name: They will be used to compute pulls.
1167/// - Parameters have different names: The position of the fit parameter in the set of fit parameters will be
1168/// computed. The parameter at the same position in the set of generator parameters will be used.
1169///
1170/// Further options:
1171/// <table>
1172/// <tr><th> Arguments <th> Effect
1173/// <tr><td> FrameRange(double lo, double hi) <td> Set range of frame to given specification
1174/// <tr><td> FrameBins(int bins) <td> Set default number of bins of frame to given number
1175/// <tr><td> Frame() <td> Pass supplied named arguments to RooAbsRealLValue::frame() function. See there
1176/// for list of allowed arguments
1177/// <tr><td> FitGauss(bool flag) <td> Add a gaussian fit to the frame
1178/// </table>
1179///
1180/// If no frame specifications are given, the AutoSymRange() feature will be used to set a default range.
1181/// Any other named argument is passed to the RooAbsData::plotOn(). See that function for allowed options.
1182///
1183/// If you want to have more control over the Gaussian fit to the pull
1184/// distribution, you can also do it after the call to plotPull():
1185///
1186/// ~~~ {.cpp}
1187/// RooPlot *frame = mcstudy->plotPull(myVariable, RooFit::Bins(40), RooFit::FitGauss(false));
1188/// RooRealVar pullMean("pullMean","Mean of pull",0,-10,10) ;
1189/// RooRealVar pullSigma("pullSigma","Width of pull",1,0.1,5) ;
1190/// pullMean.setPlotLabel("pull #mu"); // optional (to get nicer plot labels if you want)
1191/// pullSigma.setPlotLabel("pull #sigma"); // optional
1192/// RooGaussian pullGauss("pullGauss","Gaussian of pull", *frame->getPlotVar(), pullMean, pullSigma);
1193/// pullGauss.fitTo(const_cast<RooDataSet&>(mcstudy->fitParDataSet()),
1194/// RooFit::Minos(0), RooFit::PrintLevel(-1)) ;
1195/// pullGauss.plotOn(frame) ;
1196/// pullGauss.paramOn(frame, RooFit::Layout(0.65, 0.9, 0.9)); // optionally specify label position (xmin, xmax, ymax)
1197/// ~~~
1198
1200 const RooCmdArg& arg3, const RooCmdArg& arg4,
1201 const RooCmdArg& arg5, const RooCmdArg& arg6,
1202 const RooCmdArg& arg7, const RooCmdArg& arg8)
1203{
1204 // Stuff all arguments in a list
1206 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
1207 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
1208 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
1209 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
1210
1211 TString name(param.GetName());
1212 TString title(param.GetTitle());
1213 name.Append("pull") ; title.Append(" Pull") ;
1214 RooRealVar pvar(name,title,-100,100) ;
1215 pvar.setBins(100) ;
1216
1217
1218 RooPlot* frame = makeFrameAndPlotCmd(pvar, cmdList, true) ;
1219 if (frame) {
1220
1221 // Pick up optional FitGauss command from list
1222 RooCmdConfig pc("RooMCStudy::plotPull(" + std::string(_genModel->GetName()) + ")");
1223 pc.defineInt("fitGauss","FitGauss",0,0) ;
1224 pc.allowUndefined() ;
1225 pc.process(cmdList) ;
1226 bool fitGauss=pc.getInt("fitGauss") ;
1227
1228 // Pass stripped command list to plotOn()
1230 const bool success = _fitParData->plotOn(frame,cmdList) ;
1231
1232 if (!success) {
1233 coutF(Plotting) << "No pull distribution for the parameter '" << param.GetName() << "'. Check logs for errors." << std::endl;
1234 return frame;
1235 }
1236
1237 // Add Gaussian fit if requested
1238 if (fitGauss) {
1239 fitGaussToPulls(*frame, *_fitParData);
1240 }
1241
1242 // To make sure the frame has no dangling pointer to pvar.
1244 }
1245 return frame;
1246}
1247
1248
1249
1250////////////////////////////////////////////////////////////////////////////////
1251/// Internal function. Construct RooPlot from given parameter and modify the list of named
1252/// arguments 'cmdList' to only contain the plot arguments that should be forwarded to
1253/// RooAbsData::plotOn()
1254
1256{
1257 // Select the frame-specific commands
1258 RooCmdConfig pc("RooMCStudy::plotParam(" + std::string(_genModel->GetName()) + ")");
1259 pc.defineInt("nbins","Bins",0,0) ;
1260 pc.defineDouble("xlo","Range",0,0) ;
1261 pc.defineDouble("xhi","Range",1,0) ;
1262 pc.defineInt("dummy","FrameArgs",0,0) ;
1263 pc.defineMutex("Bins","FrameArgs") ;
1264 pc.defineMutex("Range","FrameArgs") ;
1265
1266 // Process and check varargs
1267 pc.allowUndefined() ;
1268 pc.process(cmdList) ;
1269 if (!pc.ok(true)) {
1270 return nullptr ;
1271 }
1272
1273 // Make frame according to specs
1274 Int_t nbins = pc.getInt("nbins") ;
1275 double xlo = pc.getDouble("xlo") ;
1276 double xhi = pc.getDouble("xhi") ;
1277 RooPlot* frame ;
1278
1279 if (pc.hasProcessed("FrameArgs")) {
1280 // Explicit frame arguments are given, pass them on
1281 RooCmdArg* frameArg = static_cast<RooCmdArg*>(cmdList.FindObject("FrameArgs")) ;
1282 frame = param.frame(frameArg->subArgs()) ;
1283 } else {
1284 // FrameBins, FrameRange or none are given, build custom frame command list
1285 RooCmdArg bins = RooFit::Bins(nbins) ;
1286 RooCmdArg range = RooFit::Range(xlo,xhi) ;
1289
1290 if (pc.hasProcessed("Bins")) frameCmdList.Add(&bins) ;
1291 if (pc.hasProcessed("Range")) {
1292 frameCmdList.Add(&range) ;
1293 } else {
1294 frameCmdList.Add(&autoRange) ;
1295 }
1296 frame = param.frame(frameCmdList) ;
1297 }
1298
1299 // Filter frame command from list and pass on to plotOn()
1300 RooCmdConfig::stripCmdList(cmdList,"FrameArgs,Bins,Range") ;
1301
1302 return frame ;
1303}
1304
1305
1306
1307////////////////////////////////////////////////////////////////////////////////
1308/// Create a RooPlot of the -log(L) distribution in the range lo-hi
1309/// with 'nBins' bins
1310
1311RooPlot* RooMCStudy::plotNLL(double lo, double hi, Int_t nBins)
1312{
1313 RooPlot* frame = _nllVar->frame(lo,hi,nBins) ;
1314
1315 _fitParData->plotOn(frame) ;
1316 return frame ;
1317}
1318
1319
1320
1321////////////////////////////////////////////////////////////////////////////////
1322/// Create a RooPlot of the distribution of the fitted errors of the given parameter.
1323/// The frame is created with a range [lo,hi] and plotted data will be binned in 'nbins' bins
1324
1325RooPlot* RooMCStudy::plotError(const RooRealVar& param, double lo, double hi, Int_t nbins)
1326{
1327 if (_canAddFitResults) {
1328 calcPulls() ;
1330 }
1331
1332 std::unique_ptr<RooErrorVar> evar{param.errorVar()};
1333 RooPlot* frame = evar->frame(lo,hi,nbins) ;
1334 _fitParData->plotOn(frame) ;
1335
1336 return frame ;
1337}
1338
1339
1340
1341////////////////////////////////////////////////////////////////////////////////
1342/// Create a RooPlot of the pull distribution for the given
1343/// parameter. The range lo-hi is plotted in nbins. If fitGauss is
1344/// set, an unbinned ML fit of the distribution to a Gaussian p.d.f
1345/// is performed. The fit result is overlaid on the returned RooPlot
1346/// and a box with the fitted mean and sigma is added.
1347///
1348/// If the parameters of the models for generation and fit differ, simple heuristics are used to find the
1349/// corresponding parameters:
1350/// - Parameters have the same name: They will be used to compute pulls.
1351/// - Parameters have different names: The position of the fit parameter in the set of fit parameters will be
1352/// computed. The parameter at the same position in the set of generator parameters will be used.
1353
1354RooPlot* RooMCStudy::plotPull(const RooRealVar& param, double lo, double hi, Int_t nbins, bool fitGauss)
1355{
1356 if (_canAddFitResults) {
1357 calcPulls() ;
1359 }
1360
1361 TString name(param.GetName());
1362 TString title(param.GetTitle());
1363 name.Append("pull") ; title.Append(" Pull") ;
1364 RooRealVar pvar(name,title,lo,hi) ;
1365 pvar.setBins(nbins) ;
1366
1367 RooPlot* frame = pvar.frame() ;
1368 const bool success = _fitParData->plotOn(frame);
1369
1370 if (!success) {
1371 coutF(Plotting) << "No pull distribution for the parameter '" << param.GetName() << "'. Check logs for errors." << std::endl;
1372 return frame;
1373 }
1374
1375 if (fitGauss) {
1376 fitGaussToPulls(*frame, *_fitParData);
1377 }
1378
1379 return frame ;
1380}
1381
1382
1383////////////////////////////////////////////////////////////////////////////////
1384/// If one of the TObject we have a referenced to is deleted, remove the
1385/// reference.
1386
1388{
1392 if (_ngenVar.get() == obj) _ngenVar.reset();
1393
1394 if (_fitParData) _fitParData->RecursiveRemove(obj);
1395 if (_fitParData.get() == obj) _fitParData.reset();
1396
1397 if (_genParData) _genParData->RecursiveRemove(obj);
1398 if (_genParData.get() == obj) _genParData.reset();
1399}
1400
#define coutI(a)
#define oocoutW(o, a)
#define coutW(a)
#define coutF(a)
#define oocoutE(o, a)
#define oocoutI(o, a)
#define coutE(a)
#define ooccoutI(o, a)
#define ooccoutP(o, a)
#define oocoutP(o, a)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
char name[80]
Definition TGX11.cxx:142
#define hi
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:76
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
const_iterator end() const
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
Storage_t::size_type size() const
const_iterator begin() const
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:55
virtual double sumEntries() const =0
Return effective number of entries in dataset, i.e., sum all weights.
virtual const RooArgSet * get() const
Definition RooAbsData.h:99
Base class for add-on modules to RooMCStudy that can perform additional calculations on each generate...
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:32
virtual double expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
Int_t * randomizeProtoOrder(Int_t nProto, Int_t nGen, bool resample=false) const
Return lookup table with randomized order for nProto prototype events.
RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={}, const RooCmdArg &arg10={}) const override
Helper calling plotOn(RooPlot*, RooLinkedList&) const.
Definition RooAbsPdf.h:116
RooFit::OwningPtr< RooFitResult > fitTo(RooAbsData &data, CmdArgs_t const &... cmdArgs)
Fit PDF to given dataset.
Definition RooAbsPdf.h:149
virtual RooPlot * paramOn(RooPlot *frame, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Add a box with parameter values (and errors) to the specified frame.
virtual RooFit::OwningPtr< RooDataHist > generateBinned(const RooArgSet &whatVars, double nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}) const
As RooAbsPdf::generateBinned(const RooArgSet&, const RooCmdArg&,const RooCmdArg&, const RooCmdArg&,...
Definition RooAbsPdf.h:102
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool verbose=false) const
Interface function to create a generator context from a p.d.f.
RooPlot * frame(const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create a new RooPlot on the heap with a drawing frame initialized for this object,...
void setConstant(bool value=true)
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:159
Named container for two doubles, two integers two object points and three string pointers that can be...
Definition RooCmdArg.h:26
TObject * Clone(const char *newName=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooCmdArg.h:58
Configurable parser for RooCmdArg named arguments.
void defineMutex(const char *head, Args_t &&... tail)
Define arguments where any pair is mutually exclusive.
bool process(const RooCmdArg &arg)
Process given RooCmdArg.
bool hasProcessed(const char *cmdName) const
Return true if RooCmdArg with name 'cmdName' has been processed.
double getDouble(const char *name, double defaultValue=0.0) const
Return double property registered with name 'name'.
bool defineDouble(const char *name, const char *argName, int doubleNum, double defValue=0.0)
Define double property name 'name' mapped to double in slot 'doubleNum' in RooCmdArg with name argNam...
static void stripCmdList(RooLinkedList &cmdList, const char *cmdsToPurge)
Utility function that strips command names listed (comma separated) in cmdsToPurge from cmdList.
RooArgSet * getSet(const char *name, RooArgSet *set=nullptr) const
Return RooArgSet property registered with name 'name'.
bool defineSet(const char *name, const char *argName, int setNum, const RooArgSet *set=nullptr)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
bool ok(bool verbose) const
Return true of parsing was successful.
bool defineObject(const char *name, const char *argName, int setNum, const TObject *obj=nullptr, bool isArray=false)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
bool defineInt(const char *name, const char *argName, int intNum, int defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
void allowUndefined(bool flag=true)
If flag is true the processing of unrecognized RooCmdArgs is not considered an error.
int getInt(const char *name, int defaultValue=0) const
Return integer property registered with name 'name'.
TObject * getObject(const char *name, TObject *obj=nullptr) const
Return TObject property registered with name 'name'.
Container class to hold unbinned data.
Definition RooDataSet.h:32
static RooDataSet * read(const char *filename, const RooArgList &variables, const char *opts="", const char *commonPath="", const char *indexCatName=nullptr)
Read data from a text file and create a dataset from it.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
const RooArgList & floatParsFinal() const
Return list of floating parameters after fit.
Int_t status() const
Return MINUIT status code.
double minNll() const
Return minimized -log(L) value.
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
void RecursiveRemove(TObject *obj) override
If one of the TObject we have a referenced to is deleted, remove the reference.
void Delete(Option_t *o=nullptr) override
Remove all elements in collection and delete all elements NB: Collection does not own elements,...
virtual void Add(TObject *arg)
TObject * FindObject(const char *name) const override
Return pointer to object with given name.
bool addFitResult(const RooFitResult &fr)
Utility function to add fit result from external fit to this RooMCStudy and process its results throu...
RooPlot * plotParam(const RooRealVar &param, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Plot the distribution of the fitted value of the given parameter on a newly created frame.
RooAbsData * _genSample
Currently generated sample.
Definition RooMCStudy.h:115
RooPlot * makeFrameAndPlotCmd(const RooRealVar &param, RooLinkedList &cmdList, bool symRange=false) const
Internal function.
RooArgSet _projDeps
List of projected dependents in fit.
Definition RooMCStudy.h:121
RooArgSet _genParams
List of actual generator parameters.
Definition RooMCStudy.h:119
const RooArgSet * fitParams(Int_t sampleNum) const
Return an argset with the fit parameters for the given sample number.
void calcPulls()
Calculate the pulls for all fit parameters in the fit results data set, and add them to that dataset.
~RooMCStudy() override
RooArgSet _dependents
List of dependents.
Definition RooMCStudy.h:126
bool _verboseGen
Verbose generation?
Definition RooMCStudy.h:145
std::list< RooAbsMCStudyModule * > _modList
List of additional study modules ;.
Definition RooMCStudy.h:149
std::unique_ptr< RooDataSet > _genParData
Definition RooMCStudy.h:136
RooArgSet _genInitParams
List of original generator parameters.
Definition RooMCStudy.h:118
TList _fitResList
Definition RooMCStudy.h:135
double _nExpGen
Definition RooMCStudy.h:141
bool fitSample(RooAbsData *genSample)
Internal method.
RooPlot * plotNLL(const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Plot the distribution of the -log(L) values on a newly created frame.
std::unique_ptr< RooDataSet > _fitParData
Definition RooMCStudy.h:137
bool generate(Int_t nSamples, Int_t nEvtPerSample=0, bool keepGenData=false, const char *asciiFilePat=nullptr)
Generate 'nSamples' samples of 'nEvtPerSample' events.
bool _extendedGen
Definition RooMCStudy.h:139
const RooDataSet * _genProtoData
Generator prototype data set.
Definition RooMCStudy.h:120
bool _canAddFitResults
Allow adding of external fit results?
Definition RooMCStudy.h:144
const RooFitResult * fitResult(Int_t sampleNum) const
Return the RooFitResult of the fit with the given run number.
RooFit::OwningPtr< RooFitResult > doFit(RooAbsData *genSample)
Internal function. Performs actual fit according to specifications.
std::unique_ptr< RooAbsGenContext > _constrGenContext
Generator context for constraints p.d.f.
Definition RooMCStudy.h:124
bool _perExptGenParams
Do generation parameter change per event?
Definition RooMCStudy.h:146
bool _binGenData
Definition RooMCStudy.h:140
bool _silence
Silent running mode?
Definition RooMCStudy.h:147
RooPlot * plotParamOn(RooPlot *frame, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Plot the distribution of fitted values of a parameter.
RooArgSet _fitParams
List of actual fit parameters.
Definition RooMCStudy.h:130
RooPlot * plotError(const RooRealVar &param, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Plot the distribution of the fit errors for the specified parameter on a newly created frame.
std::unique_ptr< RooAbsGenContext > _genContext
Generator context.
Definition RooMCStudy.h:117
RooMCStudy(const RooAbsPdf &model, const RooArgSet &observables, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Construct Monte Carlo Study Manager.
RooFit::OwningPtr< RooFitResult > refit(RooAbsData *genSample=nullptr)
Redo fit on 'current' toy sample, or if genSample is not nullptr do fit on given sample instead.
RooAbsData * genData(Int_t sampleNum) const
Return the given generated dataset.
void RecursiveRemove(TObject *obj) override
If one of the TObject we have a referenced to is deleted, remove the reference.
RooAbsPdf * _genModel
Generator model.
Definition RooMCStudy.h:116
const RooDataSet & fitParDataSet()
Return a RooDataSet containing the post-fit parameters of each toy cycle.
std::unique_ptr< RooRealVar > _nllVar
Definition RooMCStudy.h:131
RooLinkedList _fitOptList
Definition RooMCStudy.h:138
std::unique_ptr< RooAbsPdf > _constrPdf
Constraints p.d.f.
Definition RooMCStudy.h:123
RooArgSet _allDependents
List of generate + prototype dependents.
Definition RooMCStudy.h:127
bool run(bool generate, bool fit, Int_t nSamples, Int_t nEvtPerSample, bool keepGenData, const char *asciiFilePat)
Run engine method.
void resetFitParams()
Reset all fit parameters to the initial model parameters at the time of the RooMCStudy constructor.
RooAbsPdf * _fitModel
Fit model.
Definition RooMCStudy.h:128
bool fit(Int_t nSamples, const char *asciiFilePat)
Fit 'nSamples' datasets, which are read from ASCII files.
bool generateAndFit(Int_t nSamples, Int_t nEvtPerSample=0, bool keepGenData=false, const char *asciiFilePat=nullptr)
Generate and fit 'nSamples' samples of 'nEvtPerSample' events.
RooPlot * plotPull(const RooRealVar &param, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Plot the distribution of pull values for the specified parameter on a newly created frame.
TList _genDataList
Definition RooMCStudy.h:134
bool _randProto
Definition RooMCStudy.h:142
void addModule(RooAbsMCStudyModule &module)
Insert given RooMCStudy add-on module to the processing chain of this MCStudy object.
RooArgSet _fitInitParams
List of initial values of fit parameters.
Definition RooMCStudy.h:129
std::unique_ptr< RooRealVar > _ngenVar
Definition RooMCStudy.h:132
static RooMsgService & instance()
Return reference to singleton instance.
Plot frame and a container for graphics objects within that frame.
Definition RooPlot.h:43
RooAbsRealLValue * getPlotVar() const
Definition RooPlot.h:137
TAxis * GetXaxis() const
Definition RooPlot.cxx:1228
void createInternalPlotVarClone()
Replaces the pointer to the plot variable with a pointer to a clone of the plot variable that is owne...
Definition RooPlot.cxx:1401
Represents the pull of a measurement w.r.t.
Definition RooPullVar.h:24
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition RooRandom.cxx:47
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void setVal(double value) override
Set value of variable to 'value'.
void setRange(const char *name, double min, double max, bool shared=true)
Set a fit or plotting range.
RooErrorVar * errorVar() const
Return a RooAbsRealLValue representing the error associated with this variable.
std::string format(const RooCmdArg &formatArg) const
Format contents of RooRealVar for pretty printing on RooPlot parameter boxes.
Persistable container for RooFit projects.
RooAbsPdf * pdf(RooStringView name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
RooFactoryWSTool & factory()
Return instance to factory tool.
RooRealVar * var(RooStringView name) const
Retrieve real-valued variable (RooRealVar) with given name. A null pointer is returned if not found.
bool import(const RooAbsArg &arg, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={})
Import a RooAbsArg object, e.g.
Double_t GetXmax() const
Definition TAxis.h:142
Double_t GetXmin() const
Definition TAxis.h:141
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
A doubly linked list.
Definition TList.h:38
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:894
void Add(TObject *obj) override
Definition TList.h:81
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:600
TObject * At(Int_t idx) const override
Returns the object at position idx. Returns 0 if idx is out of range.
Definition TList.cxx:487
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Mother of all ROOT objects.
Definition TObject.h:42
Basic string class.
Definition TString.h:137
TString & Append(const char *cs)
Definition TString.h:582
RooCmdArg AutoRange(const RooAbsData &data, double marginFactor=0.1)
RooCmdArg Label(const char *str)
RooCmdArg AutoSymRange(const RooAbsData &data, double marginFactor=0.1)
RooCmdArg Bins(Int_t nbin)
RooCmdArg Layout(double xmin, double xmax=0.99, double ymin=0.95)
RooCmdArg Constrain(const RooArgSet &params)
RooCmdArg Save(bool flag=true)
RooCmdArg ExternalConstraints(const RooArgSet &constraintPdfs)
RooCmdArg Minos(bool flag=true)
RooCmdArg PrintLevel(Int_t code)
RooCmdArg ConditionalObservables(Args_t &&... argsOrArgSet)
Create a RooCmdArg to declare conditional observables.
RooCmdArg Range(const char *rangeName, bool adjustNorm=true)
const Double_t sigma
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
Definition Config.h:35
MsgLevel
Verbosity level for RooMsgService::StreamConfig in RooMsgService.
OwningPtr< T > makeOwningPtr(std::unique_ptr< T > &&ptr)
Internal helper to turn a std::unique_ptr<T> into an OwningPtr.
Definition Config.h:40