Logo ROOT  
Reference Guide
RooAbsPdf.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/** \class RooAbsPdf
19 \ingroup Roofitcore
20
21## RooAbsPdf, the base class of all PDFs
22
23RooAbsPdf is the abstract interface for all probability density
24functions. The class provides hybrid analytical/numerical
25normalization for its implementations, error tracing and a MC
26generator interface.
27
28### A Minimal PDF Implementation
29
30A minimal implementation of a PDF class derived from RooAbsPdf
31should override the `evaluate()` function. This function should
32return the PDF's value (which does not need to be normalised).
33
34
35#### Normalization/Integration
36
37Although the normalization of a PDF is an integral part of a
38probability density function, normalization is treated separately
39in RooAbsPdf. The reason is that a RooAbsPdf object is more than a
40PDF: it can be a building block for a more complex, composite PDF
41if any of its variables are functions instead of variables. In
42such cases the normalization of the composite may not be simply the
43integral over the dependents of the top level PDF as these are
44functions with potentially non-trivial Jacobian terms themselves.
45\note Therefore, no explicit attempt should be made to normalize the
46function output in evaluate(). In particular, normalisation constants
47can be omitted to speed up the function evaluations, and included later
48in the integration of the PDF (see below), which is called rarely in
49comparison to the `evaluate()` function.
50
51In addition, RooAbsPdf objects do not have a static concept of what
52variables are parameters and what variables are dependents (which
53need to be integrated over for a correct PDF normalization).
54Instead, the choice of normalization is always specified each time a
55normalized value is requested from the PDF via the getVal()
56method.
57
58RooAbsPdf manages the entire normalization logic of each PDF with
59help of a RooRealIntegral object, which coordinates the integration
60of a given choice of normalization. By default, RooRealIntegral will
61perform a fully numeric integration of all dependents. However,
62PDFs can advertise one or more (partial) analytical integrals of
63their function, and these will be used by RooRealIntegral, if it
64determines that this is safe (i.e. no hidden Jacobian terms,
65multiplication with other PDFs that have one or more dependents in
66commen etc).
67
68#### Implementing analytical integrals
69To implement analytical integrals, two functions must be implemented. First,
70
71```
72Int_t getAnalyticalIntegral(const RooArgSet& integSet, RooArgSet& anaIntSet)
73```
74should return the analytical integrals that are supported. `integSet`
75is the set of dependents for which integration is requested. The
76function should copy the subset of dependents it can analytically
77integrate to `anaIntSet`, and return a unique identification code for
78this integration configuration. If no integration can be
79performed, zero should be returned. Second,
80
81```
82Double_t analyticalIntegral(Int_t code)
83```
84
85implements the actual analytical integral(s) advertised by
86`getAnalyticalIntegral()`. This function will only be called with
87codes returned by `getAnalyticalIntegral()`, except code zero.
88
89The integration range for each dependent to be integrated can
90be obtained from the dependent's proxy functions `min()` and
91`max()`. Never call these proxy functions for any proxy not known to
92be a dependent via the integration code. Doing so may be
93ill-defined, e.g. in case the proxy holds a function, and will
94trigger an assert. Integrated category dependents should always be
95summed over all of their states.
96
97
98
99### Direct generation of observables
100
101Distributions for any PDF can be generated with the accept/reject method,
102but for certain PDFs, more efficient methods may be implemented. To
103implement direct generation of one or more observables, two
104functions need to be implemented, similar to those for analytical
105integrals:
106
107```
108Int_t getGenerator(const RooArgSet& generateVars, RooArgSet& directVars)
109```
110and
111```
112void generateEvent(Int_t code)
113```
114
115The first function advertises observables, for which distributions can be generated,
116similar to the way analytical integrals are advertised. The second
117function implements the actual generator for the advertised observables.
118
119The generated dependent values should be stored in the proxy
120objects. For this, the assignment operator can be used (i.e. `xProxy
121= 3.0` ). Never call assign to any proxy not known to be a dependent
122via the generation code. Doing so may be ill-defined, e.g. in case
123the proxy holds a function, and will trigger an assert.
124
125
126### Batched function evaluations (Advanced usage)
127
128To speed up computations with large numbers of data events in unbinned fits,
129it is beneficial to override `evaluateSpan()`. Like this, large spans of
130computations can be done, without having to call `evaluate()` for each single data event.
131`evaluateSpan()` should execute the same computation as `evaluate()`, but it
132may choose an implementation that is capable of SIMD computations.
133If evaluateSpan is not implemented, the classic and slower `evaluate()` will be
134called for each data event.
135*/
136
137#include "RooAbsPdf.h"
138
139#include "RooFit.h"
140#include "RooMsgService.h"
141#include "RooDataSet.h"
142#include "RooArgSet.h"
143#include "RooArgProxy.h"
144#include "RooRealProxy.h"
145#include "RooRealVar.h"
146#include "RooGenContext.h"
147#include "RooBinnedGenContext.h"
148#include "RooPlot.h"
149#include "RooCurve.h"
150#include "RooNLLVar.h"
151#include "RooCategory.h"
152#include "RooNameReg.h"
153#include "RooCmdConfig.h"
154#include "RooGlobalFunc.h"
155#include "RooAddition.h"
156#include "RooRandom.h"
157#include "RooNumIntConfig.h"
158#include "RooProjectedPdf.h"
159#include "RooCustomizer.h"
160#include "RooConstraintSum.h"
161#include "RooParamBinning.h"
162#include "RooNumCdf.h"
163#include "RooFitResult.h"
164#include "RooNumGenConfig.h"
165#include "RooCachedReal.h"
166#include "RooXYChi2Var.h"
167#include "RooChi2Var.h"
168#include "RooMinimizer.h"
169#include "RooRealIntegral.h"
170#include "RooWorkspace.h"
171#include "RooNaNPacker.h"
172#include "RooHelpers.h"
173#include "RooBatchCompute.h"
174#include "RooFormulaVar.h"
175
176#include "TClass.h"
177#include "TMath.h"
178#include "TPaveText.h"
179#include "TList.h"
180#include "TMatrixD.h"
181#include "TMatrixDSym.h"
182#include "Math/CholeskyDecomp.h"
183#include "RooDerivative.h"
184
185#include <algorithm>
186#include <iostream>
187#include <string>
188#include <cmath>
189#include <stdexcept>
190
191using namespace std;
192
194
196
198
199
202
203////////////////////////////////////////////////////////////////////////////////
204/// Default constructor
205
206RooAbsPdf::RooAbsPdf() : _norm(0), _normSet(0), _specGeneratorConfig(0)
207{
208 _errorCount = 0 ;
209 _negCount = 0 ;
210 _rawValue = 0 ;
212 _traceCount = 0 ;
213}
214
215
216
217////////////////////////////////////////////////////////////////////////////////
218/// Constructor with name and title only
219
220RooAbsPdf::RooAbsPdf(const char *name, const char *title) :
221 RooAbsReal(name,title), _norm(0), _normSet(0), _normMgr(this,10), _selectComp(kTRUE), _specGeneratorConfig(0)
222{
224 setTraceCounter(0) ;
225}
226
227
228
229////////////////////////////////////////////////////////////////////////////////
230/// Constructor with name, title, and plot range
231
232RooAbsPdf::RooAbsPdf(const char *name, const char *title,
233 Double_t plotMin, Double_t plotMax) :
234 RooAbsReal(name,title,plotMin,plotMax), _norm(0), _normSet(0), _normMgr(this,10), _selectComp(kTRUE), _specGeneratorConfig(0)
235{
237 setTraceCounter(0) ;
238}
239
240
241
242////////////////////////////////////////////////////////////////////////////////
243/// Copy constructor
244
245RooAbsPdf::RooAbsPdf(const RooAbsPdf& other, const char* name) :
246 RooAbsReal(other,name), _norm(0), _normSet(0),
247 _normMgr(other._normMgr,this), _selectComp(other._selectComp), _normRange(other._normRange)
248{
251
252 if (other._specGeneratorConfig) {
254 } else {
256 }
257}
258
259
260
261////////////////////////////////////////////////////////////////////////////////
262/// Destructor
263
265{
267}
268
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Return current value, normalized by integrating over
273/// the observables in `nset`. If `nset` is 0, the unnormalized value
274/// is returned. All elements of `nset` must be lvalues.
275///
276/// Unnormalized values are not cached.
277/// Doing so would be complicated as `_norm->getVal()` could
278/// spoil the cache and interfere with returning the cached
279/// return value. Since unnormalized calls are typically
280/// done in integration calls, there is no performance hit.
281
283{
284
285 // Special handling of case without normalization set (used in numeric integration of pdfs)
286 if (!nset) {
287 RooArgSet* tmp = _normSet ;
288 _normSet = 0 ;
289 Double_t val = evaluate() ;
290 _normSet = tmp ;
291
292 return TMath::IsNaN(val) ? 0. : val;
293 }
294
295
296 // Process change in last data set used
297 Bool_t nsetChanged(kFALSE) ;
298 if (nset!=_normSet || _norm==0) {
299 nsetChanged = syncNormalization(nset) ;
300 }
301
302 // Return value of object. Calculated if dirty, otherwise cached value is returned.
303 if (isValueDirty() || nsetChanged || _norm->isValueDirty()) {
304
305 // Evaluate numerator
306 const double rawVal = evaluate();
307
308 // Evaluate denominator
309 const double normVal = _norm->getVal();
310
311 if (normVal < 0. || (normVal == 0. && rawVal != 0)) {
312 //Unreasonable normalisations. A zero integral can be tolerated if the function vanishes, though.
313 const std::string msg = "p.d.f normalization integral is zero or negative: " + std::to_string(normVal);
314 logEvalError(msg.c_str());
316 return _value = RooNaNPacker::packFloatIntoNaN(-normVal + (rawVal < 0. ? -rawVal : 0.));
317 }
318
319 if (rawVal < 0.) {
320 logEvalError(Form("p.d.f value is less than zero (%f), trying to recover", rawVal));
322 return _value = RooNaNPacker::packFloatIntoNaN(-rawVal);
323 }
324
325 if (TMath::IsNaN(rawVal)) {
326 logEvalError("p.d.f value is Not-a-Number");
328 return _value = rawVal;
329 }
330
331 _value = (rawVal == 0. && normVal == 0.) ? 0. : rawVal / normVal;
332
334 }
335
336 return _value ;
337}
338
339
340////////////////////////////////////////////////////////////////////////////////
341/// Compute batch of values for given input data, and normalise by integrating over
342/// the observables in `normSet`. Store result in `evalData`, and return a span pointing to
343/// it.
344/// This uses evaluateSpan() to perform an (unnormalised) computation of data points. This computation
345/// is finalised by normalising the bare values, and by checking for computation errors.
346/// Derived classes should override evaluateSpan() to reach maximal performance.
347///
348/// \param[in,out] evalData Object holding data that should be used in computations. Results are also stored here.
349/// \param[in] normSet If not nullptr, normalise results by integrating over
350/// the variables in this set. The normalisation is only computed once, and applied
351/// to the full batch.
352/// \return RooSpan with probabilities. The memory of this span is owned by `evalData`.
353/// \see RooAbsReal::getValues().
355 auto item = evalData.spans.find(this);
356 if (item != evalData.spans.end()) {
357 return item->second;
358 }
359
360 auto outputs = evaluateSpan(evalData, normSet);
361 assert(evalData.spans.count(this) > 0);
362
363 if (normSet != nullptr) {
364 if (normSet != _normSet || _norm == nullptr) {
365 syncNormalization(normSet);
366 }
367 // Evaluate denominator
368 // In most cases, the integral will be a scalar. But it can still happen
369 // that the integral is a vector, for example in a conditional fit where
370 // pdf is parametrized by another observable that is also a batch. That's
371 // why we have to use the batch interface also for the integral.
372 auto const& normVals = _norm->getValues(evalData);
373
374 if(normVals.size() > 1) {
375 for(std::size_t i = 0; i < outputs.size(); ++i) {
376 if (normVals[i] < 0. || (normVals[i] == 0. && outputs[i] != 0)) {
377 logEvalError(Form("p.d.f normalization integral is zero or negative."
378 "\n\tInt(%s) = %f", GetName(), normVals[i]));
379 }
380 if(normVals[i] != 1. && normVals[i] > 0.) {
381 outputs[i] /= normVals[i];
382 }
383 }
384
385 } else {
386 const double normVal = normVals[0];
387 if (normVal < 0.
388 || (normVal == 0. && std::any_of(outputs.begin(), outputs.end(), [](double val){return val != 0;}))) {
389 logEvalError(Form("p.d.f normalization integral is zero or negative."
390 "\n\tInt(%s) = %f", GetName(), normVal));
391 }
392
393 if (normVal != 1. && normVal > 0.) {
394 const double invNorm = 1./normVal;
395 for (double& val : outputs) { //CHECK_VECTORISE
396 val *= invNorm;
397 }
398 }
399 }
400 }
401
402 return outputs;
403}
404
405////////////////////////////////////////////////////////////////////////////////
406/// Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further information)
407///
408/// This function applies the normalization specified by 'normSet' to the integral returned
409/// by RooAbsReal::analyticalIntegral(). The passthrough scenario (code=0) is also changed
410/// to return a normalized answer
411
412Double_t RooAbsPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
413{
414 cxcoutD(Eval) << "RooAbsPdf::analyticalIntegralWN(" << GetName() << ") code = " << code << " normset = " << (normSet?*normSet:RooArgSet()) << endl ;
415
416
417 if (code==0) return getVal(normSet) ;
418 if (normSet) {
419 return analyticalIntegral(code,rangeName) / getNorm(normSet) ;
420 } else {
421 return analyticalIntegral(code,rangeName) ;
422 }
423}
424
425
426
427////////////////////////////////////////////////////////////////////////////////
428/// Check that passed value is positive and not 'not-a-number'. If
429/// not, print an error, until the error counter reaches its set
430/// maximum.
431
433{
434 // check for a math error or negative value
435 Bool_t error(kFALSE) ;
436 if (TMath::IsNaN(value)) {
437 logEvalError(Form("p.d.f value is Not-a-Number (%f), forcing value to zero",value)) ;
438 error=kTRUE ;
439 }
440 if (value<0) {
441 logEvalError(Form("p.d.f value is less than zero (%f), forcing value to zero",value)) ;
442 error=kTRUE ;
443 }
444
445 // do nothing if we are no longer tracing evaluations and there was no error
446 if(!error) return error ;
447
448 // otherwise, print out this evaluations input values and result
449 if(++_errorCount <= 10) {
450 cxcoutD(Tracing) << "*** Evaluation Error " << _errorCount << " ";
451 if(_errorCount == 10) cxcoutD(Tracing) << "(no more will be printed) ";
452 }
453 else {
454 return error ;
455 }
456
457 Print() ;
458 return error ;
459}
460
461
462////////////////////////////////////////////////////////////////////////////////
463/// Get normalisation term needed to normalise the raw values returned by
464/// getVal(). Note that `getVal(normalisationVariables)` will automatically
465/// apply the normalisation term returned here.
466/// \param nset Set of variables to normalise over.
468{
469 if (!nset) return 1 ;
470
472 if (_verboseEval>1) cxcoutD(Tracing) << IsA()->GetName() << "::getNorm(" << GetName() << "): norm(" << _norm << ") = " << _norm->getVal() << endl ;
473
474 Double_t ret = _norm->getVal() ;
475 if (ret==0.) {
476 if(++_errorCount <= 10) {
477 coutW(Eval) << "RooAbsPdf::getNorm(" << GetName() << ":: WARNING normalization is zero, nset = " ; nset->Print("1") ;
478 if(_errorCount == 10) coutW(Eval) << "RooAbsPdf::getNorm(" << GetName() << ") INFO: no more messages will be printed " << endl ;
479 }
480 }
481
482 return ret ;
483}
484
485
486
487////////////////////////////////////////////////////////////////////////////////
488/// Return pointer to RooAbsReal object that implements calculation of integral over observables iset in range
489/// rangeName, optionally taking the integrand normalized over observables nset
490
491const RooAbsReal* RooAbsPdf::getNormObj(const RooArgSet* nset, const RooArgSet* iset, const TNamed* rangeName) const
492{
493
494 // Check normalization is already stored
495 CacheElem* cache = (CacheElem*) _normMgr.getObj(nset,iset,0,rangeName) ;
496 if (cache) {
497 return cache->_norm ;
498 }
499
500 // If not create it now
501 RooArgSet depList;
502 getObservables(iset, depList);
503 RooAbsReal* norm = createIntegral(depList,*nset, *getIntegratorConfig(), RooNameReg::str(rangeName)) ;
504
505 // Store it in the cache
506 cache = new CacheElem(*norm) ;
507 _normMgr.setObj(nset,iset,cache,rangeName) ;
508
509 // And return the newly created integral
510 return norm ;
511}
512
513
514
515////////////////////////////////////////////////////////////////////////////////
516/// Verify that the normalization integral cached with this PDF
517/// is valid for given set of normalization observables.
518///
519/// If not, the cached normalization integral (if any) is deleted
520/// and a new integral is constructed for use with 'nset'.
521/// Elements in 'nset' can be discrete and real, but must be lvalues.
522///
523/// For functions that declare to be self-normalized by overloading the
524/// selfNormalized() function, a unit normalization is always constructed.
525
526Bool_t RooAbsPdf::syncNormalization(const RooArgSet* nset, Bool_t adjustProxies) const
527{
528
529// cout << IsA()->GetName() << "::syncNormalization(" << GetName() << ") nset = " << nset << " = " << (nset?*nset:RooArgSet()) << endl ;
530
531 _normSet = (RooArgSet*) nset ;
532
533 // Check if data sets are identical
534 CacheElem* cache = (CacheElem*) _normMgr.getObj(nset) ;
535 if (cache) {
536
537 Bool_t nsetChanged = (_norm!=cache->_norm) ;
538 _norm = cache->_norm ;
539
540
541// cout << "returning existing object " << _norm->GetName() << endl ;
542
543 if (nsetChanged && adjustProxies) {
544 // Update dataset pointers of proxies
545 ((RooAbsPdf*) this)->setProxyNormSet(nset) ;
546 }
547
548 return nsetChanged ;
549 }
550
551 // Update dataset pointers of proxies
552 if (adjustProxies) {
553 ((RooAbsPdf*) this)->setProxyNormSet(nset) ;
554 }
555
556 RooArgSet depList;
557 getObservables(nset, depList);
558
559 if (_verboseEval>0) {
560 if (!selfNormalized()) {
561 cxcoutD(Tracing) << IsA()->GetName() << "::syncNormalization(" << GetName()
562 << ") recreating normalization integral " << endl ;
564 } else {
565 cxcoutD(Tracing) << IsA()->GetName() << "::syncNormalization(" << GetName() << ") selfNormalized, creating unit norm" << endl;
566 }
567 }
568
569 // Destroy old normalization & create new
570 if (selfNormalized() || !dependsOn(depList)) {
571 auto ntitle = std::string(GetTitle()) + " Unit Normalization";
572 auto nname = std::string(GetName()) + "_UnitNorm";
573 _norm = new RooRealVar(nname.c_str(),ntitle.c_str(),1) ;
574 } else {
575 const char* nr = (_normRangeOverride.Length()>0 ? _normRangeOverride.Data() : (_normRange.Length()>0 ? _normRange.Data() : 0)) ;
576
577// cout << "RooAbsPdf::syncNormalization(" << GetName() << ") rangeName for normalization is " << (nr?nr:"<null>") << endl ;
578 RooAbsReal* normInt = createIntegral(depList,*getIntegratorConfig(),nr) ;
579 normInt->getVal() ;
580// cout << "resulting normInt = " << normInt->GetName() << endl ;
581
582 const char* cacheParamsStr = getStringAttribute("CACHEPARAMINT") ;
583 if (cacheParamsStr && strlen(cacheParamsStr)) {
584
585 std::unique_ptr<RooArgSet> intParams{normInt->getVariables()} ;
586
587 RooArgSet cacheParams = RooHelpers::selectFromArgSet(*intParams, cacheParamsStr);
588
589 if (!cacheParams.empty()) {
590 cxcoutD(Caching) << "RooAbsReal::createIntObj(" << GetName() << ") INFO: constructing " << cacheParams.getSize()
591 << "-dim value cache for integral over " << depList << " as a function of " << cacheParams << " in range " << (nr?nr:"<default>") << endl ;
592 string name = Form("%s_CACHE_[%s]",normInt->GetName(),cacheParams.contentsString().c_str()) ;
593 RooCachedReal* cachedIntegral = new RooCachedReal(name.c_str(),name.c_str(),*normInt,cacheParams) ;
594 cachedIntegral->setInterpolationOrder(2) ;
595 cachedIntegral->addOwnedComponents(*normInt) ;
596 cachedIntegral->setCacheSource(kTRUE) ;
597 if (normInt->operMode()==ADirty) {
598 cachedIntegral->setOperMode(ADirty) ;
599 }
600 normInt= cachedIntegral ;
601 }
602
603 }
604 _norm = normInt ;
605 }
606
607 // Register new normalization with manager (takes ownership)
608 cache = new CacheElem(*_norm) ;
609 _normMgr.setObj(nset,cache) ;
610
611// cout << "making new object " << _norm->GetName() << endl ;
612
613 return kTRUE ;
614}
615
616
617
618////////////////////////////////////////////////////////////////////////////////
619/// Reset error counter to given value, limiting the number
620/// of future error messages for this pdf to 'resetValue'
621
623{
624 _errorCount = resetValue ;
625 _negCount = resetValue ;
626}
627
628
629
630////////////////////////////////////////////////////////////////////////////////
631/// Reset trace counter to given value, limiting the
632/// number of future trace messages for this pdf to 'value'
633
635{
636 if (!allNodes) {
637 _traceCount = value ;
638 return ;
639 } else {
640 RooArgList branchList ;
641 branchNodeServerList(&branchList) ;
642 TIterator* iter = branchList.createIterator() ;
643 RooAbsArg* arg ;
644 while((arg=(RooAbsArg*)iter->Next())) {
645 RooAbsPdf* pdf = dynamic_cast<RooAbsPdf*>(arg) ;
646 if (pdf) pdf->setTraceCounter(value,kFALSE) ;
647 }
648 delete iter ;
649 }
650
651}
652
653
654
655
656////////////////////////////////////////////////////////////////////////////////
657/// Return the log of the current value with given normalization
658/// An error message is printed if the argument of the log is negative.
659
661{
662 Double_t prob = getVal(nset) ;
663
664 if (fabs(prob)>1e6) {
665 coutW(Eval) << "RooAbsPdf::getLogVal(" << GetName() << ") WARNING: large likelihood value: " << prob << endl ;
666 }
667
668 if(prob < 0) {
669 logEvalError("getLogVal() top-level p.d.f evaluates to a negative number") ;
670 return RooNaNPacker::packFloatIntoNaN(-prob);
671 }
672
673 if(prob == 0) {
674 logEvalError("getLogVal() top-level p.d.f evaluates to zero") ;
675
676 return -std::numeric_limits<double>::infinity();
677 }
678
679 if (TMath::IsNaN(prob)) {
680 logEvalError("getLogVal() top-level p.d.f evaluates to NaN") ;
681
682 return prob;
683 }
684
685 return log(prob);
686}
687
688
689////////////////////////////////////////////////////////////////////////////////
690/// Check for infinity or NaN.
691/// \param[in] inputs Array to check
692/// \return True if either infinity or NaN were found.
693namespace {
694template<class T>
695bool checkInfNaNNeg(const T& inputs) {
696 // check for a math error or negative value
697 bool inf = false;
698 bool nan = false;
699 bool neg = false;
700
701 for (double val : inputs) { //CHECK_VECTORISE
702 inf |= !std::isfinite(val);
703 nan |= TMath::IsNaN(val); // Works also during fast math
704 neg |= val < 0;
705 }
706
707 return inf || nan || neg;
708}
709}
710
711
712////////////////////////////////////////////////////////////////////////////////
713/// Scan through outputs and fix+log all nans and negative values.
714/// \param[in,out] outputs Array to be scanned & fixed.
715/// \param[in] begin Begin of event range. Only needed to print the correct event number
716/// where the error occurred.
717void RooAbsPdf::logBatchComputationErrors(RooSpan<const double>& outputs, std::size_t begin) const {
718 for (unsigned int i=0; i<outputs.size(); ++i) {
719 const double value = outputs[i];
720 if (TMath::IsNaN(outputs[i])) {
721 logEvalError(Form("p.d.f value of (%s) is Not-a-Number (%f) for entry %zu",
722 GetName(), value, begin+i));
723 } else if (!std::isfinite(outputs[i])){
724 logEvalError(Form("p.d.f value of (%s) is (%f) for entry %zu",
725 GetName(), value, begin+i));
726 } else if (outputs[i] < 0.) {
727 logEvalError(Form("p.d.f value of (%s) is less than zero (%f) for entry %zu",
728 GetName(), value, begin+i));
729 }
730 }
731}
732
733
734////////////////////////////////////////////////////////////////////////////////
735/// Compute the log-likelihoods for all events in the requested batch.
736/// The arguments are passed over to getValues().
737/// \param[in] evalData Struct with data that should be used for evaluation.
738/// \param[in] normSet Optional normalisation set to be used during computations.
739/// \return Returns a batch of doubles that contains the log probabilities.
741{
742 auto pdfValues = getValues(evalData, normSet);
743
744 evalData.logProbabilities.resize(pdfValues.size());
746
747 if (checkInfNaNNeg(pdfValues)) {
748 logBatchComputationErrors(pdfValues, 0);
749
750 for (std::size_t i = 0; i < pdfValues.size(); ++i) {
751 const double prob = pdfValues[i];
752 double theLog = RooBatchCompute::fast_log(prob);
753
754 if (prob <= 0.) {
755 // Pass magnitude of undershoot to minimiser:
756 theLog = RooNaNPacker::packFloatIntoNaN(-prob);
757 } else if (std::isnan(prob)) {
758 theLog = prob;
759 }
760
761 output[i] = theLog;
762 }
763
764 return output;
765 }
766
767 for (std::size_t i = 0; i < pdfValues.size(); ++i) { //CHECK_VECTORISE
768 const double prob = pdfValues[i];
770 }
771
772 return output;
773}
774
775////////////////////////////////////////////////////////////////////////////////
776/// Return the extended likelihood term (\f$ N_\mathrm{expect} - N_\mathrm{observed} \cdot \log(N_\mathrm{expect} \f$)
777/// of this PDF for the given number of observed events.
778///
779/// For successful operation, the PDF implementation must indicate that
780/// it is extendable by overloading `canBeExtended()`, and must
781/// implement the `expectedEvents()` function.
782
784{
785 // check if this PDF supports extended maximum likelihood fits
786 if(!canBeExtended()) {
787 coutE(InputArguments) << fName << ": this PDF does not support extended maximum likelihood"
788 << endl;
789 return 0;
790 }
791
792 Double_t expected= expectedEvents(nset);
793 if(expected < 0) {
794 coutE(InputArguments) << fName << ": calculated negative expected events: " << expected
795 << endl;
796 logEvalError("extendedTerm #expected events is <0 return a NaN");
797 return TMath::QuietNaN();
798 }
799
800
801 // Explicitly handle case Nobs=Nexp=0
802 if (fabs(expected)<1e-10 && fabs(observed)<1e-10) {
803 return 0 ;
804 }
805
806 // Check for errors in Nexpected
807 if (TMath::IsNaN(expected)) {
808 logEvalError("extendedTerm #expected events is a NaN") ;
809 return TMath::QuietNaN() ;
810 }
811
812 // calculate and return the negative log-likelihood of the Poisson
813 // factor for this dataset, dropping the constant log(observed!)
814 // Double_t extra=0;
815 // if(observed<1000000) {
816 // Double_t Delta1 = (expected-observed);
817 // Double_t Delta2 = observed*(log(expected)-log(observed+1));
818 // Double_t Const3 = 0.5*log(observed+1);
819 // extra= Delta1 - Delta2 + Const3;
820
821 // cout << " extra obs = " << observed << " exp = " << expected << endl ;
822 // cout << " extra orig = " << expected - observed*log(expected) << endl ;
823 // cout << " extra orig fix = " << expected - observed*log(expected) + log(TMath::Gamma(observed+1)) << endl ;
824 // cout << " extra new = " << extra << endl ;
825
826 // } else {
827 // Double_t sigma_square=expected;
828 // Double_t diff=observed-expected;
829 // extra=-log(sigma_square)/2 + (diff*diff)/(2*sigma_square);
830 // }
831
832 Double_t extra= expected - observed*log(expected);
833
834// cout << "RooAbsPdf::extendedTerm(" << GetName() << ") observed = " << observed << " expected = " << expected << endl ;
835
836 Bool_t trace(kFALSE) ;
837 if(trace) {
838 cxcoutD(Tracing) << fName << "::extendedTerm: expected " << expected << " events, got "
839 << observed << " events. extendedTerm = " << extra << endl;
840 }
841
842// cout << "RooAbsPdf::extendedTerm(" << GetName() << ") nExp = " << expected << " nObs = " << observed << endl ;
843 return extra;
844}
845
846
847
848////////////////////////////////////////////////////////////////////////////////
849/// Construct representation of -log(L) of PDF with given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset
850/// is binned, a binned likelihood is constructed.
851///
852/// The following named arguments are supported
853///
854/// <table>
855/// <tr><th> Type of CmdArg <th> Effect on nll
856/// <tr><td> `ConditionalObservables(Args_t &&... argsOrArgSet)` <td> Do not normalize PDF over listed observables.
857// Arguments can either be multiple RooRealVar or a single RooArgSet containing them.
858/// <tr><td> `Extended(Bool_t flag)` <td> Add extended likelihood term, off by default
859/// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name
860/// <tr><td> `Range(Double_t lo, Double_t hi)` <td> Fit only data inside given range. A range named "fit" is created on the fly on all observables.
861/// Multiple comma separated range names can be specified.
862/// <tr><td> `SumCoefRange(const char* name)` <td> Set the range in which to interpret the coefficients of RooAddPdf components
863/// <tr><td> `NumCPU(int num, int strat)` <td> Parallelize NLL calculation on num CPUs
864/// <table>
865/// <tr><th> Strategy <th> Effect
866/// <tr><td> 0 = RooFit::BulkPartition (Default) <td> Divide events in N equal chunks
867/// <tr><td> 1 = RooFit::Interleave <td> Process event i%N in process N. Recommended for binned data with
868/// a substantial number of zero-bins, which will be distributed across processes more equitably in this strategy
869/// <tr><td> 2 = RooFit::SimComponents <td> Process each component likelihood of a RooSimultaneous fully in a single process
870/// and distribute components over processes. This approach can be benificial if normalization calculation time
871/// dominates the total computation time of a component (since the normalization calculation must be performed
872/// in each process in strategies 0 and 1. However beware that if the RooSimultaneous components do not share many
873/// parameters this strategy is inefficient: as most minuit-induced likelihood calculations involve changing
874/// a single parameter, only 1 of the N processes will be active most of the time if RooSimultaneous components
875/// do not share many parameters
876/// <tr><td> 3 = RooFit::Hybrid <td> Follow strategy 0 for all RooSimultaneous components, except those with less than
877/// 30 dataset entries, for which strategy 2 is followed.
878/// </table>
879/// <tr><td> `BatchMode(bool on)` <td> Batch evaluation mode. See fitTo().
880/// <tr><td> `Optimize(Bool_t flag)` <td> Activate constant term optimization (on by default)
881/// <tr><td> `SplitRange(Bool_t flag)` <td> Use separate fit ranges in a simultaneous fit. Actual range name for each subsample is assumed to
882/// be `rangeName_indexState`, where `indexState` is the state of the master index category of the simultaneous fit.
883/// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
884/// ```
885/// myVariable.setRange("range_pi0", 135, 210);
886/// myVariable.setRange("range_gamma", 50, 210);
887/// ```
888/// <tr><td> `Constrain(const RooArgSet&pars)` <td> For p.d.f.s that contain internal parameter constraint terms (that is usually product PDFs, where one
889/// term of the product depends on parameters but not on the observable(s),), only apply constraints to the given subset of parameters.
890/// <tr><td> `ExternalConstraints(const RooArgSet& )` <td> Include given external constraints to likelihood by multiplying them with the original likelihood.
891/// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of normalization observables to be used for the constraint terms.
892/// If none are specified the constrained parameters are used.
893/// <tr><td> `GlobalObservablesTag(const char* tagName)` <td> Define the set of normalization observables to be used for the constraint terms by
894/// a string attribute associated with pdf observables that match the given tagName.
895/// <tr><td> `Verbose(Bool_t flag)` <td> Controls RooFit informational messages in likelihood construction
896/// <tr><td> `CloneData(Bool flag)` <td> Use clone of dataset in NLL (default is true)
897/// <tr><td> `Offset(Bool_t)` <td> Offset likelihood by initial value (so that starting value of FCN in minuit is zero).
898/// This can improve numeric stability in simultaneous fits with components with large likelihood values
899/// <tr><td> `IntegrateBins(double precision)` <td> In binned fits, integrate the PDF over the bins instead of using the probability density at the bin centre.
900/// This can reduce the bias observed when fitting functions with high curvature to binned data.
901/// - precision > 0: Activate bin integration everywhere. Use precision between 0.01 and 1.E-6, depending on binning.
902/// Note that a low precision such as 0.01 might yield identical results to 1.E-4, since the integrator might reach 1.E-4 already in its first
903/// integration step. If lower precision is desired (more speed), a RooBinSamplingPdf has to be created manually, and its integrator
904/// has to be manipulated directly.
905/// - precision = 0: Activate bin integration only for continuous PDFs fit to a RooDataHist.
906/// - precision < 0: Deactivate.
907/// \see RooBinSamplingPdf
908/// </table>
909///
910///
911
912RooAbsReal* RooAbsPdf::createNLL(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
913 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
914{
916 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
917 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
918 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
919 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
920 return createNLL(data,l) ;
921}
922
923namespace {
924
925std::unique_ptr<RooAbsReal> createMultiRangeNLLCorrectionTerm(
926 RooAbsPdf const &pdf, RooAbsData const &data, std::string const &baseName, std::string const &rangeNames)
927{
928 double sumEntriesTotal = 0.0;
929
930 RooArgList termList;
931 RooArgList integralList;
932
933 for (const auto &currentRangeName : RooHelpers::tokenise(rangeNames, ",")) {
934 const std::string currentName = baseName + "_" + currentRangeName;
935
936 auto sumEntriesCurrent = data.sumEntries("1", currentRangeName.c_str());
937 sumEntriesTotal += sumEntriesCurrent;
938
939 RooArgSet depList;
940 pdf.getObservables(data.get(), depList);
941 auto pdfIntegralCurrent = pdf.createIntegral(depList, nullptr, nullptr, currentRangeName.c_str());
942
943 auto term = new RooFormulaVar((currentName + "_correctionTerm").c_str(),
944 (std::string("-(") + std::to_string(sumEntriesCurrent) + " * log(x[0]))").c_str(),
945 RooArgList(*pdfIntegralCurrent));
946
947 termList.add(*term);
948 integralList.add(*pdfIntegralCurrent);
949 }
950
951 auto integralFull = new RooAddition((baseName + "_correctionFullIntegralTerm").c_str(),
952 "integral",
953 integralList,
954 true);
955
956 auto fullRangeTerm = new RooFormulaVar((baseName + "_foobar").c_str(),
957 (std::string("(") + std::to_string(sumEntriesTotal) + " * log(x[0]))").c_str(),
958 RooArgList(*integralFull));
959
960 termList.add(*fullRangeTerm);
961 return std::unique_ptr<RooAbsReal>{
962 new RooAddition((baseName + "_correction").c_str(), "correction", termList, true)};
963}
964
965
966} // namespace
967
968
969////////////////////////////////////////////////////////////////////////////////
970/// Construct representation of -log(L) of PDFwith given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset
971/// is binned, a binned likelihood is constructed.
972///
973/// See RooAbsPdf::createNLL(RooAbsData& data, RooCmdArg arg1, RooCmdArg arg2, RooCmdArg arg3, RooCmdArg arg4,
974/// RooCmdArg arg5, RooCmdArg arg6, RooCmdArg arg7, RooCmdArg arg8)
975/// for documentation of options
976
978{
979
980 // Select the pdf-specific commands
981 RooCmdConfig pc(Form("RooAbsPdf::createNLL(%s)",GetName())) ;
982
983 pc.defineString("rangeName","RangeWithName",0,"",kTRUE) ;
984 pc.defineString("addCoefRange","SumCoefRange",0,"") ;
985 pc.defineString("globstag","GlobalObservablesTag",0,"") ;
986 pc.defineDouble("rangeLo","Range",0,-999.) ;
987 pc.defineDouble("rangeHi","Range",1,-999.) ;
988 pc.defineInt("splitRange","SplitRange",0,0) ;
989 pc.defineInt("ext","Extended",0,2) ;
990 pc.defineInt("numcpu","NumCPU",0,1) ;
991 pc.defineInt("interleave","NumCPU",1,0) ;
992 pc.defineInt("verbose","Verbose",0,0) ;
993 pc.defineInt("optConst","Optimize",0,0) ;
994 pc.defineInt("cloneData","CloneData", 0, 2);
995 pc.defineObject("projDepSet","ProjectedObservables",0,0) ;
996 pc.defineSet("cPars","Constrain",0,0) ;
997 pc.defineSet("glObs","GlobalObservables",0,0) ;
998 pc.defineInt("doOffset","OffsetLikelihood",0,0) ;
999 pc.defineSet("extCons","ExternalConstraints",0,0) ;
1000 pc.defineInt("BatchMode", "BatchMode", 0, 0);
1001 pc.defineDouble("IntegrateBins", "IntegrateBins", 0, -1.);
1002 pc.defineMutex("Range","RangeWithName") ;
1003 pc.defineMutex("GlobalObservables","GlobalObservablesTag") ;
1004
1005 // Process and check varargs
1006 pc.process(cmdList) ;
1007 if (!pc.ok(kTRUE)) {
1008 return 0 ;
1009 }
1010
1011 // Decode command line arguments
1012 const char* rangeName = pc.getString("rangeName",0,kTRUE) ;
1013 const char* addCoefRangeName = pc.getString("addCoefRange",0,kTRUE) ;
1014 Int_t ext = pc.getInt("ext") ;
1015 Int_t numcpu = pc.getInt("numcpu") ;
1016 Int_t numcpu_strategy = pc.getInt("interleave");
1017 // strategy 3 works only for RooSimultaneus.
1018 if (numcpu_strategy==3 && !this->InheritsFrom("RooSimultaneous") ) {
1019 coutW(Minimization) << "Cannot use a NumCpu Strategy = 3 when the pdf is not a RooSimultaneus, "
1020 "falling back to default strategy = 0" << endl;
1021 numcpu_strategy = 0;
1022 }
1023 RooFit::MPSplit interl = (RooFit::MPSplit) numcpu_strategy;
1024
1025 Int_t splitr = pc.getInt("splitRange") ;
1026 Bool_t verbose = pc.getInt("verbose") ;
1027 Int_t optConst = pc.getInt("optConst") ;
1028 Int_t cloneData = pc.getInt("cloneData") ;
1029 Int_t doOffset = pc.getInt("doOffset") ;
1030
1031 // If no explicit cloneData command is specified, cloneData is set to true if optimization is activated
1032 if (cloneData==2) {
1033 cloneData = optConst ;
1034 }
1035
1036 // Process automatic extended option
1037 if (ext==2) {
1038 ext = ((extendMode()==CanBeExtended || extendMode()==MustBeExtended)) ? 1 : 0 ;
1039 if (ext) {
1040 coutI(Minimization) << "p.d.f. provides expected number of events, including extended term in likelihood." << endl ;
1041 }
1042 }
1043
1044 // Clear possible range attributes from previous fits.
1045 setStringAttribute("fitrange", nullptr);
1046
1047 if (pc.hasProcessed("Range")) {
1048 Double_t rangeLo = pc.getDouble("rangeLo") ;
1049 Double_t rangeHi = pc.getDouble("rangeHi") ;
1050
1051 // Create range with name 'fit' with above limits on all observables
1052 RooArgSet obs;
1053 getObservables(data.get(), obs) ;
1054 for (auto arg : obs) {
1055 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
1056 if (rrv) rrv->setRange("fit",rangeLo,rangeHi) ;
1057 }
1058
1059 // Set range name to be fitted to "fit"
1060 rangeName = "fit" ;
1061 }
1062
1063 RooArgSet projDeps ;
1064 auto tmp = static_cast<RooArgSet*>(pc.getObject("projDepSet")) ;
1065 if (tmp) {
1066 projDeps.add(*tmp) ;
1067 }
1068
1069 // Construct NLL
1071 RooAbsReal* nll ;
1072 string baseName = Form("nll_%s_%s",GetName(),data.GetName()) ;
1074 cfg.addCoefRangeName = addCoefRangeName ? addCoefRangeName : "";
1075 cfg.nCPU = numcpu;
1076 cfg.interleave = interl;
1077 cfg.verbose = verbose;
1078 cfg.splitCutRange = static_cast<bool>(splitr);
1079 cfg.cloneInputData = static_cast<bool>(cloneData);
1080 cfg.integrateOverBinsPrecision = pc.getDouble("IntegrateBins");
1081 cfg.binnedL = false;
1082 if (!rangeName || strchr(rangeName,',')==0) {
1083 // Simple case: default range, or single restricted range
1084 //cout<<"FK: Data test 1: "<<data.sumEntries()<<endl;
1085
1086 cfg.rangeName = rangeName ? rangeName : "";
1087 auto theNLL = new RooNLLVar(baseName.c_str(),"-log(likelihood)",*this,data,projDeps,cfg, ext);
1088 theNLL->batchMode(pc.getInt("BatchMode"));
1089 nll = theNLL;
1090 } else {
1091 // Composite case: multiple ranges
1092 RooArgList nllList ;
1093 auto tokens = RooHelpers::tokenise(rangeName, ",");
1094 if (RooHelpers::checkIfRangesOverlap(*this, data, tokens)) {
1095 throw std::runtime_error(
1096 std::string("Error in RooAbsPdf::createNLL! The ranges ") + rangeName + " are overlapping!");
1097 }
1098 for (const auto& token : tokens) {
1099 cfg.rangeName = token;
1100 auto nllComp = new RooNLLVar((baseName + "_" + token).c_str(),"-log(likelihood)",
1101 *this,data,projDeps,cfg,ext);
1102 nllComp->batchMode(pc.getInt("BatchMode"));
1103 nllList.add(*nllComp) ;
1104 }
1105
1106 if (!ext) {
1107 // Each RooNLLVar was created with the normalization set corresponding to
1108 // the subrange, not the union range like it should be. We have to add an
1109 // extra term to cancel this normalization problem. However, this is
1110 // only necessarry for the non-extended case, because adding an extension
1111 // term to the individual NLLs as done here is mathematicall equivalent
1112 // to adding the normalization correction terms plus a global extension
1113 // term.
1114 nllList.add(*createMultiRangeNLLCorrectionTerm(*this, data, baseName, rangeName).release());
1115 }
1116
1117 nll = new RooAddition(baseName.c_str(),"-log(likelihood)",nllList,true) ;
1118 }
1120
1121 auto constraintTerm = RooConstraintSum::createConstraintTerm(
1122 baseName + "_constr", // name
1123 *this, // pdf
1124 *data.get(), // observables
1125 pc.getSet("cPars"), // Constrain RooCmdArg
1126 pc.getSet("extCons"), // ExternalConstraints RooCmdArg
1127 pc.getSet("glObs"), // GlobalObservables RooCmdArg
1128 pc.getString("globstag",0,true), // GlobalObservablesTag RooCmdArg
1129 _myws // passing workspace to cache the set of constraints
1130 );
1131
1132 // Include constraints, if any, in likelihood
1133 if (constraintTerm) {
1134 RooAbsReal* orignll = nll ;
1135 nll = new RooAddition(Form("%s_with_constr",baseName.c_str()),"nllWithCons",RooArgSet(*nll,*constraintTerm)) ;
1136 nll->addOwnedComponents(RooArgSet(*orignll,*constraintTerm.release())) ;
1137 }
1138
1139 if (optConst) {
1141 }
1142
1143 if (doOffset) {
1144 nll->enableOffsetting(kTRUE) ;
1145 }
1146
1147 return nll ;
1148}
1149
1150
1152{
1153 // Calculated corrected errors for weighted likelihood fits
1154 std::unique_ptr<RooFitResult> rw(minimizer.save());
1155 // Weighted inverse Hessian matrix
1156 const TMatrixDSym &matV = rw->covarianceMatrix();
1157 coutI(Fitting)
1158 << "RooAbsPdf::fitTo(" << this->GetName()
1159 << ") Calculating covariance matrix according to the asymptotically correct approach. If you find this "
1160 "method useful please consider citing https://arxiv.org/abs/1911.01303."
1161 << endl;
1162
1163 // Initialise matrix containing first derivatives
1164 auto nFloatPars = rw->floatParsFinal().getSize();
1165 TMatrixDSym num(nFloatPars);
1166 for (int k = 0; k < nFloatPars; k++) {
1167 for (int l = 0; l < nFloatPars; l++) {
1168 num(k, l) = 0.0;
1169 }
1170 }
1171 RooArgSet obs;
1172 this->getObservables(data.get(), obs);
1173 // Create derivative objects
1174 std::vector<std::unique_ptr<RooDerivative>> derivatives;
1175 const RooArgList &floated = rw->floatParsFinal();
1176 std::unique_ptr<RooArgSet> floatingparams{
1177 static_cast<RooArgSet *>(this->getParameters(data)->selectByAttrib("Constant", false))};
1178 for (const auto paramresult : floated) {
1179 auto paraminternal = static_cast<RooRealVar *>(floatingparams->find(*paramresult));
1180 assert(floatingparams->find(*paramresult)->IsA() == RooRealVar::Class());
1181 derivatives.emplace_back(this->derivative(*paraminternal, obs, 1));
1182 }
1183
1184 // Loop over data
1185 for (int j = 0; j < data.numEntries(); j++) {
1186 // Sets obs to current data point, this is where the pdf will be evaluated
1187 obs = *data.get(j);
1188 // Determine first derivatives
1189 std::vector<double> diffs(floated.getSize(), 0.0);
1190 for (int k = 0; k < floated.getSize(); k++) {
1191 const auto paramresult = static_cast<RooRealVar *>(floated.at(k));
1192 auto paraminternal = static_cast<RooRealVar *>(floatingparams->find(*paramresult));
1193 // first derivative to parameter k at best estimate point for this measurement
1194 double diff = derivatives[k]->getVal();
1195 // need to reset to best fit point after differentiation
1196 *paraminternal = paramresult->getVal();
1197 diffs[k] = diff;
1198 }
1199 // Fill numerator matrix
1200 double prob = getVal(&obs);
1201 for (int k = 0; k < floated.getSize(); k++) {
1202 for (int l = 0; l < floated.getSize(); l++) {
1203 num(k, l) += data.weight() * data.weight() * diffs[k] * diffs[l] / (prob * prob);
1204 }
1205 }
1206 }
1207 num.Similarity(matV);
1208
1209 // Propagate corrected errors to parameters objects
1210 minimizer.applyCovarianceMatrix(num);
1211
1212 // The derivatives are found in RooFit and not with the minimizer (e.g.
1213 // minuit), so the quality of the corrected covariance matrix corresponds to
1214 // the quality of the original covariance matrix
1215 return rw->covQual();
1216}
1217
1219{
1220
1221 // Make list of RooNLLVar components of FCN
1222 std::vector<RooNLLVar *> nllComponents;
1223 std::unique_ptr<RooArgSet> comps{nll.getComponents()};
1224 for (auto const &arg : *comps) {
1225 if (RooNLLVar *nllComp = dynamic_cast<RooNLLVar *>(arg)) {
1226 nllComponents.push_back(nllComp);
1227 }
1228 }
1229
1230 // Calculated corrected errors for weighted likelihood fits
1231 std::unique_ptr<RooFitResult> rw{minimizer.save()};
1232 for (auto &comp : nllComponents) {
1233 comp->applyWeightSquared(true);
1234 }
1235 coutI(Fitting) << "RooAbsPdf::fitTo(" << this->GetName()
1236 << ") Calculating sum-of-weights-squared correction matrix for covariance matrix"
1237 << std::endl;
1238 minimizer.hesse();
1239 std::unique_ptr<RooFitResult> rw2{minimizer.save()};
1240 for (auto &comp : nllComponents) {
1241 comp->applyWeightSquared(false);
1242 }
1243
1244 // Apply correction matrix
1245 const TMatrixDSym &matV = rw->covarianceMatrix();
1246 TMatrixDSym matC = rw2->covarianceMatrix();
1248 if (!decomp) {
1249 coutE(Fitting) << "RooAbsPdf::fitTo(" << this->GetName()
1250 << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction "
1251 "matrix calculated with weight-squared is singular"
1252 << std::endl;
1253 return -1;
1254 }
1255
1256 // replace C by its inverse
1257 decomp.Invert(matC);
1258 // the class lies about the matrix being symmetric, so fill in the
1259 // part above the diagonal
1260 for (int i = 0; i < matC.GetNrows(); ++i) {
1261 for (int j = 0; j < i; ++j) {
1262 matC(j, i) = matC(i, j);
1263 }
1264 }
1265 matC.Similarity(matV);
1266 // C now contiains V C^-1 V
1267 // Propagate corrected errors to parameters objects
1268 minimizer.applyCovarianceMatrix(matC);
1269
1270 return std::min(rw->covQual(), rw2->covQual());
1271}
1272
1273
1274////////////////////////////////////////////////////////////////////////////////
1275/// Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset
1276/// is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT
1277/// commands MIGRAD, HESSE in succession.
1278/// \param[in] data Data to fit the PDF to
1279/// \param[in] arg1 One or more arguments to control the behaviour of the fit
1280/// \return RooFitResult with fit status and parameters if option Save() is used, `nullptr` otherwise. The user takes ownership of the fit result.
1281///
1282/// The following named arguments are supported
1283///
1284/// <table>
1285/// <tr><th> Type of CmdArg <th> Options to control construction of -log(L)
1286/// <tr><td> `ConditionalObservables(Args_t &&... argsOrArgSet)` <td> Do not normalize PDF over listed observables.
1287// Arguments can either be multiple RooRealVar or a single RooArgSet containing them.
1288/// <tr><td> `Extended(Bool_t flag)` <td> Add extended likelihood term, off by default
1289/// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name. Multiple comma-separated range names can be specified.
1290/// In this case, the unnormalized PDF \f$f(x)\f$ is normalized by the integral over all ranges \f$r_i\f$:
1291/// \f[
1292/// p(x) = \frac{f(x)}{\sum_i \int_{r_i} f(x) dx}.
1293/// \f]
1294/// <tr><td> `Range(Double_t lo, Double_t hi)` <td> Fit only data inside given range. A range named "fit" is created on the fly on all observables.
1295/// <tr><td> `SumCoefRange(const char* name)` <td> Set the range in which to interpret the coefficients of RooAddPdf components
1296/// <tr><td> `NumCPU(int num, int strat)` <td> Parallelize NLL calculation on `num` CPUs
1297/// <table>
1298/// <tr><th> Strategy <th> Effect
1299/// <tr><td> 0 = RooFit::BulkPartition (Default) <td> Divide events in N equal chunks
1300/// <tr><td> 1 = RooFit::Interleave <td> Process event i%N in process N. Recommended for binned data with
1301/// a substantial number of zero-bins, which will be distributed across processes more equitably in this strategy
1302/// <tr><td> 2 = RooFit::SimComponents <td> Process each component likelihood of a RooSimultaneous fully in a single process
1303/// and distribute components over processes. This approach can be benificial if normalization calculation time
1304/// dominates the total computation time of a component (since the normalization calculation must be performed
1305/// in each process in strategies 0 and 1. However beware that if the RooSimultaneous components do not share many
1306/// parameters this strategy is inefficient: as most minuit-induced likelihood calculations involve changing
1307/// a single parameter, only 1 of the N processes will be active most of the time if RooSimultaneous components
1308/// do not share many parameters
1309/// <tr><td> 3 = RooFit::Hybrid <td> Follow strategy 0 for all RooSimultaneous components, except those with less than
1310/// 30 dataset entries, for which strategy 2 is followed.
1311/// </table>
1312/// <tr><td> `SplitRange(Bool_t flag)` <td> Use separate fit ranges in a simultaneous fit. Actual range name for each subsample is assumed
1313/// to by `rangeName_indexState` where indexState is the state of the master index category of the simultaneous fit.
1314/// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
1315/// ```
1316/// myVariable.setRange("range_pi0", 135, 210);
1317/// myVariable.setRange("range_gamma", 50, 210);
1318/// ```
1319/// <tr><td> `Constrain(const RooArgSet&pars)` <td> For p.d.f.s that contain internal parameter constraint terms (that is usually product PDFs, where one
1320/// term of the product depends on parameters but not on the observable(s),), only apply constraints to the given subset of parameters.
1321/// <tr><td> `ExternalConstraints(const RooArgSet& )` <td> Include given external constraints to likelihood by multiplying them with the original likelihood.
1322/// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of normalization observables to be used for the constraint terms.
1323/// If none are specified the constrained parameters are used.
1324/// <tr><td> `Offset(Bool_t)` <td> Offset likelihood by initial value (so that starting value of FCN in minuit is zero).
1325/// This can improve numeric stability in simultaneously fits with components with large likelihood values
1326/// <tr><td> `BatchMode(bool on)` <td> **Experimental** batch evaluation mode. This computes a batch of likelihood values at a time,
1327/// uses faster math functions and possibly auto vectorisation (this depends on the compiler flags).
1328/// Depending on hardware capabilities, the compiler flags and whether a batch evaluation function was
1329/// implemented for the PDFs of the model, likelihood computations are 2x to 10x faster.
1330/// The relative difference of the single log-likelihoods w.r.t. the legacy mode is usually better than 1.E-12,
1331/// and fit parameters usually agree to better than 1.E-6.
1332/// <tr><td> `IntegrateBins(double precision)` <td> In binned fits, integrate the PDF over the bins instead of using the probability density at the bin centre.
1333/// This can reduce the bias observed when fitting functions with high curvature to binned data.
1334/// - precision > 0: Activate bin integration everywhere. Use precision between 0.01 and 1.E-6, depending on binning.
1335/// Note that a low precision such as 0.01 might yield identical results to 1.E-4, since the integrator might reach 1.E-4 already in its first
1336/// integration step. If lower precision is desired (more speed), a RooBinSamplingPdf has to be created manually, and its integrator
1337/// has to be manipulated directly.
1338/// - precision = 0: Activate bin integration only for continuous PDFs fit to a RooDataHist.
1339/// - precision < 0: Deactivate.
1340/// \see RooBinSamplingPdf
1341///
1342/// <tr><th><th> Options to control flow of fit procedure
1343/// <tr><td> `Minimizer("<type>", "<algo>")` <td> Choose minimization package and optionally the algorithm to use. Default is MINUIT/MIGRAD through the RooMinimizer interface,
1344/// but others can be specified (through RooMinimizer interface).
1345/// <table>
1346/// <tr><th> Type <th> Algorithm
1347/// <tr><td> Minuit <td> migrad, simplex, minimize (=migrad+simplex), migradimproved (=migrad+improve)
1348/// <tr><td> Minuit2 <td> migrad, simplex, minimize, scan
1349/// <tr><td> GSLMultiMin <td> conjugatefr, conjugatepr, bfgs, bfgs2, steepestdescent
1350/// <tr><td> GSLSimAn <td> -
1351/// </table>
1352///
1353/// <tr><td> `InitialHesse(Bool_t flag)` <td> Flag controls if HESSE before MIGRAD as well, off by default
1354/// <tr><td> `Optimize(Bool_t flag)` <td> Activate constant term optimization of test statistic during minimization (on by default)
1355/// <tr><td> `Hesse(Bool_t flag)` <td> Flag controls if HESSE is run after MIGRAD, on by default
1356/// <tr><td> `Minos(Bool_t flag)` <td> Flag controls if MINOS is run after HESSE, off by default
1357/// <tr><td> `Minos(const RooArgSet& set)` <td> Only run MINOS on given subset of arguments
1358/// <tr><td> `Save(Bool_t flag)` <td> Flag controls if RooFitResult object is produced and returned, off by default
1359/// <tr><td> `Strategy(Int_t flag)` <td> Set Minuit strategy (0 to 2, default is 1)
1360/// <tr><td> `EvalErrorWall(bool flag=true)` <td> When parameters are in disallowed regions (e.g. PDF is negative), return very high value to fitter
1361/// to force it out of that region. This can, however, mean that the fitter gets lost in this region. If
1362/// this happens, try switching it off.
1363/// <tr><td> `RecoverFromUndefinedRegions(double strength)` <td> When PDF is invalid (e.g. parameter in undefined region), try to direct minimiser away from that region.
1364/// `strength` controls the magnitude of the penalty term. Leaving out this argument defaults to 10. Switch off with `strength = 0.`.
1365/// <tr><td> `FitOptions(const char* optStr)` <td> \deprecated Steer fit with classic options string (for backward compatibility).
1366/// \attention Use of this option excludes use of any of the new style steering options.
1367///
1368/// <tr><td> `SumW2Error(Bool_t flag)` <td> Apply correction to errors and covariance matrix.
1369/// This uses two covariance matrices, one with the weights, the other with squared weights,
1370/// to obtain the correct errors for weighted likelihood fits. If this option is activated, the
1371/// corrected covariance matrix is calculated as \f$ V_\mathrm{corr} = V C^{-1} V \f$, where \f$ V \f$ is the original
1372/// covariance matrix and \f$ C \f$ is the inverse of the covariance matrix calculated using the
1373/// squared weights. This allows to switch between two interpretations of errors:
1374/// <table>
1375/// <tr><th> SumW2Error <th> Interpretation
1376/// <tr><td> true <td> The errors reflect the uncertainty of the Monte Carlo simulation.
1377/// Use this if you want to know how much accuracy you can get from the available Monte Carlo statistics.
1378///
1379/// **Example**: Simulation with 1000 events, the average weight is 0.1.
1380/// The errors are as big as if one fitted to 1000 events.
1381/// <tr><td> false <td> The errors reflect the errors of a dataset, which is as big as the sum of weights.
1382/// Use this if you want to know what statistical errors you would get if you had a dataset with as many
1383/// events as the (weighted) Monte Carlo simulation represents.
1384///
1385/// **Example** (Data as above):
1386/// The errors are as big as if one fitted to 100 events.
1387/// </table>
1388/// \note If the `SumW2Error` correction is enabled, the covariance matrix quality stored in the RooFitResult
1389/// object will be the minimum of the original covariance matrix quality and the quality of the covariance
1390/// matrix calculated with the squared weights.
1391/// <tr><td> `AsymptoticError()` <td> Use the asymptotically correct approach to estimate errors in the presence of weights.
1392/// This is slower but more accurate than `SumW2Error`. See also https://arxiv.org/abs/1911.01303).
1393/// <tr><td> `PrefitDataFraction(double fraction)`
1394/// <td> Runs a prefit on a small dataset of size fraction*(actual data size). This can speed up fits
1395/// by finding good starting values for the parameters for the actual fit.
1396/// \warning Prefitting may give bad results when used in binned analysis.
1397///
1398/// <tr><th><th> Options to control informational output
1399/// <tr><td> `Verbose(Bool_t flag)` <td> Flag controls if verbose output is printed (NLL, parameter changes during fit).
1400/// <tr><td> `Timer(Bool_t flag)` <td> Time CPU and wall clock consumption of fit steps, off by default.
1401/// <tr><td> `PrintLevel(Int_t level)` <td> Set Minuit print level (-1 to 3, default is 1). At -1 all RooFit informational messages are suppressed as well.
1402/// See RooMinimizer::PrintLevel for the meaning of the levels.
1403/// <tr><td> `Warnings(Bool_t flag)` <td> Enable or disable MINUIT warnings (enabled by default)
1404/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per likelihood evaluation.
1405/// A negative value suppresses output completely, a zero value will only print the error count per p.d.f component,
1406/// a positive value will print details of each error up to `numErr` messages per p.d.f component.
1407/// </table>
1408///
1409
1410RooFitResult* RooAbsPdf::fitTo(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
1411 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1412{
1414 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
1415 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
1416 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
1417 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
1418 return fitTo(data,l) ;
1419}
1420
1421
1422
1423////////////////////////////////////////////////////////////////////////////////
1424/// Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset
1425/// is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT
1426/// commands MIGRAD, HESSE and MINOS in succession.
1427///
1428/// See RooAbsPdf::fitTo(RooAbsData&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&)
1429///
1430/// for documentation of options
1431
1433{
1434 // Select the pdf-specific commands
1435 RooCmdConfig pc(Form("RooAbsPdf::fitTo(%s)",GetName())) ;
1436
1437 RooLinkedList fitCmdList(cmdList) ;
1438 RooLinkedList nllCmdList = pc.filterCmdList(fitCmdList,"ProjectedObservables,Extended,Range,"
1439 "RangeWithName,SumCoefRange,NumCPU,SplitRange,Constrained,Constrain,ExternalConstraints,"
1440 "CloneData,GlobalObservables,GlobalObservablesTag,OffsetLikelihood,BatchMode,IntegrateBins");
1441
1442 pc.defineDouble("prefit", "Prefit",0,0);
1443 pc.defineDouble("RecoverFromUndefinedRegions", "RecoverFromUndefinedRegions",0,10.);
1444 pc.defineString("fitOpt","FitOptions",0,"") ;
1445 pc.defineInt("optConst","Optimize",0,2) ;
1446 pc.defineInt("verbose","Verbose",0,0) ;
1447 pc.defineInt("doSave","Save",0,0) ;
1448 pc.defineInt("doTimer","Timer",0,0) ;
1449 pc.defineInt("plevel","PrintLevel",0,1) ;
1450 pc.defineInt("strat","Strategy",0,1) ;
1451 pc.defineInt("initHesse","InitialHesse",0,0) ;
1452 pc.defineInt("hesse","Hesse",0,1) ;
1453 pc.defineInt("minos","Minos",0,0) ;
1454 pc.defineInt("ext","Extended",0,2) ;
1455 pc.defineInt("numcpu","NumCPU",0,1) ;
1456 pc.defineInt("numee","PrintEvalErrors",0,10) ;
1457 pc.defineInt("doEEWall","EvalErrorWall",0,1) ;
1458 pc.defineInt("doWarn","Warnings",0,1) ;
1459 pc.defineInt("doSumW2","SumW2Error",0,-1) ;
1460 pc.defineInt("doAsymptoticError","AsymptoticError",0,-1) ;
1461 pc.defineInt("doOffset","OffsetLikelihood",0,0) ;
1462 pc.defineString("mintype","Minimizer",0,"Minuit") ;
1463 pc.defineString("minalg","Minimizer",1,"minuit") ;
1464 pc.defineObject("minosSet","Minos",0,0) ;
1465 pc.defineSet("cPars","Constrain",0,0) ;
1466 pc.defineSet("extCons","ExternalConstraints",0,0) ;
1467 pc.defineMutex("FitOptions","Verbose") ;
1468 pc.defineMutex("FitOptions","Save") ;
1469 pc.defineMutex("FitOptions","Timer") ;
1470 pc.defineMutex("FitOptions","Strategy") ;
1471 pc.defineMutex("FitOptions","InitialHesse") ;
1472 pc.defineMutex("FitOptions","Hesse") ;
1473 pc.defineMutex("FitOptions","Minos") ;
1474 pc.defineMutex("Range","RangeWithName") ;
1475 pc.defineMutex("InitialHesse","Minimizer") ;
1476
1477 // Process and check varargs
1478 pc.process(fitCmdList) ;
1479 if (!pc.ok(kTRUE)) {
1480 return 0 ;
1481 }
1482
1483 // Decode command line arguments
1484 Double_t prefit = pc.getDouble("prefit");
1485 const double recoverFromNaN = pc.getDouble("RecoverFromUndefinedRegions");
1486 const char* fitOpt = pc.getString("fitOpt",0,kTRUE) ;
1487 Int_t optConst = pc.getInt("optConst") ;
1488 Int_t verbose = pc.getInt("verbose") ;
1489 Int_t doSave = pc.getInt("doSave") ;
1490 Int_t doTimer = pc.getInt("doTimer") ;
1491 Int_t plevel = pc.getInt("plevel") ;
1492 Int_t strat = pc.getInt("strat") ;
1493 Int_t initHesse= pc.getInt("initHesse") ;
1494 Int_t hesse = pc.getInt("hesse") ;
1495 Int_t minos = pc.getInt("minos") ;
1496 Int_t numee = pc.getInt("numee") ;
1497 Int_t doEEWall = pc.getInt("doEEWall") ;
1498 Int_t doWarn = pc.getInt("doWarn") ;
1499 Int_t doSumW2 = pc.getInt("doSumW2") ;
1500 Int_t doAsymptotic = pc.getInt("doAsymptoticError");
1501 const RooArgSet* minosSet = static_cast<RooArgSet*>(pc.getObject("minosSet")) ;
1502 const char* minType = pc.getString("mintype","Minuit") ;
1503 const char* minAlg = pc.getString("minalg","minuit") ;
1504
1505 if (optConst > 1) {
1506 // optConst >= 2 is pre-computating values, which are never used when
1507 // the batchMode is on. This just wastes time.
1508
1509 RooCmdConfig conf(Form("RooAbsPdf::fitTo(%s)", GetName()));
1510 conf.defineInt("BatchMode","BatchMode",0,0);
1511 conf.allowUndefined(true);
1512 conf.process(nllCmdList);
1513 if (conf.getInt("BatchMode") != 0) {
1514 optConst = 1;
1515 }
1516 }
1517
1518
1519 // Determine if the dataset has weights
1520 Bool_t weightedData = data.isNonPoissonWeighted() ;
1521
1522 // Warn user that a method to determine parameter uncertainties should be provided if weighted data is offered
1523 if (weightedData && doSumW2==-1 && doAsymptotic==-1) {
1524 coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: a likelihood fit is requested of what appears to be weighted data.\n"
1525 << " While the estimated values of the parameters will always be calculated taking the weights into account,\n"
1526 << " there are multiple ways to estimate the errors of the parameters. You are advised to make an \n"
1527 << " explicit choice for the error calculation:\n"
1528 << " - Either provide SumW2Error(true), to calculate a sum-of-weights-corrected HESSE error matrix\n"
1529 << " (error will be proportional to the number of events in MC).\n"
1530 << " - Or provide SumW2Error(false), to return errors from original HESSE error matrix\n"
1531 << " (which will be proportional to the sum of the weights, i.e., a dataset with <sum of weights> events).\n"
1532 << " - Or provide AsymptoticError(true), to use the asymptotically correct expression\n"
1533 << " (for details see https://arxiv.org/abs/1911.01303)."
1534 << endl ;
1535 }
1536
1537 if (minos && (doSumW2==1 || doAsymptotic == 1)) {
1538 coutE(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << "): sum-of-weights and asymptotic error correction do not work with MINOS errors. Not fitting." << endl;
1539 return nullptr;
1540 }
1541 if (doAsymptotic==1 && minos) {
1542 coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: asymptotic correction does not apply to MINOS errors" << endl ;
1543 }
1544
1545 if (prefit != 0) {
1546 size_t nEvents = static_cast<size_t>(prefit*data.numEntries());
1547 if (prefit > 0.5 || nEvents < 100) {
1548 oocoutW(this,InputArguments) << "PrefitDataFraction should be in suitable range."
1549 << "With the current PrefitDataFraction=" << prefit
1550 << ", the number of events would be " << nEvents<< " out of "
1551 << data.numEntries() << ". Skipping prefit..." << endl;
1552 }
1553 else {
1554 size_t step = data.numEntries()/nEvents;
1555 RooArgSet tinyVars(*data.get());
1556 RooRealVar weight("weight","weight",1);
1557
1558 if (data.isWeighted()) tinyVars.add(weight);
1559
1560 RooDataSet tiny("tiny", "tiny", tinyVars,
1561 data.isWeighted() ? RooFit::WeightVar(weight) : RooCmdArg());
1562
1563 for (int i=0; i<data.numEntries(); i+=step)
1564 {
1565 const RooArgSet *event = data.get(i);
1566 tiny.add(*event, data.weight());
1567 }
1568 RooLinkedList tinyCmdList(cmdList) ;
1569 pc.filterCmdList(tinyCmdList,"Prefit,Hesse,Minos,Verbose,Save,Timer");
1570 RooCmdArg hesse_option = RooFit::Hesse(false);
1571 RooCmdArg print_option = RooFit::PrintLevel(-1);
1572
1573 tinyCmdList.Add(&hesse_option);
1574 tinyCmdList.Add(&print_option);
1575
1576 fitTo(tiny,tinyCmdList);
1577 }
1578 }
1579
1580 RooAbsReal* nll = createNLL(data,nllCmdList) ;
1581 RooFitResult *ret = 0 ;
1582
1583 //avoid setting both SumW2 and Asymptotic for uncertainty correction
1584 if (doSumW2==1 && doAsymptotic==1) {
1585 coutE(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") ERROR: Cannot compute both asymptotically correct and SumW2 errors." << endl ;
1586 return ret;
1587 }
1588
1589 // Instantiate MINUIT
1590
1591 RooMinimizer m(*nll) ;
1592
1593 m.setMinimizerType(minType) ;
1594
1595 m.setEvalErrorWall(doEEWall) ;
1596 m.setRecoverFromNaNStrength(recoverFromNaN);
1597 if (doWarn==0) {
1598 // m.setNoWarn() ; WVE FIX THIS
1599 }
1600
1601 m.setPrintEvalErrors(numee) ;
1602 if (plevel!=1) {
1603 m.setPrintLevel(plevel) ;
1604 }
1605
1606 if (optConst) {
1607 // Activate constant term optimization
1608 m.optimizeConst(optConst) ;
1609 }
1610
1611 if (fitOpt) {
1612
1613 // Play fit options as historically defined
1614 ret = m.fit(fitOpt) ;
1615
1616 } else {
1617
1618 if (verbose) {
1619 // Activate verbose options
1620 m.setVerbose(1) ;
1621 }
1622 if (doTimer) {
1623 // Activate timer options
1624 m.setProfile(1) ;
1625 }
1626
1627 if (strat!=1) {
1628 // Modify fit strategy
1629 m.setStrategy(strat) ;
1630 }
1631
1632 if (initHesse) {
1633 // Initialize errors with hesse
1634 m.hesse() ;
1635 }
1636
1637 // Minimize using chosen algorithm
1638 m.minimize(minType,minAlg) ;
1639
1640 if (hesse) {
1641 // Evaluate errors with Hesse
1642 m.hesse() ;
1643 }
1644
1645 int corrCovQual = -1;
1646
1647 //asymptotically correct approach
1648 if (doAsymptotic==1 && m.getNPar()>0) {
1649 corrCovQual = calculateAsymptoticCorrectedCovMatrix(m, data);
1650 }
1651
1652 if (doSumW2==1 && m.getNPar()>0) {
1653 corrCovQual = calculateSumW2CorrectedCovMatrix(m, *nll);
1654 }
1655
1656 if (minos) {
1657 // Evaluate errs with Minos
1658 if (minosSet) {
1659 m.minos(*minosSet) ;
1660 } else {
1661 m.minos() ;
1662 }
1663 }
1664
1665 // Optionally return fit result
1666 if (doSave) {
1667 string name = Form("fitresult_%s_%s",GetName(),data.GetName()) ;
1668 string title = Form("Result of fit of p.d.f. %s to dataset %s",GetName(),data.GetName()) ;
1669 ret = m.save(name.c_str(),title.c_str()) ;
1670 if((doSumW2==1 || doAsymptotic==1) && m.getNPar()>0) {
1671 ret->setCovQual(corrCovQual);
1672 }
1673 }
1674
1675 }
1676
1677 if (optConst) {
1678 m.optimizeConst(0) ;
1679 }
1680
1681
1682 // Cleanup
1683 delete nll ;
1684 return ret ;
1685}
1686
1687
1688
1689////////////////////////////////////////////////////////////////////////////////
1690/// Calls RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
1691
1693{
1694 // Select the pdf-specific commands
1695 RooCmdConfig pc(Form("RooAbsPdf::chi2FitTo(%s)",GetName())) ;
1696
1697 // Pull arguments to be passed to chi2 construction from list
1698 RooLinkedList fitCmdList(cmdList) ;
1699 RooLinkedList chi2CmdList = pc.filterCmdList(fitCmdList,"Range,RangeWithName,NumCPU,Optimize,ProjectedObservables,AddCoefRange,SplitRange,DataError,Extended,IntegrateBins") ;
1700
1701 RooAbsReal* chi2 = createChi2(data,chi2CmdList) ;
1702 RooFitResult* ret = chi2FitDriver(*chi2,fitCmdList) ;
1703
1704 // Cleanup
1705 delete chi2 ;
1706 return ret ;
1707}
1708
1709
1710
1711
1712////////////////////////////////////////////////////////////////////////////////
1713/// Create a \f$ \chi^2 \f$ from a histogram and this function.
1714///
1715/// Options to control construction of the \f$ \chi^2 \f$
1716/// ------------------------------------------
1717/// <table>
1718/// <tr><th> Type of CmdArg <th> Effect on \f$ \chi^2 \f$
1719/// <tr><td> `Extended()` <td> Use expected number of events of an extended p.d.f as normalization
1720/// <tr><td> `DataError()` <td> Choose between:
1721/// - Expected error [RooAbsData::Expected]
1722/// - Observed error (e.g. Sum-of-weights) [RooAbsData::SumW2]
1723/// - Poisson interval [RooAbsData::Poisson]
1724/// - Default: Expected error for unweighted data, Sum-of-weights for weighted data [RooAbsData::Auto]
1725/// <tr><td> `NumCPU()` <td> Activate parallel processing feature
1726/// <tr><td> `Range()` <td> Fit only selected region
1727/// <tr><td> `SumCoefRange()` <td> Set the range in which to interpret the coefficients of RooAddPdf components
1728/// <tr><td> `SplitRange()` <td> Fit ranges used in different categories get named after the category.
1729/// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
1730/// ```
1731/// myVariable.setRange("range_pi0", 135, 210);
1732/// myVariable.setRange("range_gamma", 50, 210);
1733/// ```
1734/// <tr><td> `ConditionalObservables(Args_t &&... argsOrArgSet)` <td> Define projected observables.
1735// Arguments can either be multiple RooRealVar or a single RooArgSet containing them.
1736/// </table>
1737
1739 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
1740 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1741{
1742 RooLinkedList cmdList ;
1743 cmdList.Add((TObject*)&arg1) ; cmdList.Add((TObject*)&arg2) ;
1744 cmdList.Add((TObject*)&arg3) ; cmdList.Add((TObject*)&arg4) ;
1745 cmdList.Add((TObject*)&arg5) ; cmdList.Add((TObject*)&arg6) ;
1746 cmdList.Add((TObject*)&arg7) ; cmdList.Add((TObject*)&arg8) ;
1747
1748 RooCmdConfig pc(Form("RooAbsPdf::createChi2(%s)",GetName())) ;
1749 pc.defineString("rangeName","RangeWithName",0,"",kTRUE) ;
1750 pc.allowUndefined(kTRUE) ;
1751 pc.process(cmdList) ;
1752 if (!pc.ok(kTRUE)) {
1753 return 0 ;
1754 }
1755 const char* rangeName = pc.getString("rangeName",0,kTRUE) ;
1756
1757 // Construct Chi2
1759 RooAbsReal* chi2 ;
1760 string baseName = Form("chi2_%s_%s",GetName(),data.GetName()) ;
1761
1762 // Clear possible range attributes from previous fits.
1763 setStringAttribute("fitrange", nullptr);
1764
1765 if (!rangeName || strchr(rangeName,',')==0) {
1766 // Simple case: default range, or single restricted range
1767
1768 chi2 = new RooChi2Var(baseName.c_str(),baseName.c_str(),*this,data,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1769
1770 } else {
1771
1772 // Find which argument is RangeWithName
1773 const RooCmdArg* rarg(0) ;
1774 string rcmd = "RangeWithName" ;
1775 if (arg1.GetName()==rcmd) rarg = &arg1 ;
1776 if (arg2.GetName()==rcmd) rarg = &arg2 ;
1777 if (arg3.GetName()==rcmd) rarg = &arg3 ;
1778 if (arg4.GetName()==rcmd) rarg = &arg4 ;
1779 if (arg5.GetName()==rcmd) rarg = &arg5 ;
1780 if (arg6.GetName()==rcmd) rarg = &arg6 ;
1781 if (arg7.GetName()==rcmd) rarg = &arg7 ;
1782 if (arg8.GetName()==rcmd) rarg = &arg8 ;
1783
1784 // Composite case: multiple ranges
1785 RooArgList chi2List ;
1786 for (std::string& token : RooHelpers::tokenise(rangeName, ",")) {
1787 RooCmdArg subRangeCmd = RooFit::Range(token.c_str()) ;
1788 // Construct chi2 while substituting original RangeWithName argument with subrange argument created above
1789 RooAbsReal* chi2Comp = new RooChi2Var(Form("%s_%s", baseName.c_str(), token.c_str()), "chi^2", *this, data,
1790 &arg1==rarg?subRangeCmd:arg1,&arg2==rarg?subRangeCmd:arg2,
1791 &arg3==rarg?subRangeCmd:arg3,&arg4==rarg?subRangeCmd:arg4,
1792 &arg5==rarg?subRangeCmd:arg5,&arg6==rarg?subRangeCmd:arg6,
1793 &arg7==rarg?subRangeCmd:arg7,&arg8==rarg?subRangeCmd:arg8) ;
1794 chi2List.add(*chi2Comp) ;
1795 }
1796 chi2 = new RooAddition(baseName.c_str(),"chi^2",chi2List,kTRUE) ;
1797 }
1799
1800
1801 return chi2 ;
1802}
1803
1804
1805
1806
1807////////////////////////////////////////////////////////////////////////////////
1808/// Argument-list version of RooAbsPdf::createChi2()
1809
1811{
1812 // Select the pdf-specific commands
1813 RooCmdConfig pc(Form("RooAbsPdf::createChi2(%s)",GetName())) ;
1814
1815 pc.defineInt("integrate","Integrate",0,0) ;
1816 pc.defineObject("yvar","YVar",0,0) ;
1817
1818 // Process and check varargs
1819 pc.process(cmdList) ;
1820 if (!pc.ok(kTRUE)) {
1821 return 0 ;
1822 }
1823
1824 // Decode command line arguments
1825 Bool_t integrate = pc.getInt("integrate") ;
1826 RooRealVar* yvar = (RooRealVar*) pc.getObject("yvar") ;
1827
1828 string name = Form("chi2_%s_%s",GetName(),data.GetName()) ;
1829
1830 if (yvar) {
1831 return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,*yvar,integrate) ;
1832 } else {
1833 return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,integrate) ;
1834 }
1835}
1836
1837
1838
1839
1840////////////////////////////////////////////////////////////////////////////////
1841/// Print value of p.d.f, also print normalization integral that was last used, if any
1842
1843void RooAbsPdf::printValue(ostream& os) const
1844{
1845 // silent warning messages coming when evaluating a RooAddPdf without a normalization set
1847
1848 getVal() ;
1849
1850 if (_norm) {
1851 os << evaluate() << "/" << _norm->getVal() ;
1852 } else {
1853 os << evaluate() ;
1854 }
1855}
1856
1857
1858
1859////////////////////////////////////////////////////////////////////////////////
1860/// Print multi line detailed information of this RooAbsPdf
1861
1862void RooAbsPdf::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
1863{
1865 os << indent << "--- RooAbsPdf ---" << endl;
1866 os << indent << "Cached value = " << _value << endl ;
1867 if (_norm) {
1868 os << indent << " Normalization integral: " << endl ;
1869 auto moreIndent = std::string(indent.Data()) + " " ;
1870 _norm->printStream(os,kName|kAddress|kTitle|kValue|kArgs,kSingleLine,moreIndent.c_str()) ;
1871 }
1872}
1873
1874
1875
1876////////////////////////////////////////////////////////////////////////////////
1877/// Return a binned generator context
1878
1880{
1881 return new RooBinnedGenContext(*this,vars,0,0,verbose) ;
1882}
1883
1884
1885////////////////////////////////////////////////////////////////////////////////
1886/// Interface function to create a generator context from a p.d.f. This default
1887/// implementation returns a 'standard' context that works for any p.d.f
1888
1890 const RooArgSet* auxProto, Bool_t verbose) const
1891{
1892 return new RooGenContext(*this,vars,prototype,auxProto,verbose) ;
1893}
1894
1895
1896////////////////////////////////////////////////////////////////////////////////
1897
1898RooAbsGenContext* RooAbsPdf::autoGenContext(const RooArgSet &vars, const RooDataSet* prototype, const RooArgSet* auxProto,
1899 Bool_t verbose, Bool_t autoBinned, const char* binnedTag) const
1900{
1901 if (prototype || (auxProto && auxProto->getSize()>0)) {
1902 return genContext(vars,prototype,auxProto,verbose);
1903 }
1904
1905 RooAbsGenContext *context(0) ;
1906 if ( (autoBinned && isBinnedDistribution(vars)) || ( binnedTag && strlen(binnedTag) && (getAttribute(binnedTag)||string(binnedTag)=="*"))) {
1907 context = binnedGenContext(vars,verbose) ;
1908 } else {
1909 context= genContext(vars,0,0,verbose);
1910 }
1911 return context ;
1912}
1913
1914
1915
1916////////////////////////////////////////////////////////////////////////////////
1917/// Generate a new dataset containing the specified variables with events sampled from our distribution.
1918/// Generate the specified number of events or expectedEvents() if not specified.
1919/// \param[in] whatVars Choose variables in which to generate events. Variables not listed here will remain
1920/// constant and not be used for event generation.
1921/// \param[in] argxx Optional RooCmdArg() to change behaviour of generate().
1922/// \return RooDataSet *, owned by caller.
1923///
1924/// Any variables of this PDF that are not in whatVars will use their
1925/// current values and be treated as fixed parameters. Returns zero
1926/// in case of an error.
1927///
1928/// <table>
1929/// <tr><th> Type of CmdArg <th> Effect on generate
1930/// <tr><td> `Name(const char* name)` <td> Name of the output dataset
1931/// <tr><td> `Verbose(Bool_t flag)` <td> Print informational messages during event generation
1932/// <tr><td> `NumEvent(int nevt)` <td> Generate specified number of events
1933/// <tr><td> `Extended()` <td> If no number of events to be generated is given,
1934/// use expected number of events from extended likelihood term.
1935/// This evidently only works for extended PDFs.
1936/// <tr><td> `GenBinned(const char* tag)` <td> Use binned generation for all component pdfs that have 'setAttribute(tag)' set
1937/// <tr><td> `AutoBinned(Bool_t flag)` <td> Automatically deploy binned generation for binned distributions (e.g. RooHistPdf, sums and products of
1938/// RooHistPdfs etc)
1939/// \note Datasets that are generated in binned mode are returned as weighted unbinned datasets. This means that
1940/// for each bin, there will be one event in the dataset with a weight corresponding to the (possibly randomised) bin content.
1941///
1942///
1943/// <tr><td> `AllBinned()` <td> As above, but for all components.
1944/// \note The notion of components is only meaningful for simultaneous PDFs
1945/// as binned generation is always executed at the top-level node for a regular
1946/// PDF, so for those it only mattes that the top-level node is tagged.
1947///
1948/// <tr><td> ProtoData(const RooDataSet& data, Bool_t randOrder)
1949/// <td> Use specified dataset as prototype dataset. If randOrder in ProtoData() is set to true,
1950/// the order of the events in the dataset will be read in a random order if the requested
1951/// number of events to be generated does not match the number of events in the prototype dataset.
1952/// \note If ProtoData() is used, the specified existing dataset as a prototype: the new dataset will contain
1953/// the same number of events as the prototype (unless otherwise specified), and any prototype variables not in
1954/// whatVars will be copied into the new dataset for each generated event and also used to set our PDF parameters.
1955/// The user can specify a number of events to generate that will override the default. The result is a
1956/// copy of the prototype dataset with only variables in whatVars randomized. Variables in whatVars that
1957/// are not in the prototype will be added as new columns to the generated dataset.
1958///
1959/// </table>
1960///
1961/// #### Accessing the underlying event generator
1962/// Depending on the fit model (if it is difficult to sample), it may be necessary to change generator settings.
1963/// For the default generator (RooFoamGenerator), the number of samples or cells could be increased by e.g. using
1964/// myPdf->specialGeneratorConfig()->getConfigSection("RooFoamGenerator").setRealValue("nSample",1e4);
1965///
1966/// The foam generator e.g. has the following config options:
1967/// - nCell[123N]D
1968/// - nSample
1969/// - chatLevel
1970/// \see rf902_numgenconfig.C
1971
1972RooDataSet *RooAbsPdf::generate(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
1973 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
1974{
1975 // Select the pdf-specific commands
1976 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
1977 pc.defineObject("proto","PrototypeData",0,0) ;
1978 pc.defineString("dsetName","Name",0,"") ;
1979 pc.defineInt("randProto","PrototypeData",0,0) ;
1980 pc.defineInt("resampleProto","PrototypeData",1,0) ;
1981 pc.defineInt("verbose","Verbose",0,0) ;
1982 pc.defineInt("extended","Extended",0,0) ;
1983 pc.defineInt("nEvents","NumEvents",0,0) ;
1984 pc.defineInt("autoBinned","AutoBinned",0,1) ;
1985 pc.defineInt("expectedData","ExpectedData",0,0) ;
1986 pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
1987 pc.defineString("binnedTag","GenBinned",0,"") ;
1988 pc.defineMutex("GenBinned","ProtoData") ;
1989 pc.defineMutex("Extended", "NumEvents");
1990
1991 // Process and check varargs
1992 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
1993 if (!pc.ok(kTRUE)) {
1994 return 0 ;
1995 }
1996
1997 // Decode command line arguments
1998 RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
1999 const char* dsetName = pc.getString("dsetName") ;
2000 Bool_t verbose = pc.getInt("verbose") ;
2001 Bool_t randProto = pc.getInt("randProto") ;
2002 Bool_t resampleProto = pc.getInt("resampleProto") ;
2003 Bool_t extended = pc.getInt("extended") ;
2004 Bool_t autoBinned = pc.getInt("autoBinned") ;
2005 const char* binnedTag = pc.getString("binnedTag") ;
2006 Int_t nEventsI = pc.getInt("nEvents") ;
2007 Double_t nEventsD = pc.getInt("nEventsD") ;
2008 //Bool_t verbose = pc.getInt("verbose") ;
2009 Bool_t expectedData = pc.getInt("expectedData") ;
2010
2011 Double_t nEvents = (nEventsD>0) ? nEventsD : Double_t(nEventsI);
2012
2013 // Force binned mode for expected data mode
2014 if (expectedData) {
2015 binnedTag="*" ;
2016 }
2017
2018 if (extended) {
2019 if (nEvents == 0) nEvents = expectedEvents(&whatVars);
2020 } else if (nEvents==0) {
2021 cxcoutI(Generation) << "No number of events specified , number of events generated is "
2022 << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
2023 }
2024
2025 if (extended && protoData && !randProto) {
2026 cxcoutI(Generation) << "WARNING Using generator option Extended() (Poisson distribution of #events) together "
2027 << "with a prototype dataset implies incomplete sampling or oversampling of proto data. "
2028 << "Set randomize flag in ProtoData() option to randomize prototype dataset order and thus "
2029 << "to randomize the set of over/undersampled prototype events for each generation cycle." << endl ;
2030 }
2031
2032
2033 // Forward to appropriate implementation
2034 RooDataSet* data ;
2035 if (protoData) {
2036 data = generate(whatVars,*protoData,Int_t(nEvents),verbose,randProto,resampleProto) ;
2037 } else {
2038 data = generate(whatVars,nEvents,verbose,autoBinned,binnedTag,expectedData, extended) ;
2039 }
2040
2041 // Rename dataset to given name if supplied
2042 if (dsetName && strlen(dsetName)>0) {
2043 data->SetName(dsetName) ;
2044 }
2045
2046 return data ;
2047}
2048
2049
2050
2051
2052
2053
2054////////////////////////////////////////////////////////////////////////////////
2055/// \note This method does not perform any generation. To generate according to generations specification call RooAbsPdf::generate(RooAbsPdf::GenSpec&) const
2056///
2057/// Details copied from RooAbsPdf::generate():
2058/// --------------------------------------------
2059/// \copydetails RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
2060
2062 const RooCmdArg& arg1,const RooCmdArg& arg2,
2063 const RooCmdArg& arg3,const RooCmdArg& arg4,
2064 const RooCmdArg& arg5,const RooCmdArg& arg6)
2065{
2066
2067 // Select the pdf-specific commands
2068 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
2069 pc.defineObject("proto","PrototypeData",0,0) ;
2070 pc.defineString("dsetName","Name",0,"") ;
2071 pc.defineInt("randProto","PrototypeData",0,0) ;
2072 pc.defineInt("resampleProto","PrototypeData",1,0) ;
2073 pc.defineInt("verbose","Verbose",0,0) ;
2074 pc.defineInt("extended","Extended",0,0) ;
2075 pc.defineInt("nEvents","NumEvents",0,0) ;
2076 pc.defineInt("autoBinned","AutoBinned",0,1) ;
2077 pc.defineString("binnedTag","GenBinned",0,"") ;
2078 pc.defineMutex("GenBinned","ProtoData") ;
2079
2080
2081 // Process and check varargs
2082 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
2083 if (!pc.ok(kTRUE)) {
2084 return 0 ;
2085 }
2086
2087 // Decode command line arguments
2088 RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
2089 const char* dsetName = pc.getString("dsetName") ;
2090 Int_t nEvents = pc.getInt("nEvents") ;
2091 Bool_t verbose = pc.getInt("verbose") ;
2092 Bool_t randProto = pc.getInt("randProto") ;
2093 Bool_t resampleProto = pc.getInt("resampleProto") ;
2094 Bool_t extended = pc.getInt("extended") ;
2095 Bool_t autoBinned = pc.getInt("autoBinned") ;
2096 const char* binnedTag = pc.getString("binnedTag") ;
2097
2098 RooAbsGenContext* cx = autoGenContext(whatVars,protoData,0,verbose,autoBinned,binnedTag) ;
2099
2100 return new GenSpec(cx,whatVars,protoData,nEvents,extended,randProto,resampleProto,dsetName) ;
2101}
2102
2103
2104////////////////////////////////////////////////////////////////////////////////
2105/// If many identical generation requests
2106/// are needed, e.g. in toy MC studies, it is more efficient to use the prepareMultiGen()/generate()
2107/// combination than calling the standard generate() multiple times as
2108/// initialization overhead is only incurred once.
2109
2111{
2112 //Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen) : spec._nGen ;
2113 //Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen==0?expectedEvents(spec._whatVars):spec._nGen) : spec._nGen ;
2114 //Int_t nEvt = spec._nGen == 0 ? RooRandom::randomGenerator()->Poisson(expectedEvents(spec._whatVars)) : spec._nGen;
2115
2116 Double_t nEvt = spec._nGen == 0 ? expectedEvents(spec._whatVars) : spec._nGen;
2117
2118 RooDataSet* ret = generate(*spec._genContext,spec._whatVars,spec._protoData, nEvt,kFALSE,spec._randProto,spec._resampleProto,
2119 spec._init,spec._extended) ;
2120 spec._init = kTRUE ;
2121 return ret ;
2122}
2123
2124
2125
2126
2127
2128////////////////////////////////////////////////////////////////////////////////
2129/// Generate a new dataset containing the specified variables with
2130/// events sampled from our distribution.
2131///
2132/// \param[in] whatVars Generate a dataset with the variables (and categories) in this set.
2133/// Any variables of this PDF that are not in `whatVars` will use their
2134/// current values and be treated as fixed parameters.
2135/// \param[in] nEvents Generate the specified number of events or else try to use
2136/// expectedEvents() if nEvents <= 0 (default).
2137/// \param[in] verbose Show which generator strategies are being used.
2138/// \param[in] autoBinned If original distribution is binned, return bin centers and randomise weights
2139/// instead of generating single events.
2140/// \param[in] binnedTag
2141/// \param[in] expectedData Call setExpectedData on the genContext.
2142/// \param[in] extended Randomise number of events generated according to Poisson(nEvents). Only useful
2143/// if PDF is extended.
2144/// \return New dataset. Returns zero in case of an error. The caller takes ownership of the returned
2145/// dataset.
2146
2147RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, Double_t nEvents, Bool_t verbose, Bool_t autoBinned, const char* binnedTag, Bool_t expectedData, Bool_t extended) const
2148{
2149 if (nEvents==0 && extendMode()==CanNotBeExtended) {
2150 return new RooDataSet("emptyData","emptyData",whatVars) ;
2151 }
2152
2153 // Request for binned generation
2154 RooAbsGenContext *context = autoGenContext(whatVars,0,0,verbose,autoBinned,binnedTag) ;
2155 if (expectedData) {
2156 context->setExpectedData(kTRUE) ;
2157 }
2158
2159 RooDataSet *generated = 0;
2160 if(0 != context && context->isValid()) {
2161 generated= context->generate(nEvents, kFALSE, extended);
2162 }
2163 else {
2164 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") cannot create a valid context" << endl;
2165 }
2166 if(0 != context) delete context;
2167 return generated;
2168}
2169
2170
2171
2172
2173////////////////////////////////////////////////////////////////////////////////
2174/// Internal method
2175
2176RooDataSet *RooAbsPdf::generate(RooAbsGenContext& context, const RooArgSet &whatVars, const RooDataSet *prototype,
2177 Double_t nEvents, Bool_t /*verbose*/, Bool_t randProtoOrder, Bool_t resampleProto,
2178 Bool_t skipInit, Bool_t extended) const
2179{
2180 if (nEvents==0 && (prototype==0 || prototype->numEntries()==0)) {
2181 return new RooDataSet("emptyData","emptyData",whatVars) ;
2182 }
2183
2184 RooDataSet *generated = 0;
2185
2186 // Resampling implies reshuffling in the implementation
2187 if (resampleProto) {
2188 randProtoOrder=kTRUE ;
2189 }
2190
2191 if (randProtoOrder && prototype && prototype->numEntries()!=nEvents) {
2192 coutI(Generation) << "RooAbsPdf::generate (Re)randomizing event order in prototype dataset (Nevt=" << nEvents << ")" << endl ;
2193 Int_t* newOrder = randomizeProtoOrder(prototype->numEntries(),Int_t(nEvents),resampleProto) ;
2194 context.setProtoDataOrder(newOrder) ;
2195 delete[] newOrder ;
2196 }
2197
2198 if(context.isValid()) {
2199 generated= context.generate(nEvents,skipInit,extended);
2200 }
2201 else {
2202 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") do not have a valid generator context" << endl;
2203 }
2204 return generated;
2205}
2206
2207
2208
2209
2210////////////////////////////////////////////////////////////////////////////////
2211/// Generate a new dataset using a prototype dataset as a model,
2212/// with values of the variables in `whatVars` sampled from our distribution.
2213///
2214/// \param[in] whatVars Generate for these variables.
2215/// \param[in] prototype Use this dataset
2216/// as a prototype: the new dataset will contain the same number of
2217/// events as the prototype (by default), and any prototype variables not in
2218/// whatVars will be copied into the new dataset for each generated
2219/// event and also used to set our PDF parameters. The user can specify a
2220/// number of events to generate that will override the default. The result is a
2221/// copy of the prototype dataset with only variables in whatVars
2222/// randomized. Variables in whatVars that are not in the prototype
2223/// will be added as new columns to the generated dataset.
2224/// \param[in] nEvents Number of events to generate. Defaults to 0, which means number
2225/// of event in prototype dataset.
2226/// \param[in] verbose Show which generator strategies are being used.
2227/// \param[in] randProtoOrder Randomise order of retrieval of events from proto dataset.
2228/// \param[in] resampleProto Resample from the proto dataset.
2229/// \return The new dataset. Returns zero in case of an error. The caller takes ownership of the
2230/// returned dataset.
2231
2232RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, const RooDataSet& prototype,
2233 Int_t nEvents, Bool_t verbose, Bool_t randProtoOrder, Bool_t resampleProto) const
2234{
2235 RooAbsGenContext *context= genContext(whatVars,&prototype,0,verbose);
2236 if (context) {
2237 RooDataSet* data = generate(*context,whatVars,&prototype,nEvents,verbose,randProtoOrder,resampleProto) ;
2238 delete context ;
2239 return data ;
2240 } else {
2241 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") ERROR creating generator context" << endl ;
2242 return 0 ;
2243 }
2244}
2245
2246
2247
2248////////////////////////////////////////////////////////////////////////////////
2249/// Return lookup table with randomized order for nProto prototype events.
2250
2252{
2253 // Make output list
2254 Int_t* lut = new Int_t[nProto] ;
2255
2256 // Randomly sample input list into output list
2257 if (!resampleProto) {
2258 // In this mode, randomization is a strict reshuffle of the order
2259 std::iota(lut, lut + nProto, 0); // fill the vector with 0 to nProto - 1
2260 // Shuffle code taken from https://en.cppreference.com/w/cpp/algorithm/random_shuffle.
2261 // The std::random_shuffle function was deprecated in C++17. We could have
2262 // used std::shuffle instead, but this is not straight-forward to use with
2263 // RooRandom::integer() and we didn't want to change the random number
2264 // generator. It might cause unwanted effects like reproducibility problems.
2265 for (int i = nProto-1; i > 0; --i) {
2266 std::swap(lut[i], lut[RooRandom::integer(i+1)]);
2267 }
2268 } else {
2269 // In this mode, we resample, i.e. events can be used more than once
2270 std::generate(lut, lut + nProto, [&]{ return RooRandom::integer(nProto); });
2271 }
2272
2273
2274 return lut ;
2275}
2276
2277
2278
2279////////////////////////////////////////////////////////////////////////////////
2280/// Load generatedVars with the subset of directVars that we can generate events for,
2281/// and return a code that specifies the generator algorithm we will use. A code of
2282/// zero indicates that we cannot generate any of the directVars (in this case, nothing
2283/// should be added to generatedVars). Any non-zero codes will be passed to our generateEvent()
2284/// implementation, but otherwise its value is arbitrary. The default implemetation of
2285/// this method returns zero. Subclasses will usually implement this method using the
2286/// matchArgs() methods to advertise the algorithms they provide.
2287
2288Int_t RooAbsPdf::getGenerator(const RooArgSet &/*directVars*/, RooArgSet &/*generatedVars*/, Bool_t /*staticInitOK*/) const
2289{
2290 return 0 ;
2291}
2292
2293
2294
2295////////////////////////////////////////////////////////////////////////////////
2296/// Interface for one-time initialization to setup the generator for the specified code.
2297
2299{
2300}
2301
2302
2303
2304////////////////////////////////////////////////////////////////////////////////
2305/// Interface for generation of an event using the algorithm
2306/// corresponding to the specified code. The meaning of each code is
2307/// defined by the getGenerator() implementation. The default
2308/// implementation does nothing.
2309
2311{
2312}
2313
2314
2315
2316////////////////////////////////////////////////////////////////////////////////
2317/// Check if given observable can be safely generated using the
2318/// pdfs internal generator mechanism (if that existsP). Observables
2319/// on which a PDF depends via more than route are not safe
2320/// for use with internal generators because they introduce
2321/// correlations not known to the internal generator
2322
2324{
2325 // Arg must be direct server of self
2326 if (!findServer(arg.GetName())) return kFALSE ;
2327
2328 // There must be no other dependency routes
2329 for (const auto server : _serverList) {
2330 if(server == &arg) continue;
2331 if(server->dependsOn(arg)) {
2332 return kFALSE ;
2333 }
2334 }
2335
2336 return kTRUE ;
2337}
2338
2339
2340////////////////////////////////////////////////////////////////////////////////
2341/// Generate a new dataset containing the specified variables with events sampled from our distribution.
2342/// \param[in] whatVars Choose variables in which to generate events. Variables not listed here will remain
2343/// constant and not be used for event generation
2344/// \param[in] arg1 Optional RooCmdArg to change behaviour of generateBinned()
2345/// \return RooDataHist *, to be managed by caller.
2346///
2347/// Generate the specified number of events or expectedEvents() if not specified.
2348///
2349/// Any variables of this PDF that are not in whatVars will use their
2350/// current values and be treated as fixed parameters. Returns zero
2351/// in case of an error. The caller takes ownership of the returned
2352/// dataset.
2353///
2354/// The following named arguments are supported
2355/// | Type of CmdArg | Effect on generation
2356/// |-------------------------|-----------------------
2357/// | `Name(const char* name)` | Name of the output dataset
2358/// | `Verbose(Bool_t flag)` | Print informational messages during event generation
2359/// | `NumEvent(int nevt)` | Generate specified number of events
2360/// | `Extended()` | The actual number of events generated will be sampled from a Poisson distribution with mu=nevt.
2361/// This can be *much* faster for peaked PDFs, but the number of events is not exactly what was requested.
2362/// | `ExpectedData()` | Return a binned dataset _without_ statistical fluctuations (also aliased as Asimov())
2363///
2364
2365RooDataHist *RooAbsPdf::generateBinned(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
2366 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6) const
2367{
2368
2369 // Select the pdf-specific commands
2370 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
2371 pc.defineString("dsetName","Name",0,"") ;
2372 pc.defineInt("verbose","Verbose",0,0) ;
2373 pc.defineInt("extended","Extended",0,0) ;
2374 pc.defineInt("nEvents","NumEvents",0,0) ;
2375 pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
2376 pc.defineInt("expectedData","ExpectedData",0,0) ;
2377
2378 // Process and check varargs
2379 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
2380 if (!pc.ok(kTRUE)) {
2381 return 0 ;
2382 }
2383
2384 // Decode command line arguments
2385 Double_t nEvents = pc.getDouble("nEventsD") ;
2386 if (nEvents<0) {
2387 nEvents = pc.getInt("nEvents") ;
2388 }
2389 //Bool_t verbose = pc.getInt("verbose") ;
2390 Bool_t extended = pc.getInt("extended") ;
2391 Bool_t expectedData = pc.getInt("expectedData") ;
2392 const char* dsetName = pc.getString("dsetName") ;
2393
2394 if (extended) {
2395 //nEvents = (nEvents==0?Int_t(expectedEvents(&whatVars)+0.5):nEvents) ;
2396 nEvents = (nEvents==0 ? expectedEvents(&whatVars) :nEvents) ;
2397 cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
2398 << GetName() << "::expectedEvents() = " << nEvents << endl ;
2399 // If Poisson fluctuation results in zero events, stop here
2400 if (nEvents==0) {
2401 return 0 ;
2402 }
2403 } else if (nEvents==0) {
2404 cxcoutI(Generation) << "No number of events specified , number of events generated is "
2405 << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
2406 }
2407
2408 // Forward to appropriate implementation
2409 RooDataHist* data = generateBinned(whatVars,nEvents,expectedData,extended) ;
2410
2411 // Rename dataset to given name if supplied
2412 if (dsetName && strlen(dsetName)>0) {
2413 data->SetName(dsetName) ;
2414 }
2415
2416 return data ;
2417}
2418
2419
2420
2421
2422////////////////////////////////////////////////////////////////////////////////
2423/// Generate a new dataset containing the specified variables with
2424/// events sampled from our distribution.
2425///
2426/// \param[in] whatVars Variables that values should be generated for.
2427/// \param[in] nEvents How many events to generate. If `nEvents <=0`, use the value returned by expectedEvents() as target.
2428/// \param[in] expectedData If set to true (false by default), the returned histogram returns the 'expected'
2429/// data sample, i.e. no statistical fluctuations are present.
2430/// \param[in] extended For each bin, generate Poisson(x, mu) events, where `mu` is chosen such that *on average*,
2431/// one would obtain `nEvents` events. This means that the true number of events will fluctuate around the desired value,
2432/// but the generation happens a lot faster.
2433/// Especially if the PDF is sharply peaked, the multinomial event generation necessary to generate *exactly* `nEvents` events can
2434/// be very slow.
2435///
2436/// The binning used for generation of events is the currently set binning for the variables.
2437/// It can e.g. be changed using
2438/// ```
2439/// x.setBins(15);
2440/// x.setRange(-5., 5.);
2441/// pdf.generateBinned(RooArgSet(x), 1000);
2442/// ```
2443///
2444/// Any variables of this PDF that are not in `whatVars` will use their
2445/// current values and be treated as fixed parameters.
2446/// \return RooDataHist* owned by the caller. Returns `nullptr` in case of an error.
2447RooDataHist *RooAbsPdf::generateBinned(const RooArgSet &whatVars, Double_t nEvents, Bool_t expectedData, Bool_t extended) const
2448{
2449 // Create empty RooDataHist
2450 RooDataHist* hist = new RooDataHist("genData","genData",whatVars) ;
2451
2452 // Scale to number of events and introduce Poisson fluctuations
2453 if (nEvents<=0) {
2454 if (!canBeExtended()) {
2455 coutE(InputArguments) << "RooAbsPdf::generateBinned(" << GetName() << ") ERROR: No event count provided and p.d.f does not provide expected number of events" << endl ;
2456 delete hist ;
2457 return 0 ;
2458 } else {
2459
2460 // Don't round in expectedData or extended mode
2461 if (expectedData || extended) {
2462 nEvents = expectedEvents(&whatVars) ;
2463 } else {
2464 nEvents = std::round(expectedEvents(&whatVars));
2465 }
2466 }
2467 }
2468
2469 // Sample p.d.f. distribution
2470 fillDataHist(hist,&whatVars,1,kTRUE) ;
2471
2472 vector<int> histOut(hist->numEntries()) ;
2473 Double_t histMax(-1) ;
2474 Int_t histOutSum(0) ;
2475 for (int i=0 ; i<hist->numEntries() ; i++) {
2476 hist->get(i) ;
2477 if (expectedData) {
2478
2479 // Expected data, multiply p.d.f by nEvents
2480 Double_t w=hist->weight()*nEvents ;
2481 hist->set(i, w, sqrt(w));
2482
2483 } else if (extended) {
2484
2485 // Extended mode, set contents to Poisson(pdf*nEvents)
2486 Double_t w = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
2487 hist->set(w,sqrt(w)) ;
2488
2489 } else {
2490
2491 // Regular mode, fill array of weights with Poisson(pdf*nEvents), but to not fill
2492 // histogram yet.
2493 if (hist->weight()>histMax) {
2494 histMax = hist->weight() ;
2495 }
2496 histOut[i] = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
2497 histOutSum += histOut[i] ;
2498 }
2499 }
2500
2501
2502 if (!expectedData && !extended) {
2503
2504 // Second pass for regular mode - Trim/Extend dataset to exact number of entries
2505
2506 // Calculate difference between what is generated so far and what is requested
2507 Int_t nEvtExtra = abs(Int_t(nEvents)-histOutSum) ;
2508 Int_t wgt = (histOutSum>nEvents) ? -1 : 1 ;
2509
2510 // Perform simple binned accept/reject procedure to get to exact event count
2511 std::size_t counter = 0;
2512 bool havePrintedInfo = false;
2513 while(nEvtExtra>0) {
2514
2515 Int_t ibinRand = RooRandom::randomGenerator()->Integer(hist->numEntries()) ;
2516 hist->get(ibinRand) ;
2517 Double_t ranY = RooRandom::randomGenerator()->Uniform(histMax) ;
2518
2519 if (ranY<hist->weight()) {
2520 if (wgt==1) {
2521 histOut[ibinRand]++ ;
2522 } else {
2523 // If weight is negative, prior bin content must be at least 1
2524 if (histOut[ibinRand]>0) {
2525 histOut[ibinRand]-- ;
2526 } else {
2527 continue ;
2528 }
2529 }
2530 nEvtExtra-- ;
2531 }
2532
2533 if ((counter++ > 10*nEvents || nEvents > 1.E7) && !havePrintedInfo) {
2534 havePrintedInfo = true;
2535 coutP(Generation) << "RooAbsPdf::generateBinned(" << GetName() << ") Performing costly accept/reject sampling. If this takes too long, use "
2536 << "extended mode to speed up the process." << std::endl;
2537 }
2538 }
2539
2540 // Transfer working array to histogram
2541 for (int i=0 ; i<hist->numEntries() ; i++) {
2542 hist->get(i) ;
2543 hist->set(histOut[i],sqrt(1.0*histOut[i])) ;
2544 }
2545
2546 } else if (expectedData) {
2547
2548 // Second pass for expectedData mode -- Normalize to exact number of requested events
2549 // Minor difference may be present in first round due to difference between
2550 // bin average and bin integral in sampling bins
2551 Double_t corr = nEvents/hist->sumEntries() ;
2552 for (int i=0 ; i<hist->numEntries() ; i++) {
2553 hist->get(i) ;
2554 hist->set(hist->weight()*corr,sqrt(hist->weight()*corr)) ;
2555 }
2556
2557 }
2558
2559 return hist;
2560}
2561
2562
2563
2564////////////////////////////////////////////////////////////////////////////////
2565/// Special generator interface for generation of 'global observables' -- for RooStats tools
2566
2568{
2569 return generate(whatVars,nEvents) ;
2570}
2571
2572namespace {
2573void removeRangeOverlap(std::vector<std::pair<double, double>>& ranges) {
2574 //Sort from left to right
2575 std::sort(ranges.begin(), ranges.end());
2576
2577 for (auto it = ranges.begin(); it != ranges.end(); ++it) {
2578 double& startL = it->first;
2579 double& endL = it->second;
2580
2581 for (auto innerIt = it+1; innerIt != ranges.end(); ++innerIt) {
2582 const double startR = innerIt->first;
2583 const double endR = innerIt->second;
2584
2585 if (startL <= startR && startR <= endL) {
2586 //Overlapping ranges, extend left one
2587 endL = std::max(endL, endR);
2588 *innerIt = make_pair(0., 0.);
2589 }
2590 }
2591 }
2592
2593 auto newEnd = std::remove_if(ranges.begin(), ranges.end(),
2594 [](const std::pair<double,double>& input){
2595 return input.first == input.second;
2596 });
2597 ranges.erase(newEnd, ranges.end());
2598}
2599}
2600
2601
2602////////////////////////////////////////////////////////////////////////////////
2603/// Plot (project) PDF on specified frame.
2604/// - If a PDF is plotted in an empty frame, it
2605/// will show a unit-normalized curve in the frame variable. When projecting a multi-
2606/// dimensional PDF onto the frame axis, hidden parameters are taken are taken at
2607/// their current value.
2608/// - If a PDF is plotted in a frame in which a dataset has already been plotted, it will
2609/// show a projection integrated over all variables that were present in the shown
2610/// dataset (except for the one on the x-axis). The normalization of the curve will
2611/// be adjusted to the event count of the plotted dataset. An informational message
2612/// will be printed for each projection step that is performed.
2613/// - If a PDF is plotted in a frame showing a dataset *after* a fit, the above happens,
2614/// but the PDF will be drawn and normalised only in the fit range. If this is not desired,
2615/// plotting and normalisation range can be overridden using Range() and NormRange() as
2616/// documented in the table below.
2617///
2618/// This function takes the following named arguments (for more arguments, see also
2619/// RooAbsReal::plotOn(RooPlot*,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,
2620/// const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,
2621/// const RooCmdArg&) const )
2622///
2623///
2624/// <table>
2625/// <tr><th> Type of argument <th> Controlling normalisation
2626/// <tr><td> `NormRange(const char* name)` <td> Calculate curve normalization w.r.t. specified range[s].
2627/// See the tutorial rf212_plottingInRanges_blinding.C
2628/// \note Setting a Range() by default also sets a NormRange() on the same range, meaning that the
2629/// PDF is plotted and normalised in the same range. Overriding this can be useful if the PDF was fit
2630/// in limited range[s] such as side bands, `NormRange("sidebandLeft,sidebandRight")`, but the PDF
2631/// should be drawn in the full range, `Range("")`.
2632///
2633/// <tr><td> `Normalization(Double_t scale, ScaleType code)` <td> Adjust normalization by given scale factor.
2634/// Interpretation of number depends on code:
2635/// `RooAbsReal::Relative`: relative adjustment factor
2636/// `RooAbsReal::NumEvent`: scale to match given number of events.
2637///
2638/// <tr><th> Type of argument <th> Misc control
2639/// <tr><td> `Name(const chat* name)` <td> Give curve specified name in frame. Useful if curve is to be referenced later
2640/// <tr><td> `Asymmetry(const RooCategory& c)` <td> Show the asymmetry of the PDF in given two-state category
2641/// \f$ \frac{F(+)-F(-)}{F(+)+F(-)} \f$ rather than the PDF projection. Category must have two
2642/// states with indices -1 and +1 or three states with indeces -1,0 and +1.
2643/// <tr><td> `ShiftToZero(Bool_t flag)` <td> Shift entire curve such that lowest visible point is at exactly zero.
2644/// Mostly useful when plotting -log(L) or \f$ \chi^2 \f$ distributions
2645/// <tr><td> `AddTo(const char* name, double_t wgtSelf, double_t wgtOther)` <td> Create a projection of this PDF onto the x-axis, but
2646/// instead of plotting it directly, add it to an existing curve with given name (and relative weight factors).
2647/// <tr><td> `Components(const char* names)` <td> When plotting sums of PDFs, plot only the named components (*e.g.* only
2648/// the signal of a signal+background model).
2649/// <tr><td> `Components(const RooArgSet& compSet)` <td> As above, but pass a RooArgSet of the components themselves.
2650///
2651/// <tr><th> Type of argument <th> Projection control
2652/// <tr><td> `Slice(const RooArgSet& set)` <td> Override default projection behaviour by omitting observables listed
2653/// in set from the projection, i.e. by not integrating over these.
2654/// Slicing is usually only sensible in discrete observables, by e.g. creating a slice
2655/// of the PDF at the current value of the category observable.
2656/// <tr><td> `Slice(RooCategory& cat, const char* label)` <td> Override default projection behaviour by omitting the specified category
2657/// observable from the projection, i.e., by not integrating over all states of this category.
2658/// The slice is positioned at the given label value. Multiple Slice() commands can be given to specify slices
2659/// in multiple observables, e.g.
2660/// ```{.cpp}
2661/// pdf.plotOn(frame, Slice(tagCategory, "2tag"), Slice(jetCategory, "3jet"));
2662/// ```
2663/// <tr><td> `Project(const RooArgSet& set)` <td> Override default projection behaviour by projecting
2664/// over observables given in set, completely ignoring the default projection behavior. Advanced use only.
2665/// <tr><td> `ProjWData(const RooAbsData& d)` <td> Override default projection _technique_ (integration). For observables
2666/// present in given dataset projection of PDF is achieved by constructing an average over all observable
2667/// values in given set. Consult RooFit plotting tutorial for further explanation of meaning & use of this technique
2668/// <tr><td> `ProjWData(const RooArgSet& s, const RooAbsData& d)` <td> As above but only consider subset 's' of
2669/// observables in dataset 'd' for projection through data averaging
2670/// <tr><td> `ProjectionRange(const char* rn)` <td> When projecting the PDF onto the plot axis, it is usually integrated
2671/// over the full range of the invisible variables. The ProjectionRange overrides this.
2672/// This is useful if the PDF was fitted in a limited range in y, but it is now projected onto x. If
2673/// `ProjectionRange("<name of fit range>")` is passed, the projection is normalised correctly.
2674///
2675/// <tr><th> Type of argument <th> Plotting control
2676/// <tr><td> `LineStyle(Int_t style)` <td> Select line style by ROOT line style code, default is solid
2677/// <tr><td> `LineColor(Int_t color)` <td> Select line color by ROOT color code, default is blue
2678/// <tr><td> `LineWidth(Int_t width)` <td> Select line with in pixels, default is 3
2679/// <tr><td> `FillStyle(Int_t style)` <td> Select fill style, default is not filled. If a filled style is selected,
2680/// also use VLines() to add vertical downward lines at end of curve to ensure proper closure
2681/// <tr><td> `FillColor(Int_t color)` <td> Select fill color by ROOT color code
2682/// <tr><td> `Range(const char* name)` <td> Only draw curve in range defined by given name. Multiple comma-separated ranges can be given.
2683/// An empty string "" or `nullptr` means to use the default range of the variable.
2684/// <tr><td> `Range(double lo, double hi)` <td> Only draw curve in specified range
2685/// <tr><td> `VLines()` <td> Add vertical lines to y=0 at end points of curve
2686/// <tr><td> `Precision(Double_t eps)` <td> Control precision of drawn curve w.r.t to scale of plot, default is 1e-3. A higher precision will
2687/// result in more and more densely spaced curve points. A negative precision value will disable
2688/// adaptive point spacing and restrict sampling to the grid point of points defined by the binning
2689/// of the plotted observable (recommended for expensive functions such as profile likelihoods)
2690/// <tr><td> `Invisible(Bool_t flag)` <td> Add curve to frame, but do not display. Useful in combination AddTo()
2691/// <tr><td> `VisualizeError(const RooFitResult& fitres, Double_t Z=1, Bool_t linearMethod=kTRUE)`
2692/// <td> Visualize the uncertainty on the parameters, as given in fitres, at 'Z' sigma.
2693///
2694/// <tr><td> `VisualizeError(const RooFitResult& fitres, const RooArgSet& param, Double_t Z=1, Bool_t linearMethod=kTRUE)`
2695/// <td> Visualize the uncertainty on the subset of parameters 'param', as given in fitres, at 'Z' sigma.
2696/// </table>
2697
2699{
2700
2701 // Pre-processing if p.d.f. contains a fit range and there is no command specifying one,
2702 // add a fit range as default range
2703 RooCmdArg* plotRange(0) ;
2704 RooCmdArg* normRange2(0);
2705 if (getStringAttribute("fitrange") && !cmdList.FindObject("Range") &&
2706 !cmdList.FindObject("RangeWithName")) {
2707 plotRange = (RooCmdArg*) RooFit::Range(getStringAttribute("fitrange")).Clone() ;
2708 cmdList.Add(plotRange) ;
2709 }
2710
2711 if (getStringAttribute("fitrange") && !cmdList.FindObject("NormRange")) {
2712 normRange2 = (RooCmdArg*) RooFit::NormRange(getStringAttribute("fitrange")).Clone() ;
2713 cmdList.Add(normRange2) ;
2714 }
2715
2716 if (plotRange || normRange2) {
2717 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f was fitted in a subrange and no explicit "
2718 << (plotRange?"Range()":"") << ((plotRange&&normRange2)?" and ":"")
2719 << (normRange2?"NormRange()":"") << " was specified. Plotting / normalising in fit range. To override, do one of the following"
2720 << "\n\t- Clear the automatic fit range attribute: <pdf>.setStringAttribute(\"fitrange\", nullptr);"
2721 << "\n\t- Explicitly specify the plotting range: Range(\"<rangeName>\")."
2722 << "\n\t- Explicitly specify where to compute the normalisation: NormRange(\"<rangeName>\")."
2723 << "\n\tThe default (full) range can be denoted with Range(\"\") / NormRange(\"\")."<< endl ;
2724 }
2725
2726 // Sanity checks
2727 if (plotSanityChecks(frame)) return frame ;
2728
2729 // Select the pdf-specific commands
2730 RooCmdConfig pc(Form("RooAbsPdf::plotOn(%s)",GetName())) ;
2731 pc.defineDouble("scaleFactor","Normalization",0,1.0) ;
2732 pc.defineInt("scaleType","Normalization",0,Relative) ;
2733 pc.defineObject("compSet","SelectCompSet",0) ;
2734 pc.defineString("compSpec","SelectCompSpec",0) ;
2735 pc.defineObject("asymCat","Asymmetry",0) ;
2736 pc.defineDouble("rangeLo","Range",0,-999.) ;
2737 pc.defineDouble("rangeHi","Range",1,-999.) ;
2738 pc.defineString("rangeName","RangeWithName",0,"") ;
2739 pc.defineString("normRangeName","NormRange",0,"") ;
2740 pc.defineInt("rangeAdjustNorm","Range",0,0) ;
2741 pc.defineInt("rangeWNAdjustNorm","RangeWithName",0,0) ;
2742 pc.defineMutex("SelectCompSet","SelectCompSpec") ;
2743 pc.defineMutex("Range","RangeWithName") ;
2744 pc.allowUndefined() ; // unknowns may be handled by RooAbsReal
2745
2746 // Process and check varargs
2747 pc.process(cmdList) ;
2748 if (!pc.ok(kTRUE)) {
2749 return frame ;
2750 }
2751
2752 // Decode command line arguments
2753 ScaleType stype = (ScaleType) pc.getInt("scaleType") ;
2754 Double_t scaleFactor = pc.getDouble("scaleFactor") ;
2755 const RooAbsCategoryLValue* asymCat = (const RooAbsCategoryLValue*) pc.getObject("asymCat") ;
2756 const char* compSpec = pc.getString("compSpec") ;
2757 const RooArgSet* compSet = (const RooArgSet*) pc.getObject("compSet") ;
2758 Bool_t haveCompSel = ( (compSpec && strlen(compSpec)>0) || compSet) ;
2759
2760 // Suffix for curve name
2761 std::string nameSuffix ;
2762 if (compSpec && strlen(compSpec)>0) {
2763 nameSuffix.append("_Comp[") ;
2764 nameSuffix.append(compSpec) ;
2765 nameSuffix.append("]") ;
2766 } else if (compSet) {
2767 nameSuffix.append("_Comp[") ;
2768 nameSuffix.append(compSet->contentsString().c_str()) ;
2769 nameSuffix.append("]") ;
2770 }
2771
2772 // Remove PDF-only commands from command list
2773 pc.stripCmdList(cmdList,"SelectCompSet,SelectCompSpec") ;
2774
2775 // Adjust normalization, if so requested
2776 if (asymCat) {
2777 RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.c_str(),0,0,0) ;
2778 cmdList.Add(&cnsuffix);
2779 return RooAbsReal::plotOn(frame,cmdList) ;
2780 }
2781
2782 // More sanity checks
2783 Double_t nExpected(1) ;
2784 if (stype==RelativeExpected) {
2785 if (!canBeExtended()) {
2786 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
2787 << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
2788 return frame ;
2789 }
2790 frame->updateNormVars(*frame->getPlotVar()) ;
2791 nExpected = expectedEvents(frame->getNormVars()) ;
2792 }
2793
2794 if (stype != Raw) {
2795
2796 if (frame->getFitRangeNEvt() && stype==Relative) {
2797
2798 Bool_t hasCustomRange(kFALSE), adjustNorm(kFALSE) ;
2799
2800 std::vector<pair<Double_t,Double_t> > rangeLim;
2801
2802 // Retrieve plot range to be able to adjust normalization to data
2803 if (pc.hasProcessed("Range")) {
2804
2805 Double_t rangeLo = pc.getDouble("rangeLo") ;
2806 Double_t rangeHi = pc.getDouble("rangeHi") ;
2807 rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
2808 adjustNorm = pc.getInt("rangeAdjustNorm") ;
2809 hasCustomRange = kTRUE ;
2810
2811 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range ["
2812 << rangeLo << "," << rangeHi << "]" ;
2813 if (!pc.hasProcessed("NormRange")) {
2814 ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " range" << endl ;
2815 } else {
2816 ccoutI(Plotting) << endl ;
2817 }
2818
2819 nameSuffix.append(Form("_Range[%f_%f]",rangeLo,rangeHi)) ;
2820
2821 } else if (pc.hasProcessed("RangeWithName")) {
2822
2823 for (const std::string& rangeNameToken : RooHelpers::tokenise(pc.getString("rangeName", "", false), ",", /*returnEmptyToken=*/true)) {
2824 const char* thisRangeName = rangeNameToken.empty() ? nullptr : rangeNameToken.c_str();
2825 if (thisRangeName && !frame->getPlotVar()->hasRange(thisRangeName)) {
2826 coutE(Plotting) << "Range '" << rangeNameToken << "' not defined for variable '"
2827 << frame->getPlotVar()->GetName() << "'. Ignoring ..." << std::endl;
2828 continue;
2829 }
2830 rangeLim.push_back(frame->getPlotVar()->getRange(thisRangeName));
2831 }
2832 adjustNorm = pc.getInt("rangeWNAdjustNorm") ;
2833 hasCustomRange = kTRUE ;
2834
2835 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range '" << pc.getString("rangeName", "", false) << "'" ;
2836 if (!pc.hasProcessed("NormRange")) {
2837 ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " range" << endl ;
2838 } else {
2839 ccoutI(Plotting) << endl ;
2840 }
2841
2842 nameSuffix.append(Form("_Range[%s]",pc.getString("rangeName"))) ;
2843 }
2844 // Specification of a normalization range override those in a regular range
2845 if (pc.hasProcessed("NormRange")) {
2846 rangeLim.clear();
2847 for (const auto& rangeNameToken : RooHelpers::tokenise(pc.getString("normRangeName", "", false), ",", /*returnEmptyToken=*/true)) {
2848 const char* thisRangeName = rangeNameToken.empty() ? nullptr : rangeNameToken.c_str();
2849 if (thisRangeName && !frame->getPlotVar()->hasRange(thisRangeName)) {
2850 coutE(Plotting) << "Range '" << rangeNameToken << "' not defined for variable '"
2851 << frame->getPlotVar()->GetName() << "'. Ignoring ..." << std::endl;
2852 continue;
2853 }
2854 rangeLim.push_back(frame->getPlotVar()->getRange(thisRangeName));
2855 }
2856 adjustNorm = kTRUE ;
2857 hasCustomRange = kTRUE ;
2858 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f. curve is normalized using explicit choice of ranges '" << pc.getString("normRangeName", "", false) << "'" << endl ;
2859
2860 nameSuffix.append(Form("_NormRange[%s]",pc.getString("rangeName"))) ;
2861
2862 }
2863
2864 if (hasCustomRange && adjustNorm) {
2865 // If overlapping ranges were given, remove them now
2866 const std::size_t oldSize = rangeLim.size();
2867 removeRangeOverlap(rangeLim);
2868
2869 if (oldSize != rangeLim.size() && !pc.hasProcessed("NormRange")) {
2870 // User gave overlapping ranges. This leads to double-counting events and integrals, and must
2871 // therefore be avoided. If a NormRange has been given, the overlap is alreay gone.
2872 // It's safe to plot even with overlap now.
2873 coutE(Plotting) << "Requested plot/integration ranges overlap. For correct plotting, new ranges "
2874 "will be defined." << std::endl;
2875 auto plotVar = dynamic_cast<RooRealVar*>(frame->getPlotVar());
2876 assert(plotVar);
2877 std::string rangesNoOverlap;
2878 for (auto it = rangeLim.begin(); it != rangeLim.end(); ++it) {
2879 std::stringstream rangeName;
2880 rangeName << "Remove_overlap_range_" << it - rangeLim.begin();
2881 plotVar->setRange(rangeName.str().c_str(), it->first, it->second);
2882 if (!rangesNoOverlap.empty())
2883 rangesNoOverlap += ",";
2884 rangesNoOverlap += rangeName.str();
2885 }
2886
2887 auto rangeArg = static_cast<RooCmdArg*>(cmdList.FindObject("RangeWithName"));
2888 if (rangeArg)
2889 rangeArg->setString(0, rangesNoOverlap.c_str());
2890 else {
2891 plotRange = new RooCmdArg(RooFit::Range(rangesNoOverlap.c_str()));
2892 cmdList.Add(plotRange);
2893 }
2894 }
2895
2896 Double_t rangeNevt(0) ;
2897 for (const auto& riter : rangeLim) {
2898 Double_t nevt= frame->getFitRangeNEvt(riter.first, riter.second);
2899 rangeNevt += nevt ;
2900 }
2901
2902 scaleFactor *= rangeNevt/nExpected ;
2903
2904 } else {
2905 scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
2906 }
2907 } else if (stype==RelativeExpected) {
2908 scaleFactor *= nExpected ;
2909 } else if (stype==NumEvent) {
2910 scaleFactor /= nExpected ;
2911 }
2912 scaleFactor *= frame->getFitRangeBinW() ;
2913 }
2914 frame->updateNormVars(*frame->getPlotVar()) ;
2915
2916 // Append overriding scale factor command at end of original command list
2917 RooCmdArg tmp = RooFit::Normalization(scaleFactor,Raw) ;
2918 tmp.setInt(1,1) ; // Flag this normalization command as created for internal use (so that VisualizeError can strip it)
2919 cmdList.Add(&tmp) ;
2920
2921 // Was a component selected requested
2922 if (haveCompSel) {
2923
2924 // Get complete set of tree branch nodes
2925 RooArgSet branchNodeSet ;
2926 branchNodeServerList(&branchNodeSet) ;
2927
2928 // Discard any non-RooAbsReal nodes
2929 for (const auto arg : branchNodeSet) {
2930 if (!dynamic_cast<RooAbsReal*>(arg)) {
2931 branchNodeSet.remove(*arg) ;
2932 }
2933 }
2934
2935 // Obtain direct selection
2936 RooArgSet* dirSelNodes ;
2937 if (compSet) {
2938 dirSelNodes = (RooArgSet*) branchNodeSet.selectCommon(*compSet) ;
2939 } else {
2940 dirSelNodes = (RooArgSet*) branchNodeSet.selectByName(compSpec) ;
2941 }
2942 if (dirSelNodes->getSize()>0) {
2943 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") directly selected PDF components: " << *dirSelNodes << endl ;
2944
2945 // Do indirect selection and activate both
2946 plotOnCompSelect(dirSelNodes) ;
2947 } else {
2948 if (compSet) {
2949 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection set " << *compSet << " does not match any components of p.d.f." << endl ;
2950 } else {
2951 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection expression '" << compSpec << "' does not select any components of p.d.f." << endl ;
2952 }
2953 return 0 ;
2954 }
2955
2956 delete dirSelNodes ;
2957 }
2958
2959
2960 RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.c_str(),0,0,0) ;
2961 cmdList.Add(&cnsuffix);
2962
2963 RooPlot* ret = RooAbsReal::plotOn(frame,cmdList) ;
2964
2965 // Restore selection status ;
2966 if (haveCompSel) plotOnCompSelect(0) ;
2967
2968 if (plotRange) {
2969 delete plotRange ;
2970 }
2971 if (normRange2) {
2972 delete normRange2 ;
2973 }
2974
2975 return ret ;
2976}
2977
2978
2979//_____________________________________________________________________________
2980/// Plot oneself on 'frame'. In addition to features detailed in RooAbsReal::plotOn(),
2981/// the scale factor for a PDF can be interpreted in three different ways. The interpretation
2982/// is controlled by ScaleType
2983/// ```
2984/// Relative - Scale factor is applied on top of PDF normalization scale factor
2985/// NumEvent - Scale factor is interpreted as a number of events. The surface area
2986/// under the PDF curve will match that of a histogram containing the specified
2987/// number of event
2988/// Raw - Scale factor is applied to the raw (projected) probability density.
2989/// Not too useful, option provided for completeness.
2990/// ```
2991// coverity[PASS_BY_VALUE]
2993{
2994
2995 // Sanity checks
2996 if (plotSanityChecks(frame)) return frame ;
2997
2998 // More sanity checks
2999 Double_t nExpected(1) ;
3000 if (o.stype==RelativeExpected) {
3001 if (!canBeExtended()) {
3002 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
3003 << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
3004 return frame ;
3005 }
3006 frame->updateNormVars(*frame->getPlotVar()) ;
3007 nExpected = expectedEvents(frame->getNormVars()) ;
3008 }
3009
3010 // Adjust normalization, if so requested
3011 if (o.stype != Raw) {
3012
3013 if (frame->getFitRangeNEvt() && o.stype==Relative) {
3014 // If non-default plotting range is specified, adjust number of events in fit range
3015 o.scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
3016 } else if (o.stype==RelativeExpected) {
3017 o.scaleFactor *= nExpected ;
3018 } else if (o.stype==NumEvent) {
3019 o.scaleFactor /= nExpected ;
3020 }
3021 o.scaleFactor *= frame->getFitRangeBinW() ;
3022 }
3023 frame->updateNormVars(*frame->getPlotVar()) ;
3024
3025 return RooAbsReal::plotOn(frame,o) ;
3026}
3027
3028
3029
3030
3031////////////////////////////////////////////////////////////////////////////////
3032/// The following named arguments are supported
3033/// <table>
3034/// <tr><th> Type of CmdArg <th> Effect on parameter box
3035/// <tr><td> `Parameters(const RooArgSet& param)` <td> Only the specified subset of parameters will be shown. By default all non-constant parameters are shown.
3036/// <tr><td> `ShowConstants(Bool_t flag)` <td> Also display constant parameters
3037/// <tr><td> `Format(const char* optStr)` <td> \deprecated Classing parameter formatting options, provided for backward compatibility
3038///
3039/// <tr><td> `Format(const char* what,...)` <td> Parameter formatting options.
3040/// | Parameter | Format
3041/// | ---------------------- | --------------------------
3042/// | `const char* what` | Controls what is shown. "N" adds name, "E" adds error, "A" shows asymmetric error, "U" shows unit, "H" hides the value
3043/// | `FixedPrecision(int n)`| Controls precision, set fixed number of digits
3044/// | `AutoPrecision(int n)` | Controls precision. Number of shown digits is calculated from error + n specified additional digits (1 is sensible default)
3045/// <tr><td> `Label(const chat* label)` <td> Add label to parameter box. Use `\n` for multi-line labels.
3046/// <tr><td> `Layout(Double_t xmin, Double_t xmax, Double_t ymax)` <td> Specify relative position of left/right side of box and top of box.
3047/// Coordinates are given as position on the pad between 0 and 1.
3048/// The lower end of the box is calculated automatically from the number of lines in the box.
3049/// </table>
3050///
3051///
3052/// Example use:
3053/// ```
3054/// pdf.paramOn(frame, Label("fit result"), Format("NEU",AutoPrecision(1)) ) ;
3055/// ```
3056///
3057
3058RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
3059 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
3060 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
3061{
3062 // Stuff all arguments in a list
3063 RooLinkedList cmdList;
3064 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
3065 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
3066 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
3067 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
3068
3069 // Select the pdf-specific commands
3070 RooCmdConfig pc(Form("RooAbsPdf::paramOn(%s)",GetName())) ;
3071 pc.defineString("label","Label",0,"") ;
3072 pc.defineDouble("xmin","Layout",0,0.65) ;
3073 pc.defineDouble("xmax","Layout",1,0.9) ;
3074 pc.defineInt("ymaxi","Layout",0,Int_t(0.9*10000)) ;
3075 pc.defineInt("showc","ShowConstants",0,0) ;
3076 pc.defineObject("params","Parameters",0,0) ;
3077 pc.defineString("formatStr","Format",0,"NELU") ;
3078 pc.defineInt("sigDigit","Format",0,2) ;
3079 pc.defineInt("dummy","FormatArgs",0,0) ;
3080 pc.defineMutex("Format","FormatArgs") ;
3081
3082 // Process and check varargs
3083 pc.process(cmdList) ;
3084 if (!pc.ok(kTRUE)) {
3085 return frame ;
3086 }
3087
3088 const char* label = pc.getString("label") ;
3089 Double_t xmin = pc.getDouble("xmin") ;
3090 Double_t xmax = pc.getDouble("xmax") ;
3091 Double_t ymax = pc.getInt("ymaxi") / 10000. ;
3092 Int_t showc = pc.getInt("showc") ;
3093
3094
3095 const char* formatStr = pc.getString("formatStr") ;
3096 Int_t sigDigit = pc.getInt("sigDigit") ;
3097
3098 // Decode command line arguments
3099 RooArgSet* params = static_cast<RooArgSet*>(pc.getObject("params")) ;
3100 if (!params) {
3101 std::unique_ptr<RooArgSet> paramsPtr{getParameters(frame->getNormVars())} ;
3102 if (pc.hasProcessed("FormatArgs")) {
3103 const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
3104 paramOn(frame,*paramsPtr,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
3105 } else {
3106 paramOn(frame,*paramsPtr,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
3107 }
3108 } else {
3109 std::unique_ptr<RooArgSet> pdfParams{getParameters(frame->getNormVars())} ;
3110 std::unique_ptr<RooArgSet> selParams{static_cast<RooArgSet*>(pdfParams->selectCommon(*params))} ;
3111 if (pc.hasProcessed("FormatArgs")) {
3112 const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
3113 paramOn(frame,*selParams,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
3114 } else {
3115 paramOn(frame,*selParams,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
3116 }
3117 }
3118
3119 return frame ;
3120}
3121
3122
3123
3124
3125////////////////////////////////////////////////////////////////////////////////
3126/// \deprecated Obsolete, provided for backward compatibility. Don't use.
3127
3128RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooAbsData* data, const char *label,
3129 Int_t sigDigits, Option_t *options, Double_t xmin,
3131{
3132 std::unique_ptr<RooArgSet> params{getParameters(data)} ;
3133 TString opts(options) ;
3134 paramOn(frame,*params,opts.Contains("c"),label,sigDigits,options,xmin,xmax,ymax) ;
3135 return frame ;
3136}
3137
3138
3139
3140////////////////////////////////////////////////////////////////////////////////
3141/// Add a text box with the current parameter values and their errors to the frame.
3142/// Observables of this PDF appearing in the 'data' dataset will be omitted.
3143///
3144/// An optional label will be inserted if passed. Multi-line labels can be generated
3145/// by adding `\n` to the label string. Use 'sigDigits'
3146/// to modify the default number of significant digits printed. The 'xmin,xmax,ymax'
3147/// values specify the initial relative position of the text box in the plot frame.
3148
3149RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooArgSet& params, Bool_t showConstants, const char *label,
3150 Int_t sigDigits, Option_t *options, Double_t xmin,
3151 Double_t xmax ,Double_t ymax, const RooCmdArg* formatCmd)
3152{
3153
3154 // parse the options
3155 TString opts = options;
3156 opts.ToLower();
3157 Bool_t showLabel= (label != 0 && strlen(label) > 0);
3158
3159 // calculate the box's size, adjusting for constant parameters
3160
3161 Double_t ymin(ymax), dy(0.06);
3162 for (const auto param : params) {
3163 auto var = static_cast<RooRealVar*>(param);
3164 if(showConstants || !var->isConstant()) ymin-= dy;
3165 }
3166
3167 std::string labelString = label;
3168 unsigned int numLines = std::count(labelString.begin(), labelString.end(), '\n') + 1;
3169 if (showLabel) ymin -= numLines * dy;
3170
3171 // create the box and set its options
3172 TPaveText *box= new TPaveText(xmin,ymax,xmax,ymin,"BRNDC");
3173 if(!box) return 0;
3174 box->SetName(Form("%s_paramBox",GetName())) ;
3175 box->SetFillColor(0);
3176 box->SetBorderSize(0);
3177 box->SetTextAlign(12);
3178 box->SetTextSize(0.04F);
3179 box->SetFillStyle(0);
3180
3181 for (const auto param : params) {
3182 auto var = static_cast<const RooRealVar*>(param);
3183 if(var->isConstant() && !showConstants) continue;
3184
3185 TString *formatted= options ? var->format(sigDigits, options) : var->format(*formatCmd) ;
3186 box->AddText(formatted->Data());
3187 delete formatted;
3188 }
3189
3190 // add the optional label if specified
3191 if (showLabel) {
3192 for (const auto& line : RooHelpers::tokenise(label, "\n")) {
3193 box->AddText(line.c_str());
3194 }
3195 }
3196
3197 // Add box to frame
3198 frame->addObject(box) ;
3199
3200 return frame ;
3201}
3202
3203
3204
3205
3206////////////////////////////////////////////////////////////////////////////////
3207/// Return expected number of events from this p.d.f for use in extended
3208/// likelihood calculations. This default implementation returns zero
3209
3211{
3212 return 0 ;
3213}
3214
3215
3216
3217////////////////////////////////////////////////////////////////////////////////
3218/// Change global level of verbosity for p.d.f. evaluations
3219
3221{
3222 _verboseEval = stat ;
3223}
3224
3225
3226
3227////////////////////////////////////////////////////////////////////////////////
3228/// Return global level of verbosity for p.d.f. evaluations
3229
3231{
3232 return _verboseEval ;
3233}
3234
3235
3236
3237////////////////////////////////////////////////////////////////////////////////
3238/// Destructor of normalization cache element. If this element
3239/// provides the 'current' normalization stored in RooAbsPdf::_norm
3240/// zero _norm pointer here before object pointed to is deleted here
3241
3243{
3244 // Zero _norm pointer in RooAbsPdf if it is points to our cache payload
3245 if (_owner) {
3246 RooAbsPdf* pdfOwner = static_cast<RooAbsPdf*>(_owner) ;
3247 if (pdfOwner->_norm == _norm) {
3248 pdfOwner->_norm = 0 ;
3249 }
3250 }
3251
3252 delete _norm ;
3253}
3254
3255
3256
3257////////////////////////////////////////////////////////////////////////////////
3258/// Return a p.d.f that represent a projection of this p.d.f integrated over given observables
3259
3261{
3262 // Construct name for new object
3263 std::string name(GetName()) ;
3264 name.append("_Proj[") ;
3265 if (iset.getSize()>0) {
3266 bool first = true;
3267 for(auto const& arg : iset) {
3268 if (first) {
3269 first = false ;
3270 } else {
3271 name.append(",") ;
3272 }
3273 name.append(arg->GetName()) ;
3274 }
3275 }
3276 name.append("]") ;
3277
3278 // Return projected p.d.f.
3279 return new RooProjectedPdf(name.c_str(),name.c_str(),*this,iset) ;
3280}
3281
3282
3283
3284////////////////////////////////////////////////////////////////////////////////
3285/// Create a cumulative distribution function of this p.d.f in terms
3286/// of the observables listed in iset. If no nset argument is given
3287/// the c.d.f normalization is constructed over the integrated
3288/// observables, so that its maximum value is precisely 1. It is also
3289/// possible to choose a different normalization for
3290/// multi-dimensional p.d.f.s: eg. for a pdf f(x,y,z) one can
3291/// construct a partial cdf c(x,y) that only when integrated itself
3292/// over z results in a maximum value of 1. To construct such a cdf pass
3293/// z as argument to the optional nset argument
3294
3296{
3297 return createCdf(iset,RooFit::SupNormSet(nset)) ;
3298}
3299
3300
3301
3302////////////////////////////////////////////////////////////////////////////////
3303/// Create an object that represents the integral of the function over one or more observables listed in `iset`.
3304/// The actual integration calculation is only performed when the return object is evaluated. The name
3305/// of the integral object is automatically constructed from the name of the input function, the variables
3306/// it integrates and the range integrates over
3307///
3308/// The following named arguments are accepted
3309/// | Type of CmdArg | Effect on CDF
3310/// | ---------------------|-------------------
3311/// | SupNormSet(const RooArgSet&) | Observables over which should be normalized _in addition_ to the integration observables
3312/// | ScanNumCdf() | Apply scanning technique if cdf integral involves numeric integration [ default ]
3313/// | ScanAllCdf() | Always apply scanning technique
3314/// | ScanNoCdf() | Never apply scanning technique
3315/// | ScanParameters(Int_t nbins, Int_t intOrder) | Parameters for scanning technique of making CDF: number of sampled bins and order of interpolation applied on numeric cdf
3316
3317RooAbsReal* RooAbsPdf::createCdf(const RooArgSet& iset, const RooCmdArg& arg1, const RooCmdArg& arg2,
3318 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
3319 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
3320{
3321 // Define configuration for this method
3322 RooCmdConfig pc(Form("RooAbsReal::createCdf(%s)",GetName())) ;
3323 pc.defineObject("supNormSet","SupNormSet",0,0) ;
3324 pc.defineInt("numScanBins","ScanParameters",0,1000) ;
3325 pc.defineInt("intOrder","ScanParameters",1,2) ;
3326 pc.defineInt("doScanNum","ScanNumCdf",0,1) ;
3327 pc.defineInt("doScanAll","ScanAllCdf",0,0) ;
3328 pc.defineInt("doScanNon","ScanNoCdf",0,0) ;
3329 pc.defineMutex("ScanNumCdf","ScanAllCdf","ScanNoCdf") ;
3330
3331 // Process & check varargs
3332 pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
3333 if (!pc.ok(kTRUE)) {
3334 return 0 ;
3335 }
3336
3337 // Extract values from named arguments
3338 const RooArgSet* snset = static_cast<const RooArgSet*>(pc.getObject("supNormSet",0)) ;
3339 RooArgSet nset ;
3340 if (snset) {
3341 nset.add(*snset) ;
3342 }
3343 Int_t numScanBins = pc.getInt("numScanBins") ;
3344 Int_t intOrder = pc.getInt("intOrder") ;
3345 Int_t doScanNum = pc.getInt("doScanNum") ;
3346 Int_t doScanAll = pc.getInt("doScanAll") ;
3347 Int_t doScanNon = pc.getInt("doScanNon") ;
3348
3349 // If scanning technique is not requested make integral-based cdf and return
3350 if (doScanNon) {
3351 return createIntRI(iset,nset) ;
3352 }
3353 if (doScanAll) {
3354 return createScanCdf(iset,nset,numScanBins,intOrder) ;
3355 }
3356 if (doScanNum) {
3357 std::unique_ptr<RooRealIntegral> tmp{static_cast<RooRealIntegral*>(createIntegral(iset))} ;
3358 Int_t isNum= (tmp->numIntRealVars().getSize()>0) ;
3359
3360 if (isNum) {
3361 coutI(NumIntegration) << "RooAbsPdf::createCdf(" << GetName() << ") integration over observable(s) " << iset << " involves numeric integration," << endl
3362 << " constructing cdf though numeric integration of sampled pdf in " << numScanBins << " bins and applying order "
3363 << intOrder << " interpolation on integrated histogram." << endl
3364 << " To override this choice of technique use argument ScanNone(), to change scan parameters use ScanParameters(nbins,order) argument" << endl ;
3365 }
3366
3367 return isNum ? createScanCdf(iset,nset,numScanBins,intOrder) : createIntRI(iset,nset) ;
3368 }
3369 return 0 ;
3370}
3371
3372RooAbsReal* RooAbsPdf::createScanCdf(const RooArgSet& iset, const RooArgSet& nset, Int_t numScanBins, Int_t intOrder)
3373{
3374 string name = string(GetName()) + "_NUMCDF_" + integralNameSuffix(iset,&nset).Data() ;
3375 RooRealVar* ivar = (RooRealVar*) iset.first() ;
3376 ivar->setBins(numScanBins,"numcdf") ;
3377 RooNumCdf* ret = new RooNumCdf(name.c_str(),name.c_str(),*this,*ivar,"numcdf") ;
3378 ret->setInterpolationOrder(intOrder) ;
3379 return ret ;
3380}
3381
3382
3383
3384
3385////////////////////////////////////////////////////////////////////////////////
3386/// This helper function finds and collects all constraints terms of all component p.d.f.s
3387/// and returns a RooArgSet with all those terms.
3388
3389RooArgSet* RooAbsPdf::getAllConstraints(const RooArgSet& observables, RooArgSet& constrainedParams, Bool_t stripDisconnected) const
3390{
3391 RooArgSet* ret = new RooArgSet("AllConstraints") ;
3392
3393 std::unique_ptr<RooArgSet> comps(getComponents());
3394 for (const auto arg : *comps) {
3395 auto pdf = dynamic_cast<const RooAbsPdf*>(arg) ;
3396 if (pdf && !ret->find(pdf->GetName())) {
3397 std::unique_ptr<RooArgSet> compRet(pdf->getConstraints(observables,constrainedParams,stripDisconnected));
3398 if (compRet) {
3399 ret->add(*compRet,kFALSE) ;
3400 }
3401 }
3402 }
3403
3404 return ret ;
3405}
3406
3407
3408////////////////////////////////////////////////////////////////////////////////
3409/// Returns the default numeric MC generator configuration for all RooAbsReals
3410
3412{
3414}
3415
3416
3417////////////////////////////////////////////////////////////////////////////////
3418/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3419/// If this object has no specialized configuration, a null pointer is returned
3420
3422{
3423 return _specGeneratorConfig ;
3424}
3425
3426
3427
3428////////////////////////////////////////////////////////////////////////////////
3429/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3430/// If this object has no specialized configuration, a null pointer is returned,
3431/// unless createOnTheFly is kTRUE in which case a clone of the default integrator
3432/// configuration is created, installed as specialized configuration, and returned
3433
3435{
3436 if (!_specGeneratorConfig && createOnTheFly) {
3438 }
3439 return _specGeneratorConfig ;
3440}
3441
3442
3443
3444////////////////////////////////////////////////////////////////////////////////
3445/// Return the numeric MC generator configuration used for this object. If
3446/// a specialized configuration was associated with this object, that configuration
3447/// is returned, otherwise the default configuration for all RooAbsReals is returned
3448
3450{
3451 const RooNumGenConfig* config = specialGeneratorConfig() ;
3452 if (config) return config ;
3453 return defaultGeneratorConfig() ;
3454}
3455
3456
3457
3458////////////////////////////////////////////////////////////////////////////////
3459/// Set the given configuration as default numeric MC generator
3460/// configuration for this object
3461
3463{
3465 delete _specGeneratorConfig ;
3466 }
3468}
3469
3470
3471
3472////////////////////////////////////////////////////////////////////////////////
3473/// Remove the specialized numeric MC generator configuration associated
3474/// with this object
3475
3477{
3479 delete _specGeneratorConfig ;
3480 }
3482}
3483
3484
3485
3486////////////////////////////////////////////////////////////////////////////////
3487
3489{
3490 delete _genContext ;
3491}
3492
3493
3494////////////////////////////////////////////////////////////////////////////////
3495
3496RooAbsPdf::GenSpec::GenSpec(RooAbsGenContext* context, const RooArgSet& whatVars, RooDataSet* protoData, Int_t nGen,
3497 Bool_t extended, Bool_t randProto, Bool_t resampleProto, TString dsetName, Bool_t init) :
3498 _genContext(context), _whatVars(whatVars), _protoData(protoData), _nGen(nGen), _extended(extended),
3499 _randProto(randProto), _resampleProto(resampleProto), _dsetName(dsetName), _init(init)
3500{
3501}
3502
3503
3504
3505////////////////////////////////////////////////////////////////////////////////
3506
3507void RooAbsPdf::setNormRange(const char* rangeName)
3508{
3509 if (rangeName) {
3510 _normRange = rangeName ;
3511 } else {
3512 _normRange.Clear() ;
3513 }
3514
3515 if (_norm) {
3517 _norm = 0 ;
3518 }
3519}
3520
3521
3522////////////////////////////////////////////////////////////////////////////////
3523
3524void RooAbsPdf::setNormRangeOverride(const char* rangeName)
3525{
3526 if (rangeName) {
3527 _normRangeOverride = rangeName ;
3528 } else {
3530 }
3531
3532 if (_norm) {
3534 _norm = 0 ;
3535 }
3536}
int Int_t
Definition: CPyCppyy.h:43
header file containing the templated implementation of matrix inversion routines for use with ROOT's ...
void Class()
Definition: Class.C:29
#define e(i)
Definition: RSha256.hxx:103
#define coutI(a)
Definition: RooMsgService.h:30
#define cxcoutI(a)
Definition: RooMsgService.h:85
#define cxcoutD(a)
Definition: RooMsgService.h:81
#define coutP(a)
Definition: RooMsgService.h:31
#define oocoutW(o, a)
Definition: RooMsgService.h:47
#define coutW(a)
Definition: RooMsgService.h:32
#define coutE(a)
Definition: RooMsgService.h:33
#define ccoutI(a)
Definition: RooMsgService.h:38
#define ccoutD(a)
Definition: RooMsgService.h:37
const Bool_t kFALSE
Definition: RtypesCore.h:101
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:364
static void indent(ostringstream &buf, int indent_level)
float xmin
Definition: THbookFile.cxx:95
float ymin
Definition: THbookFile.cxx:95
float xmax
Definition: THbookFile.cxx:95
float ymax
Definition: THbookFile.cxx:95
int isnan(double)
double sqrt(double)
double log(double)
char * Form(const char *fmt,...)
class to compute the Cholesky decomposition of a matrix
bool Invert(M &m) const
place the inverse into m
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:72
void clearValueAndShapeDirty() const
Definition: RooAbsArg.h:570
friend class RooDataSet
Definition: RooAbsArg.h:644
RooWorkspace * _myws
Prevent 'AlwaysDirty' mode for this node.
Definition: RooAbsArg.h:698
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:799
RooAbsArg * findServer(const char *name) const
Return server of this with name name. Returns nullptr if not found.
Definition: RooAbsArg.h:203
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
Definition: RooAbsArg.cxx:323
friend class RooArgSet
Definition: RooAbsArg.h:600
virtual void Print(Option_t *options=0) const
Print the object to the defaultPrintStream().
Definition: RooAbsArg.h:323
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
Definition: RooAbsArg.cxx:336
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Given a set of possible observables, return the observables that this PDF depends on.
Definition: RooAbsArg.h:295
Bool_t isValueDirty() const
Definition: RooAbsArg.h:422
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2010
virtual TObject * Clone(const char *newname=0) const
Make a clone of an object using the Streamer facility.
Definition: RooAbsArg.h:84
virtual void constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt=kTRUE)
Interface function signaling a request to perform constant term optimization.
Definition: RooAbsArg.cxx:1806
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Set the operation mode of this node.
Definition: RooAbsArg.cxx:1819
Bool_t addOwnedComponents(const RooArgSet &comps)
Take ownership of the contents of 'comps'.
Definition: RooAbsArg.cxx:2218
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:314
void setProxyNormSet(const RooArgSet *nset)
Forward a change in the cached normalization argset to all the registered proxies.
Definition: RooAbsArg.cxx:1338
friend class RooProjectedPdf
Definition: RooAbsArg.h:607
RefCountList_t _serverList
Definition: RooAbsArg.h:608
RooArgSet * getComponents() const
Create a RooArgSet with all components (branch nodes) of the expression tree headed by this object.
Definition: RooAbsArg.cxx:746
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...
Definition: RooAbsArg.cxx:578
void branchNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=0, Bool_t recurseNonDerived=kFALSE) const
Fill supplied list with all branch nodes of the arg tree starting with ourself as top node.
Definition: RooAbsArg.cxx:520
OperMode operMode() const
Query the operation mode of this node.
Definition: RooAbsArg.h:485
void setInterpolationOrder(Int_t order)
Set interpolation order of RooHistFunct representing cache histogram.
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
RooAbsArg * first() const
bool empty() const
Int_t getSize() const
TIterator * createIterator(Bool_t dir=kIterForward) const
TIterator-style iteration over contained elements.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
RooAbsCollection * selectByName(const char *nameList, Bool_t verbose=kFALSE) const
Create a subset of the current collection, consisting only of those elements with names matching the ...
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
bool selectCommon(const RooAbsCollection &refColl, RooAbsCollection &outColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
RooAbsCollection * selectByAttrib(const char *name, Bool_t value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
std::string contentsString() const
Return comma separated list of contained object names as STL string.
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
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:73
virtual const RooArgSet * get() const
Definition: RooAbsData.h:119
virtual Bool_t isNonPoissonWeighted() const
Definition: RooAbsData.h:176
virtual Double_t sumEntries() const =0
Return effective number of entries in dataset, i.e., sum all weights.
virtual Double_t weight() const =0
virtual Bool_t isWeighted() const
Definition: RooAbsData.h:172
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Definition: RooAbsData.cxx:307
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
Bool_t isValid() const
virtual RooDataSet * generate(Double_t nEvents=0, Bool_t skipInit=kFALSE, Bool_t extendedMode=kFALSE)
Generate the specified number of events with nEvents>0 and and return a dataset containing the genera...
virtual void setExpectedData(Bool_t)
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
Normalization set with for above integral.
Definition: RooAbsPdf.h:328
virtual ~CacheElem()
Destructor of normalization cache element.
Definition: RooAbsPdf.cxx:3242
RooAbsReal * _norm
Definition: RooAbsPdf.h:333
RooArgSet _whatVars
Definition: RooAbsPdf.h:83
RooAbsGenContext * _genContext
Definition: RooAbsPdf.h:82
Bool_t _resampleProto
Definition: RooAbsPdf.h:88
RooDataSet * _protoData
Definition: RooAbsPdf.h:84
GenSpec * prepareMultiGen(const RooArgSet &whatVars, 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())
Prepare GenSpec configuration object for efficient generation of multiple datasets from identical spe...
Definition: RooAbsPdf.cxx:2061
RooObjCacheManager _normMgr
Definition: RooAbsPdf.h:335
virtual RooPlot * plotOn(RooPlot *frame, 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(), const RooCmdArg &arg9=RooCmdArg::none(), const RooCmdArg &arg10=RooCmdArg::none()) const
Helper calling plotOn(RooPlot*, RooLinkedList&) const.
Definition: RooAbsPdf.h:120
int calculateSumW2CorrectedCovMatrix(RooMinimizer &minimizer, RooAbsReal const &nll) const
Definition: RooAbsPdf.cxx:1218
Double_t getNorm(const RooArgSet &nset) const
Get normalisation term needed to normalise the raw values returned by getVal().
Definition: RooAbsPdf.h:210
friend class CacheElem
Definition: RooAbsPdf.h:337
virtual void generateEvent(Int_t code)
Interface for generation of an event using the algorithm corresponding to the specified code.
Definition: RooAbsPdf.cxx:2310
virtual ~RooAbsPdf()
Destructor.
Definition: RooAbsPdf.cxx:264
void logBatchComputationErrors(RooSpan< const double > &outputs, std::size_t begin) const
Scan through outputs and fix+log all nans and negative values.
Definition: RooAbsPdf.cxx:717
RooSpan< const double > getLogProbabilities(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet=nullptr) const
Compute the log-likelihoods for all events in the requested batch.
Definition: RooAbsPdf.cxx:740
RooSpan< const double > getValues(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet) const
Compute batch of values for given input data, and normalise by integrating over the observables in no...
Definition: RooAbsPdf.cxx:354
void setGeneratorConfig()
Remove the specialized numeric MC generator configuration associated with this object.
Definition: RooAbsPdf.cxx:3476
virtual void resetErrorCounters(Int_t resetValue=10)
Reset error counter to given value, limiting the number of future error messages for this pdf to 'res...
Definition: RooAbsPdf.cxx:622
virtual RooAbsReal * createChi2(RooDataHist &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())
Create a from a histogram and this function.
Definition: RooAbsPdf.cxx:1738
virtual RooFitResult * chi2FitTo(RooDataHist &data, const RooLinkedList &cmdList)
Calls RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
Definition: RooAbsPdf.cxx:1692
static int verboseEval()
Return global level of verbosity for p.d.f. evaluations.
Definition: RooAbsPdf.cxx:3230
Bool_t traceEvalPdf(Double_t value) const
Check that passed value is positive and not 'not-a-number'.
Definition: RooAbsPdf.cxx:432
virtual RooAbsReal * createNLL(RooAbsData &data, const RooLinkedList &cmdList)
Construct representation of -log(L) of PDFwith given dataset.
Definition: RooAbsPdf.cxx:977
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE) const
Interface function to create a generator context from a p.d.f.
Definition: RooAbsPdf.cxx:1889
RooAbsReal * createScanCdf(const RooArgSet &iset, const RooArgSet &nset, Int_t numScanBins, Int_t intOrder)
Definition: RooAbsPdf.cxx:3372
TString _normRange
MC generator configuration specific for this object.
Definition: RooAbsPdf.h:358
void setNormRange(const char *rangeName)
Definition: RooAbsPdf.cxx:3507
virtual Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, Bool_t staticInitOK=kTRUE) const
Load generatedVars with the subset of directVars that we can generate events for, and return a code t...
Definition: RooAbsPdf.cxx:2288
RooNumGenConfig * specialGeneratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
Definition: RooAbsPdf.cxx:3421
Bool_t canBeExtended() const
If true, PDF can provide extended likelihood term.
Definition: RooAbsPdf.h:237
virtual Bool_t selfNormalized() const
Shows if a PDF is self-normalized, which means that no attempt is made to add a normalization term.
Definition: RooAbsPdf.h:226
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Print multi line detailed information of this RooAbsPdf.
Definition: RooAbsPdf.cxx:1862
Double_t analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=0) const
Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further informatio...
Definition: RooAbsPdf.cxx:412
virtual RooAbsGenContext * autoGenContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE, Bool_t autoBinned=kTRUE, const char *binnedTag="") const
Definition: RooAbsPdf.cxx:1898
Int_t _traceCount
Definition: RooAbsPdf.h:351
RooAbsReal * _norm
Definition: RooAbsPdf.h:325
virtual Double_t extendedTerm(Double_t observedEvents, const RooArgSet *nset=0) const
Return the extended likelihood term ( ) of this PDF for the given number of observed events.
Definition: RooAbsPdf.cxx:783
virtual void printValue(std::ostream &os) const
Print value of p.d.f, also print normalization integral that was last used, if any.
Definition: RooAbsPdf.cxx:1843
virtual RooArgSet * getAllConstraints(const RooArgSet &observables, RooArgSet &constrainedParams, Bool_t stripDisconnected=kTRUE) const
This helper function finds and collects all constraints terms of all component p.d....
Definition: RooAbsPdf.cxx:3389
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:1410
virtual Bool_t syncNormalization(const RooArgSet *dset, Bool_t adjustProxies=kTRUE) const
Verify that the normalization integral cached with this PDF is valid for given set of normalization o...
Definition: RooAbsPdf.cxx:526
virtual Double_t getValV(const RooArgSet *set=0) const
Return current value, normalized by integrating over the observables in nset.
Definition: RooAbsPdf.cxx:282
Int_t _errorCount
Definition: RooAbsPdf.h:347
Bool_t _selectComp
Definition: RooAbsPdf.h:354
@ CanBeExtended
Definition: RooAbsPdf.h:231
@ MustBeExtended
Definition: RooAbsPdf.h:231
@ CanNotBeExtended
Definition: RooAbsPdf.h:231
int calculateAsymptoticCorrectedCovMatrix(RooMinimizer &minimizer, RooAbsData const &data)
Definition: RooAbsPdf.cxx:1151
virtual RooPlot * paramOn(RooPlot *frame, 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())
Add a box with parameter values (and errors) to the specified frame.
Definition: RooAbsPdf.cxx:3058
void setTraceCounter(Int_t value, Bool_t allNodes=kFALSE)
Reset trace counter to given value, limiting the number of future trace messages for this pdf to 'val...
Definition: RooAbsPdf.cxx:634
RooAbsReal * createCdf(const RooArgSet &iset, const RooArgSet &nset=RooArgSet())
Create a cumulative distribution function of this p.d.f in terms of the observables listed in iset.
Definition: RooAbsPdf.cxx:3295
virtual const RooAbsReal * getNormObj(const RooArgSet *set, const RooArgSet *iset, const TNamed *rangeName=0) const
Return pointer to RooAbsReal object that implements calculation of integral over observables iset in ...
Definition: RooAbsPdf.cxx:491
virtual Double_t getLogVal(const RooArgSet *set=0) const
Return the log of the current value with given normalization An error message is printed if the argum...
Definition: RooAbsPdf.cxx:660
Int_t * randomizeProtoOrder(Int_t nProto, Int_t nGen, Bool_t resample=kFALSE) const
Return lookup table with randomized order for nProto prototype events.
Definition: RooAbsPdf.cxx:2251
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
Definition: RooAbsPdf.cxx:3210
Int_t _negCount
Definition: RooAbsPdf.h:352
virtual RooArgSet * getConstraints(const RooArgSet &, RooArgSet &, Bool_t) const
Definition: RooAbsPdf.h:183
void setNormRangeOverride(const char *rangeName)
Definition: RooAbsPdf.cxx:3524
virtual RooDataSet * generateSimGlobal(const RooArgSet &whatVars, Int_t nEvents)
Special generator interface for generation of 'global observables' – for RooStats tools.
Definition: RooAbsPdf.cxx:2567
virtual Bool_t isDirectGenSafe(const RooAbsArg &arg) const
Check if given observable can be safely generated using the pdfs internal generator mechanism (if tha...
Definition: RooAbsPdf.cxx:2323
const RooNumGenConfig * getGeneratorConfig() const
Return the numeric MC generator configuration used for this object.
Definition: RooAbsPdf.cxx:3449
virtual void initGenerator(Int_t code)
Interface for one-time initialization to setup the generator for the specified code.
Definition: RooAbsPdf.cxx:2298
virtual RooDataHist * generateBinned(const RooArgSet &whatVars, Double_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none()) const
As RooAbsPdf::generateBinned(const RooArgSet&, const RooCmdArg&,const RooCmdArg&, const RooCmdArg&,...
Definition: RooAbsPdf.h:106
virtual ExtendMode extendMode() const
Returns ability of PDF to provide extended likelihood terms.
Definition: RooAbsPdf.h:235
RooAbsPdf()
Default constructor.
Definition: RooAbsPdf.cxx:206
virtual RooAbsGenContext * binnedGenContext(const RooArgSet &vars, Bool_t verbose=kFALSE) const
Return a binned generator context.
Definition: RooAbsPdf.cxx:1879
static RooNumGenConfig * defaultGeneratorConfig()
Returns the default numeric MC generator configuration for all RooAbsReals.
Definition: RooAbsPdf.cxx:3411
RooNumGenConfig * _specGeneratorConfig
Definition: RooAbsPdf.h:356
RooArgSet * _normSet
Normalization integral (owned by _normMgr)
Definition: RooAbsPdf.h:326
Double_t _rawValue
Definition: RooAbsPdf.h:324
static TString _normRangeOverride
Definition: RooAbsPdf.h:359
static Int_t _verboseEval
Definition: RooAbsPdf.h:319
virtual RooAbsPdf * createProjection(const RooArgSet &iset)
Return a p.d.f that represent a projection of this p.d.f integrated over given observables.
Definition: RooAbsPdf.cxx:3260
RooDataSet * generate(const RooArgSet &whatVars, Int_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none())
See RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,...
Definition: RooAbsPdf.h:57
virtual Bool_t hasRange(const char *name) const
Check if variable has a binning with given name.
std::pair< double, double > getRange(const char *name=0) const
Get low and high bound of the variable.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:61
void plotOnCompSelect(RooArgSet *selNodes) const
Helper function for plotting of composite p.d.fs.
@ RelativeExpected
Definition: RooAbsReal.h:280
virtual RooSpan< double > evaluateSpan(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet) const
Evaluate this object for a batch/span of data points.
RooDerivative * derivative(RooRealVar &obs, Int_t order=1, Double_t eps=0.001)
Return function representing first, second or third order derivative of this function.
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1=RooCmdArg(), const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg(), const RooCmdArg &arg7=RooCmdArg(), const RooCmdArg &arg8=RooCmdArg(), const RooCmdArg &arg9=RooCmdArg(), const RooCmdArg &arg10=RooCmdArg()) const
Plot (project) PDF on specified frame.
virtual Double_t evaluate() const =0
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
TString integralNameSuffix(const RooArgSet &iset, const RooArgSet *nset=0, const char *rangeName=0, Bool_t omitEmpty=kFALSE) const
Construct string with unique suffix name to give to integral object that encodes integrated observabl...
Definition: RooAbsReal.cxx:790
RooAbsReal * createIntRI(const RooArgSet &iset, const RooArgSet &nset=RooArgSet())
Utility function for createRunningIntegral.
RooFitResult * chi2FitDriver(RooAbsReal &fcn, RooLinkedList &cmdList)
Internal driver function for chi2 fits.
Double_t _value
Definition: RooAbsReal.h:477
virtual RooSpan< const double > getValues(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet=nullptr) const
by this change, please consult the release notes for ROOT 6.24 for guidance on how to make this trans...
Definition: RooAbsReal.cxx:310
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Structure printing.
Definition: RooAbsReal.cxx:488
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
virtual void enableOffsetting(Bool_t)
Definition: RooAbsReal.h:367
RooAbsReal * createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, 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()) const
Create an object that represents the integral of the function over one or more observables listed in ...
Definition: RooAbsReal.cxx:546
Bool_t plotSanityChecks(RooPlot *frame) const
Utility function for plotOn(), perform general sanity check on frame to ensure safe plotting operatio...
static void setEvalErrorLoggingMode(ErrorLoggingMode m)
Set evaluation error logging mode.
virtual Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
Definition: RooAbsReal.cxx:427
const RooNumIntConfig * getIntegratorConfig() const
Return the numeric integration configuration used for this object.
virtual Bool_t isBinnedDistribution(const RooArgSet &) const
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
Definition: RooAbsReal.h:341
void logEvalError(const char *message, const char *serverValueString=0) const
Log evaluation error message.
RooDataHist * fillDataHist(RooDataHist *hist, const RooArgSet *nset, Double_t scaleFactor, Bool_t correctForBinVolume=kFALSE, Bool_t showProgress=kFALSE) const
Fill a RooDataHist with values sampled from this function at the bin centers.
RooAddition calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
Definition: RooAddition.h:27
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:22
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Definition: RooArgList.h:110
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:35
RooBinnedGenContext is an efficient implementation of the generator context specific for binned pdfs.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=0)
RooCachedReal is an implementation of RooAbsCachedReal that can cache any external RooAbsReal input f...
Definition: RooCachedReal.h:20
void setCacheSource(Bool_t flag)
Definition: RooCachedReal.h:44
RooChi2Var implements a simple calculation from a binned dataset and a PDF.
Definition: RooChi2Var.h:25
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition: RooCmdArg.h:27
void setInt(Int_t idx, Int_t value)
Definition: RooCmdArg.h:66
void setString(Int_t idx, const char *value)
Definition: RooCmdArg.h:72
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
Definition: RooCmdConfig.h:27
Bool_t defineInt(const char *name, const char *argName, Int_t intNum, Int_t defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
Int_t getInt(const char *name, Int_t defaultValue=0)
Return integer property registered with name 'name'.
void allowUndefined(Bool_t flag=kTRUE)
Definition: RooCmdConfig.h:39
Bool_t process(const RooCmdArg &arg)
Process given RooCmdArg.
static std::unique_ptr< RooAbsReal > createConstraintTerm(std::string const &name, RooAbsPdf const &pdf, RooArgSet const &observables, RooArgSet const *constrainedParameters, RooArgSet const *externalConstraints, RooArgSet const *globalObservables, const char *globalObservablesTag, RooWorkspace *workspace=nullptr)
Create the parameter constraint sum to add to the negative log-likelihood.
The RooDataHist is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:39
double weight(std::size_t i) const
Return weight of i-th bin.
Definition: RooDataHist.h:106
void set(std::size_t binNumber, double weight, double wgtErr)
Set bin content of bin that was last loaded with get(std::size_t).
Double_t sumEntries() const override
Sum the weights of all bins.
const RooArgSet * get() const override
Get bin centre of current bin.
Definition: RooDataHist.h:78
Int_t numEntries() const override
Return the number of bins.
void SetName(const char *name) override
Change the name of the RooDataHist.
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:36
void SetName(const char *name) override
Change the name of this dataset into the given name.
virtual void add(const RooArgSet &row, Double_t weight=1.0, Double_t weightError=0) override
Add a data point, with its coordinates specified in the 'data' argset, to the data set.
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Definition: RooFitResult.h:40
void setCovQual(Int_t val)
Definition: RooFitResult.h:171
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Definition: RooFormulaVar.h:30
Class RooGenContext implement a universal generator context for all RooAbsPdf classes that do not hav...
Definition: RooGenContext.h:30
Switches the message service to a different level while the instance is alive.
Definition: RooHelpers.h:42
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:37
TObject * FindObject(const char *name) const
Return pointer to obejct with given name.
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:64
RooMinimizer is a wrapper class around ROOT::Fit:Fitter that provides a seamless interface between th...
Definition: RooMinimizer.h:49
Int_t hesse()
Execute HESSE.
RooFitResult * save(const char *name=0, const char *title=0)
Save and return a RooFitResult snapshot of current minimizer status.
void applyCovarianceMatrix(TMatrixDSym &V)
Apply results of given external covariance matrix.
Class RooNLLVar implements a -log(likelihood) calculation from a dataset and a PDF.
Definition: RooNLLVar.h:30
static const char * str(const TNamed *ptr)
Return C++ string corresponding to given TNamed pointer.
Definition: RooNameReg.cxx:103
Class RooNumCdf is an implementation of RooNumRunningInt specialized to calculate cumulative distribu...
Definition: RooNumCdf.h:17
RooNumGenConfig holds the configuration parameters of the various numeric integrators used by RooReal...
static RooNumGenConfig & defaultConfig()
Return reference to instance of default numeric integrator configuration object.
void sterilize()
Clear the cache payload but retain slot mapping w.r.t to normalization and integration sets.
A RooPlot is a plot frame and a container for graphics objects within that frame.
Definition: RooPlot.h:44
const RooArgSet * getNormVars() const
Definition: RooPlot.h:148
void addObject(TObject *obj, Option_t *drawOptions="", Bool_t invisible=kFALSE)
Add a generic object to this plot.
Definition: RooPlot.cxx:422
Double_t getFitRangeNEvt() const
Return the number of events in the fit range.
Definition: RooPlot.h:141
Double_t getFitRangeBinW() const
Return the bin width that is being used to normalise the PDF.
Definition: RooPlot.h:144
void updateNormVars(const RooArgSet &vars)
Install the given set of observables are reference normalization variables for this frame.
Definition: RooPlot.cxx:380
RooAbsRealLValue * getPlotVar() const
Definition: RooPlot.h:139
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer,...
static UInt_t integer(UInt_t max, TRandom *generator=randomGenerator())
Return an integer uniformly distributed from [0,n-1].
Definition: RooRandom.cxx:101
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition: RooRandom.cxx:53
RooRealIntegral performs hybrid numerical/analytical integrals of RooAbsReal objects.
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:39
void setBins(Int_t nBins, const char *name=0)
Create a uniform binning under name 'name' for this variable.
Definition: RooRealVar.cxx:408
void setRange(const char *name, Double_t min, Double_t max)
Set a fit or plotting range.
Definition: RooRealVar.cxx:526
A simple container to hold a batch of data values.
Definition: RooSpan.h:34
constexpr std::span< T >::index_type size() const noexcept
Definition: RooSpan.h:121
RooXYChi2Var implements a simple chi^2 calculation from an unbinned dataset with values x,...
Definition: RooXYChi2Var.h:29
Iterator abstract base class.
Definition: TIterator.h:30
virtual TObject * Next()=0
Int_t GetNrows() const
Definition: TMatrixTBase.h:123
TMatrixTSym< Element > & Similarity(const TMatrixT< Element > &n)
Calculate B * (*this) * B^T , final matrix will be (nrowsb x nrowsb) This is a similarity transform w...
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
TString fName
Definition: TNamed.h:32
Mother of all ROOT objects.
Definition: TObject.h:37
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:402
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition: TRandom.cxx:672
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition: TRandom.cxx:360
Basic string class.
Definition: TString.h:136
Ssiz_t Length() const
Definition: TString.h:410
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1150
void Clear()
Clear string without changing its capacity.
Definition: TString.cxx:1201
const char * Data() const
Definition: TString.h:369
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
TLine * line
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
RooCmdArg SupNormSet(const RooArgSet &nset)
RooCmdArg WeightVar(const char *name, Bool_t reinterpretAsWeight=kFALSE)
RooCmdArg Hesse(Bool_t flag=kTRUE)
RooCmdArg PrintLevel(Int_t code)
RooCmdArg NormRange(const char *rangeNameList)
RooCmdArg Range(const char *rangeName, Bool_t adjustNorm=kTRUE)
RooCmdArg Normalization(Double_t scaleFactor)
void swap(RDirectoryEntry &e1, RDirectoryEntry &e2) noexcept
double T(double x)
Definition: ChebyshevPol.h:34
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
static const std::string name("name")
double fast_log(double x)
Definition: RooVDTHeaders.h:56
@ Minimization
Definition: RooGlobalFunc.h:60
@ Generation
Definition: RooGlobalFunc.h:60
@ NumIntegration
Definition: RooGlobalFunc.h:62
@ InputArguments
Definition: RooGlobalFunc.h:61
bool checkIfRangesOverlap(RooAbsPdf const &pdf, RooAbsData const &data, std::vector< std::string > const &rangeNames)
Check if there is any overlap when a list of ranges is applied to a set of observables.
Definition: RooHelpers.cxx:206
std::vector< std::string > tokenise(const std::string &str, const std::string &delims, bool returnEmptyToken=true)
Tokenise the string by splitting at the characters in delims.
Definition: RooHelpers.cxx:67
RooArgSet selectFromArgSet(RooArgSet const &, std::string const &names)
Construct a RooArgSet of objects in a RooArgSet whose names match to those in the names string.
Definition: RooHelpers.cxx:292
std::string getColonSeparatedNameString(RooArgSet const &argSet)
Create a string with all sorted names of RooArgSet elements separated by colons.
Definition: RooHelpers.cxx:271
static constexpr double pc
Bool_t IsNaN(Double_t x)
Definition: TMath.h:892
Double_t QuietNaN()
Returns a quiet NaN as defined by IEEE 754
Definition: TMath.h:901
Definition: first.py:1
Double_t scaleFactor
Definition: RooAbsReal.h:496
std::string rangeName
Stores the configuration parameters for RooAbsTestStatistic.
This struct enables passing computation data around between elements of a computation graph.
Definition: RunContext.h:31
std::vector< double > logProbabilities
If evaluation should only occur in a range, the range name can be passed here.
Definition: RunContext.h:56
std::unordered_map< const RooAbsReal *, RooSpan< const double > > spans
Once an object has computed its value(s), the span pointing to the results is registered here.
Definition: RunContext.h:52
static double packFloatIntoNaN(float payload)
Pack float into mantissa of a NaN.
Definition: RooNaNPacker.h:109
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
static void output(int code)
Definition: gifencode.c:226