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