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