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