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
941namespace {
942
943std::unique_ptr<RooAbsReal> createMultiRangeNLLCorrectionTerm(
944 RooAbsPdf const &pdf, RooAbsData const &data, std::string const &baseName, std::string const &rangeNames)
945{
946 double sumEntriesTotal = 0.0;
947
948 RooArgList termList;
949 RooArgList integralList;
950
951 for (const auto &currentRangeName : ROOT::Split(rangeNames, ",")) {
952 const std::string currentName = baseName + "_" + currentRangeName;
953
954 auto sumEntriesCurrent = data.sumEntries("1", currentRangeName.c_str());
955 sumEntriesTotal += sumEntriesCurrent;
956
957 RooArgSet depList;
958 pdf.getObservables(data.get(), depList);
959 auto pdfIntegralCurrent = pdf.createIntegral(depList, &depList, nullptr, currentRangeName.c_str());
960
961 auto term = new RooFormulaVar((currentName + "_correctionTerm").c_str(),
962 (std::string("-(") + std::to_string(sumEntriesCurrent) + " * log(x[0]))").c_str(),
963 RooArgList(*pdfIntegralCurrent));
964
965 termList.add(*term);
966 integralList.add(*pdfIntegralCurrent);
967 }
968
969 auto integralFull = new RooAddition((baseName + "_correctionFullIntegralTerm").c_str(),
970 "integral",
971 integralList,
972 true);
973
974 auto fullRangeTerm = new RooFormulaVar((baseName + "_foobar").c_str(),
975 (std::string("(") + std::to_string(sumEntriesTotal) + " * log(x[0]))").c_str(),
976 RooArgList(*integralFull));
977
978 termList.add(*fullRangeTerm);
979 return std::unique_ptr<RooAbsReal>{
980 new RooAddition((baseName + "_correction").c_str(), "correction", termList, true)};
981}
982
983
984} // namespace
985
986
987////////////////////////////////////////////////////////////////////////////////
988/// Construct representation of -log(L) of PDFwith given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset
989/// is binned, a binned likelihood is constructed.
990///
991/// See RooAbsPdf::createNLL(RooAbsData& data, RooCmdArg arg1, RooCmdArg arg2, RooCmdArg arg3, RooCmdArg arg4,
992/// RooCmdArg arg5, RooCmdArg arg6, RooCmdArg arg7, RooCmdArg arg8)
993/// for documentation of options
994
996{
997 auto baseName = std::string("nll_") + GetName() + "_" + data.GetName();
998
999 // Select the pdf-specific commands
1000 RooCmdConfig pc(Form("RooAbsPdf::createNLL(%s)",GetName())) ;
1001
1002 pc.defineString("rangeName","RangeWithName",0,"",true) ;
1003 pc.defineString("addCoefRange","SumCoefRange",0,"") ;
1004 pc.defineString("globstag","GlobalObservablesTag",0,"") ;
1005 pc.defineString("globssource","GlobalObservablesSource",0,"data") ;
1006 pc.defineDouble("rangeLo","Range",0,-999.) ;
1007 pc.defineDouble("rangeHi","Range",1,-999.) ;
1008 pc.defineInt("splitRange","SplitRange",0,0) ;
1009 pc.defineInt("ext","Extended",0,2) ;
1010 pc.defineInt("numcpu","NumCPU",0,1) ;
1011 pc.defineInt("interleave","NumCPU",1,0) ;
1012 pc.defineInt("verbose","Verbose",0,0) ;
1013 pc.defineInt("optConst","Optimize",0,0) ;
1014 pc.defineInt("cloneData","CloneData", 0, 2);
1015 pc.defineSet("projDepSet","ProjectedObservables",0,0) ;
1016 pc.defineSet("cPars","Constrain",0,0) ;
1017 pc.defineSet("glObs","GlobalObservables",0,0) ;
1018 pc.defineInt("doOffset","OffsetLikelihood",0,0) ;
1019 pc.defineSet("extCons","ExternalConstraints",0,0) ;
1020 pc.defineInt("BatchMode", "BatchMode", 0, 0);
1021 pc.defineDouble("IntegrateBins", "IntegrateBins", 0, -1.);
1022 pc.defineMutex("Range","RangeWithName") ;
1023 pc.defineMutex("GlobalObservables","GlobalObservablesTag") ;
1024
1025 // Process and check varargs
1026 pc.process(cmdList) ;
1027 if (!pc.ok(true)) {
1028 return 0 ;
1029 }
1030
1031 // Decode command line arguments
1032 const char* rangeName = pc.getString("rangeName",0,true) ;
1033 const char* addCoefRangeName = pc.getString("addCoefRange",0,true) ;
1034 const bool ext = interpretExtendedCmdArg(*this, pc.getInt("ext")) ;
1035 Int_t numcpu = pc.getInt("numcpu") ;
1036 Int_t numcpu_strategy = pc.getInt("interleave");
1037 // strategy 3 works only for RooSimultaneus.
1038 if (numcpu_strategy==3 && !this->InheritsFrom("RooSimultaneous") ) {
1039 coutW(Minimization) << "Cannot use a NumCpu Strategy = 3 when the pdf is not a RooSimultaneus, "
1040 "falling back to default strategy = 0" << endl;
1041 numcpu_strategy = 0;
1042 }
1043 RooFit::MPSplit interl = (RooFit::MPSplit) numcpu_strategy;
1044
1045 Int_t splitr = pc.getInt("splitRange") ;
1046 bool verbose = pc.getInt("verbose") ;
1047 Int_t optConst = pc.getInt("optConst") ;
1048 Int_t cloneData = pc.getInt("cloneData") ;
1049 Int_t doOffset = pc.getInt("doOffset") ;
1050
1051 // If no explicit cloneData command is specified, cloneData is set to true if optimization is activated
1052 if (cloneData==2) {
1053 cloneData = optConst ;
1054 }
1055
1056 // Clear possible range attributes from previous fits.
1057 removeStringAttribute("fitrange");
1058
1059 if (pc.hasProcessed("Range")) {
1060 double rangeLo = pc.getDouble("rangeLo") ;
1061 double rangeHi = pc.getDouble("rangeHi") ;
1062
1063 // Create range with name 'fit' with above limits on all observables
1064 RooArgSet obs;
1065 getObservables(data.get(), obs) ;
1066 for (auto arg : obs) {
1067 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
1068 if (rrv) rrv->setRange("fit",rangeLo,rangeHi) ;
1069 }
1070
1071 // Set range name to be fitted to "fit"
1072 rangeName = "fit" ;
1073 }
1074
1075 RooArgSet projDeps ;
1076 auto tmp = pc.getSet("projDepSet");
1077 if (tmp) {
1078 projDeps.add(*tmp) ;
1079 }
1080
1081 const std::string globalObservablesSource = pc.getString("globssource","data",false);
1082 if(globalObservablesSource != "data" && globalObservablesSource != "model") {
1083 std::string errMsg = "RooAbsPdf::fitTo: GlobalObservablesSource can only be \"data\" or \"model\"!";
1084 coutE(InputArguments) << errMsg << std::endl;
1085 throw std::invalid_argument(errMsg);
1086 }
1087 const bool takeGlobalObservablesFromData = globalObservablesSource == "data";
1088
1089 RooFit::BatchModeOption batchMode = static_cast<RooFit::BatchModeOption>(pc.getInt("BatchMode"));
1090
1091 // Create the constraint term
1092 auto constraintTerm = RooConstraintSum::createConstraintTerm(
1093 baseName + "_constr", // name
1094 *this, // pdf
1095 data, // data
1096 pc.getSet("cPars"), // Constrain RooCmdArg
1097 pc.getSet("extCons"), // ExternalConstraints RooCmdArg
1098 pc.getSet("glObs"), // GlobalObservables RooCmdArg
1099 pc.getString("globstag",0,true), // GlobalObservablesTag RooCmdArg
1100 takeGlobalObservablesFromData, // From GlobalObservablesSource RooCmdArg
1101 _myws // passing workspace to cache the set of constraints
1102 );
1103
1104 // Construct BatchModeNLL if requested
1105 if (batchMode != RooFit::BatchModeOption::Off && batchMode != RooFit::BatchModeOption::Old) {
1107 data,
1108 std::move(constraintTerm),
1109 rangeName ? rangeName : "",
1110 addCoefRangeName ? addCoefRangeName : "",
1111 projDeps,
1112 ext,
1113 pc.getDouble("IntegrateBins"),
1114 batchMode,
1115 doOffset,
1116 takeGlobalObservablesFromData).release();
1117 }
1118
1119 // Construct NLL
1121 std::unique_ptr<RooAbsReal> nll ;
1123 cfg.addCoefRangeName = addCoefRangeName ? addCoefRangeName : "";
1124 cfg.nCPU = numcpu;
1125 cfg.interleave = interl;
1126 cfg.verbose = verbose;
1127 cfg.splitCutRange = static_cast<bool>(splitr);
1128 cfg.cloneInputData = static_cast<bool>(cloneData);
1129 cfg.integrateOverBinsPrecision = pc.getDouble("IntegrateBins");
1130 cfg.binnedL = false;
1131 cfg.takeGlobalObservablesFromData = takeGlobalObservablesFromData;
1132 if (!rangeName || strchr(rangeName,',')==0) {
1133 // Simple case: default range, or single restricted range
1134 //cout<<"FK: Data test 1: "<<data.sumEntries()<<endl;
1135
1136 cfg.rangeName = rangeName ? rangeName : "";
1137 nll = std::make_unique<RooNLLVar>(baseName.c_str(),"-log(likelihood)",*this,data,projDeps, ext, cfg);
1138 static_cast<RooNLLVar&>(*nll).batchMode(batchMode == RooFit::BatchModeOption::Old);
1139 } else {
1140 // Composite case: multiple ranges
1141 RooArgList nllList ;
1142 auto tokens = ROOT::Split(rangeName, ",");
1143 if (RooHelpers::checkIfRangesOverlap(*this, data, tokens, cfg.splitCutRange)) {
1144 throw std::runtime_error(
1145 std::string("Error in RooAbsPdf::createNLL! The ranges ") + rangeName + " are overlapping!");
1146 }
1147 for (const auto& token : tokens) {
1148 cfg.rangeName = token;
1149 auto nllComp = std::make_unique<RooNLLVar>((baseName + "_" + token).c_str(),"-log(likelihood)",
1150 *this,data,projDeps,ext,cfg);
1151 nllComp->batchMode(pc.getInt("BatchMode"));
1152 nllList.addOwned(std::move(nllComp)) ;
1153 }
1154
1155 if (!ext) {
1156 // Each RooNLLVar was created with the normalization set corresponding to
1157 // the subrange, not the union range like it should be. We have to add an
1158 // extra term to cancel this normalization problem. However, this is
1159 // only necessarry for the non-extended case, because adding an extension
1160 // term to the individual NLLs as done here is mathematicall equivalent
1161 // to adding the normalization correction terms plus a global extension
1162 // term.
1163 nllList.addOwned(createMultiRangeNLLCorrectionTerm(*this, data, baseName, rangeName));
1164 }
1165
1166 nll = std::make_unique<RooAddition>(baseName.c_str(),"-log(likelihood)",nllList) ;
1167 nll->addOwnedComponents(std::move(nllList));
1168 }
1170
1171 // Include constraints, if any, in likelihood
1172 if (constraintTerm) {
1173 auto orignll = std::move(nll) ;
1174 nll = std::make_unique<RooAddition>(Form("%s_with_constr",baseName.c_str()),"nllWithCons",RooArgSet(*orignll,*constraintTerm)) ;
1175 nll->addOwnedComponents(std::move(orignll),std::move(constraintTerm)) ;
1176 }
1177
1178 if (optConst) {
1179 nll->constOptimizeTestStatistic(RooAbsArg::Activate,optConst>1) ;
1180 }
1181
1182 if (doOffset) {
1183 nll->enableOffsetting(true) ;
1184 }
1185
1186 return nll.release() ;
1187}
1188
1189
1190////////////////////////////////////////////////////////////////////////////////
1191/// Use the asymptotically correct approach to estimate errors in the presence of weights.
1192/// This is slower but more accurate than `SumW2Error`. See also https://arxiv.org/abs/1911.01303).
1193/// Applies the calculated covaraince matrix to the RooMinimizer and returns
1194/// the quality of the covariance matrix.
1195/// See also the documentation of RooAbsPdf::fitTo(), where this function is used.
1196/// \param[in] minimizer The RooMinimizer to get the fit result from. The state
1197/// of the minimizer will be altered by this function: the covariance
1198/// matrix caltulated here will be applied to it via
1199/// RooMinimizer::applyCovarianceMatrix().
1200/// \param[in] data The dataset that was used for the fit.
1202{
1203 // Calculated corrected errors for weighted likelihood fits
1204 std::unique_ptr<RooFitResult> rw(minimizer.save());
1205 // Weighted inverse Hessian matrix
1206 const TMatrixDSym &matV = rw->covarianceMatrix();
1207 coutI(Fitting)
1208 << "RooAbsPdf::fitTo(" << this->GetName()
1209 << ") Calculating covariance matrix according to the asymptotically correct approach. If you find this "
1210 "method useful please consider citing https://arxiv.org/abs/1911.01303."
1211 << endl;
1212
1213 // Initialise matrix containing first derivatives
1214 auto nFloatPars = rw->floatParsFinal().getSize();
1215 TMatrixDSym num(nFloatPars);
1216 for (int k = 0; k < nFloatPars; k++) {
1217 for (int l = 0; l < nFloatPars; l++) {
1218 num(k, l) = 0.0;
1219 }
1220 }
1221 RooArgSet obs;
1222 this->getObservables(data.get(), obs);
1223 // Create derivative objects
1224 std::vector<std::unique_ptr<RooDerivative>> derivatives;
1225 const RooArgList &floated = rw->floatParsFinal();
1226 std::unique_ptr<RooArgSet> floatingparams{
1227 static_cast<RooArgSet *>(this->getParameters(data)->selectByAttrib("Constant", false))};
1228 for (const auto paramresult : floated) {
1229 auto paraminternal = static_cast<RooRealVar *>(floatingparams->find(*paramresult));
1230 assert(floatingparams->find(*paramresult)->IsA() == RooRealVar::Class());
1231 derivatives.emplace_back(this->derivative(*paraminternal, obs, 1));
1232 }
1233
1234 // Loop over data
1235 for (int j = 0; j < data.numEntries(); j++) {
1236 // Sets obs to current data point, this is where the pdf will be evaluated
1237 obs.assign(*data.get(j));
1238 // Determine first derivatives
1239 std::vector<double> diffs(floated.getSize(), 0.0);
1240 for (int k = 0; k < floated.getSize(); k++) {
1241 const auto paramresult = static_cast<RooRealVar *>(floated.at(k));
1242 auto paraminternal = static_cast<RooRealVar *>(floatingparams->find(*paramresult));
1243 // first derivative to parameter k at best estimate point for this measurement
1244 double diff = derivatives[k]->getVal();
1245 // need to reset to best fit point after differentiation
1246 *paraminternal = paramresult->getVal();
1247 diffs[k] = diff;
1248 }
1249 // Fill numerator matrix
1250 double prob = getVal(&obs);
1251 for (int k = 0; k < floated.getSize(); k++) {
1252 for (int l = 0; l < floated.getSize(); l++) {
1253 num(k, l) += data.weightSquared() * diffs[k] * diffs[l] / (prob * prob);
1254 }
1255 }
1256 }
1257 num.Similarity(matV);
1258
1259 // Propagate corrected errors to parameters objects
1260 minimizer.applyCovarianceMatrix(num);
1261
1262 // The derivatives are found in RooFit and not with the minimizer (e.g.
1263 // minuit), so the quality of the corrected covariance matrix corresponds to
1264 // the quality of the original covariance matrix
1265 return rw->covQual();
1266}
1267
1268
1269////////////////////////////////////////////////////////////////////////////////
1270/// Apply correction to errors and covariance matrix. This uses two covariance
1271/// matrices, one with the weights, the other with squared weights, to obtain
1272/// the correct errors for weighted likelihood fits.
1273/// Applies the calculated covaraince matrix to the RooMinimizer and returns
1274/// the quality of the covariance matrix.
1275/// See also the documentation of RooAbsPdf::fitTo(), where this function is used.
1276/// \param[in] minimizer The RooMinimizer to get the fit result from. The state
1277/// of the minimizer will be altered by this function: the covariance
1278/// matrix caltulated here will be applied to it via
1279/// RooMinimizer::applyCovarianceMatrix().
1280/// \param[in] nll The NLL object that was used for the fit.
1282{
1283 // Calculated corrected errors for weighted likelihood fits
1284 std::unique_ptr<RooFitResult> rw{minimizer.save()};
1285 nll.applyWeightSquared(true);
1286 coutI(Fitting) << "RooAbsPdf::fitTo(" << this->GetName()
1287 << ") Calculating sum-of-weights-squared correction matrix for covariance matrix"
1288 << std::endl;
1289 minimizer.hesse();
1290 std::unique_ptr<RooFitResult> rw2{minimizer.save()};
1291 nll.applyWeightSquared(false);
1292
1293 // Apply correction matrix
1294 const TMatrixDSym &matV = rw->covarianceMatrix();
1295 TMatrixDSym matC = rw2->covarianceMatrix();
1297 if (!decomp) {
1298 coutE(Fitting) << "RooAbsPdf::fitTo(" << this->GetName()
1299 << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction "
1300 "matrix calculated with weight-squared is singular"
1301 << std::endl;
1302 return -1;
1303 }
1304
1305 // replace C by its inverse
1306 decomp.Invert(matC);
1307 // the class lies about the matrix being symmetric, so fill in the
1308 // part above the diagonal
1309 for (int i = 0; i < matC.GetNrows(); ++i) {
1310 for (int j = 0; j < i; ++j) {
1311 matC(j, i) = matC(i, j);
1312 }
1313 }
1314 matC.Similarity(matV);
1315 // C now contiains V C^-1 V
1316 // Propagate corrected errors to parameters objects
1317 minimizer.applyCovarianceMatrix(matC);
1318
1319 return std::min(rw->covQual(), rw2->covQual());
1320}
1321
1322
1323////////////////////////////////////////////////////////////////////////////////
1324/// Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset
1325/// is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT
1326/// commands MIGRAD, HESSE in succession.
1327/// \param[in] data Data to fit the PDF to
1328/// \param[in] arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8 One or more arguments to control the behaviour of the fit
1329/// \return RooFitResult with fit status and parameters if option Save() is used, `nullptr` otherwise. The user takes ownership of the fit result.
1330///
1331/// The following named arguments are supported
1332///
1333/// <table>
1334/// <tr><th> Type of CmdArg <th> Options to control construction of -log(L)
1335/// <tr><td> `ConditionalObservables(Args_t &&... argsOrArgSet)` <td> Do not normalize PDF over listed observables.
1336// Arguments can either be multiple RooRealVar or a single RooArgSet containing them.
1337/// <tr><td> `Extended(bool flag)` <td> Add extended likelihood term, off by default
1338/// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name. Multiple comma-separated range names can be specified.
1339/// In this case, the unnormalized PDF \f$f(x)\f$ is normalized by the integral over all ranges \f$r_i\f$:
1340/// \f[
1341/// p(x) = \frac{f(x)}{\sum_i \int_{r_i} f(x) dx}.
1342/// \f]
1343/// <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.
1344/// <tr><td> `SumCoefRange(const char* name)` <td> Set the range in which to interpret the coefficients of RooAddPdf components
1345/// <tr><td> `NumCPU(int num, int strat)` <td> Parallelize NLL calculation on `num` CPUs
1346/// <table>
1347/// <tr><th> Strategy <th> Effect
1348/// <tr><td> 0 = RooFit::BulkPartition (Default) <td> Divide events in N equal chunks
1349/// <tr><td> 1 = RooFit::Interleave <td> Process event i%N in process N. Recommended for binned data with
1350/// a substantial number of zero-bins, which will be distributed across processes more equitably in this strategy
1351/// <tr><td> 2 = RooFit::SimComponents <td> Process each component likelihood of a RooSimultaneous fully in a single process
1352/// and distribute components over processes. This approach can be benificial if normalization calculation time
1353/// dominates the total computation time of a component (since the normalization calculation must be performed
1354/// in each process in strategies 0 and 1. However beware that if the RooSimultaneous components do not share many
1355/// parameters this strategy is inefficient: as most minuit-induced likelihood calculations involve changing
1356/// a single parameter, only 1 of the N processes will be active most of the time if RooSimultaneous components
1357/// do not share many parameters
1358/// <tr><td> 3 = RooFit::Hybrid <td> Follow strategy 0 for all RooSimultaneous components, except those with less than
1359/// 30 dataset entries, for which strategy 2 is followed.
1360/// </table>
1361/// <tr><td> `SplitRange(bool flag)` <td> Use separate fit ranges in a simultaneous fit. Actual range name for each subsample is assumed
1362/// to by `rangeName_indexState` where indexState is the state of the master index category of the simultaneous fit.
1363/// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
1364/// ```
1365/// myVariable.setRange("range_pi0", 135, 210);
1366/// myVariable.setRange("range_gamma", 50, 210);
1367/// ```
1368/// <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
1369/// term of the product depends on parameters but not on the observable(s),), only apply constraints to the given subset of parameters.
1370/// <tr><td> `ExternalConstraints(const RooArgSet& )` <td> Include given external constraints to likelihood by multiplying them with the original likelihood.
1371/// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of normalization observables to be used for the constraint terms.
1372/// If none are specified the constrained parameters are used.
1373/// <tr><td> `Offset(bool)` <td> Offset likelihood by initial value (so that starting value of FCN in minuit is zero).
1374/// This can improve numeric stability in simultaneously fits with components with large likelihood values
1375/// <tr><td> `BatchMode(bool on)` <td> **Experimental** batch evaluation mode. This computes a batch of likelihood values at a time,
1376/// uses faster math functions and possibly auto vectorisation (this depends on the compiler flags).
1377/// Depending on hardware capabilities, the compiler flags and whether a batch evaluation function was
1378/// implemented for the PDFs of the model, likelihood computations are 2x to 10x faster.
1379/// The relative difference of the single log-likelihoods w.r.t. the legacy mode is usually better than 1.E-12,
1380/// and fit parameters usually agree to better than 1.E-6.
1381/// <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.
1382/// This can reduce the bias observed when fitting functions with high curvature to binned data.
1383/// - precision > 0: Activate bin integration everywhere. Use precision between 0.01 and 1.E-6, depending on binning.
1384/// 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
1385/// integration step. If lower precision is desired (more speed), a RooBinSamplingPdf has to be created manually, and its integrator
1386/// has to be manipulated directly.
1387/// - precision = 0: Activate bin integration only for continuous PDFs fit to a RooDataHist.
1388/// - precision < 0: Deactivate.
1389/// \see RooBinSamplingPdf
1390///
1391/// <tr><th><th> Options to control flow of fit procedure
1392/// <tr><td> `Minimizer("<type>", "<algo>")` <td> Choose minimization package and optionally the algorithm to use. Default is MINUIT/MIGRAD through the RooMinimizer interface,
1393/// but others can be specified (through RooMinimizer interface).
1394/// <table>
1395/// <tr><th> Type <th> Algorithm
1396/// <tr><td> Minuit <td> migrad, simplex, minimize (=migrad+simplex), migradimproved (=migrad+improve)
1397/// <tr><td> Minuit2 <td> migrad, simplex, minimize, scan
1398/// <tr><td> GSLMultiMin <td> conjugatefr, conjugatepr, bfgs, bfgs2, steepestdescent
1399/// <tr><td> GSLSimAn <td> -
1400/// </table>
1401///
1402/// <tr><td> `InitialHesse(bool flag)` <td> Flag controls if HESSE before MIGRAD as well, off by default
1403/// <tr><td> `Optimize(bool flag)` <td> Activate constant term optimization of test statistic during minimization (on by default)
1404/// <tr><td> `Hesse(bool flag)` <td> Flag controls if HESSE is run after MIGRAD, on by default
1405/// <tr><td> `Minos(bool flag)` <td> Flag controls if MINOS is run after HESSE, off by default
1406/// <tr><td> `Minos(const RooArgSet& set)` <td> Only run MINOS on given subset of arguments
1407/// <tr><td> `Save(bool flag)` <td> Flag controls if RooFitResult object is produced and returned, off by default
1408/// <tr><td> `Strategy(Int_t flag)` <td> Set Minuit strategy (0 to 2, default is 1)
1409/// <tr><td> `EvalErrorWall(bool flag=true)` <td> When parameters are in disallowed regions (e.g. PDF is negative), return very high value to fitter
1410/// to force it out of that region. This can, however, mean that the fitter gets lost in this region. If
1411/// this happens, try switching it off.
1412/// <tr><td> `RecoverFromUndefinedRegions(double strength)` <td> When PDF is invalid (e.g. parameter in undefined region), try to direct minimiser away from that region.
1413/// `strength` controls the magnitude of the penalty term. Leaving out this argument defaults to 10. Switch off with `strength = 0.`.
1414///
1415/// <tr><td> `SumW2Error(bool flag)` <td> Apply correction to errors and covariance matrix.
1416/// This uses two covariance matrices, one with the weights, the other with squared weights,
1417/// to obtain the correct errors for weighted likelihood fits. If this option is activated, the
1418/// corrected covariance matrix is calculated as \f$ V_\mathrm{corr} = V C^{-1} V \f$, where \f$ V \f$ is the original
1419/// covariance matrix and \f$ C \f$ is the inverse of the covariance matrix calculated using the
1420/// squared weights. This allows to switch between two interpretations of errors:
1421/// <table>
1422/// <tr><th> SumW2Error <th> Interpretation
1423/// <tr><td> true <td> The errors reflect the uncertainty of the Monte Carlo simulation.
1424/// Use this if you want to know how much accuracy you can get from the available Monte Carlo statistics.
1425///
1426/// **Example**: Simulation with 1000 events, the average weight is 0.1.
1427/// The errors are as big as if one fitted to 1000 events.
1428/// <tr><td> false <td> The errors reflect the errors of a dataset, which is as big as the sum of weights.
1429/// Use this if you want to know what statistical errors you would get if you had a dataset with as many
1430/// events as the (weighted) Monte Carlo simulation represents.
1431///
1432/// **Example** (Data as above):
1433/// The errors are as big as if one fitted to 100 events.
1434/// </table>
1435/// \note If the `SumW2Error` correction is enabled, the covariance matrix quality stored in the RooFitResult
1436/// object will be the minimum of the original covariance matrix quality and the quality of the covariance
1437/// matrix calculated with the squared weights.
1438/// <tr><td> `AsymptoticError()` <td> Use the asymptotically correct approach to estimate errors in the presence of weights.
1439/// This is slower but more accurate than `SumW2Error`. See also https://arxiv.org/abs/1911.01303).
1440/// <tr><td> `PrefitDataFraction(double fraction)`
1441/// <td> Runs a prefit on a small dataset of size fraction*(actual data size). This can speed up fits
1442/// by finding good starting values for the parameters for the actual fit.
1443/// \warning Prefitting may give bad results when used in binned analysis.
1444///
1445/// <tr><th><th> Options to control informational output
1446/// <tr><td> `Verbose(bool flag)` <td> Flag controls if verbose output is printed (NLL, parameter changes during fit).
1447/// <tr><td> `Timer(bool flag)` <td> Time CPU and wall clock consumption of fit steps, off by default.
1448/// <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.
1449/// See RooMinimizer::PrintLevel for the meaning of the levels.
1450/// <tr><td> `Warnings(bool flag)` <td> Enable or disable MINUIT warnings (enabled by default)
1451/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per likelihood evaluation.
1452/// A negative value suppresses output completely, a zero value will only print the error count per p.d.f component,
1453/// a positive value will print details of each error up to `numErr` messages per p.d.f component.
1454/// </table>
1455///
1456
1457RooFitResult* RooAbsPdf::fitTo(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
1458 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1459{
1461 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
1462 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
1463 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
1464 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
1465 return fitTo(data,l) ;
1466}
1467
1468
1469////////////////////////////////////////////////////////////////////////////////
1470/// Minimizes a given NLL variable by finding the optimal parameters with the
1471/// RooMinimzer. The NLL variable can be created with RooAbsPdf::createNLL.
1472/// If you are looking for a function that combines likelihood creation with
1473/// fitting, see RooAbsPdf::fitTo.
1474/// \param[in] nll The negative log-likelihood variable to minimize.
1475/// \param[in] data The dataset that was als used for the NLL. It's a necessary
1476/// parameter because it is used in the asymptotic error correction.
1477/// \param[in] cfg Configuration struct with all the configuration options for
1478/// the RooMinimizer. These are a subset of the options that you can
1479/// also pass to RooAbsPdf::fitTo via the RooFit command arguments.
1480std::unique_ptr<RooFitResult> RooAbsPdf::minimizeNLL(RooAbsReal & nll,
1481 RooAbsData const& data, MinimizerConfig const& cfg) {
1482
1483 // Determine if the dataset has weights
1484 bool weightedData = data.isNonPoissonWeighted();
1485
1486 // Warn user that a method to determine parameter uncertainties should be provided if weighted data is offered
1487 if (weightedData && cfg.doSumW2==-1 && cfg.doAsymptotic==-1) {
1488 coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: a likelihood fit is requested of what appears to be weighted data.\n"
1489 << " While the estimated values of the parameters will always be calculated taking the weights into account,\n"
1490 << " there are multiple ways to estimate the errors of the parameters. You are advised to make an \n"
1491 << " explicit choice for the error calculation:\n"
1492 << " - Either provide SumW2Error(true), to calculate a sum-of-weights-corrected HESSE error matrix\n"
1493 << " (error will be proportional to the number of events in MC).\n"
1494 << " - Or provide SumW2Error(false), to return errors from original HESSE error matrix\n"
1495 << " (which will be proportional to the sum of the weights, i.e., a dataset with <sum of weights> events).\n"
1496 << " - Or provide AsymptoticError(true), to use the asymptotically correct expression\n"
1497 << " (for details see https://arxiv.org/abs/1911.01303)."
1498 << endl ;
1499 }
1500
1501 if (cfg.minos && (cfg.doSumW2==1 || cfg.doAsymptotic == 1)) {
1502 coutE(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << "): sum-of-weights and asymptotic error correction do not work with MINOS errors. Not fitting." << endl;
1503 return nullptr;
1504 }
1505 if (cfg.doAsymptotic==1 && cfg.minos) {
1506 coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: asymptotic correction does not apply to MINOS errors" << endl ;
1507 }
1508
1509 //avoid setting both SumW2 and Asymptotic for uncertainty correction
1510 if (cfg.doSumW2==1 && cfg.doAsymptotic==1) {
1511 coutE(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") ERROR: Cannot compute both asymptotically correct and SumW2 errors." << endl ;
1512 return nullptr;
1513 }
1514
1515 // Instantiate RooMinimizer
1516
1517 RooMinimizer m(nll);
1518 m.setMinimizerType(cfg.minType.c_str());
1519 m.setEvalErrorWall(cfg.doEEWall);
1520 m.setRecoverFromNaNStrength(cfg.recoverFromNaN);
1521 m.setPrintEvalErrors(cfg.numee);
1522 if (cfg.printLevel!=1) m.setPrintLevel(cfg.printLevel);
1523 if (cfg.optConst) m.optimizeConst(cfg.optConst); // Activate constant term optimization
1524 if (cfg.verbose) m.setVerbose(1); // Activate verbose options
1525 if (cfg.doTimer) m.setProfile(1); // Activate timer options
1526 if (cfg.strat!=1) m.setStrategy(cfg.strat); // Modify fit strategy
1527 if (cfg.initHesse) m.hesse(); // Initialize errors with hesse
1528 m.minimize(cfg.minType.c_str(), cfg.minAlg.c_str()); // Minimize using chosen algorithm
1529 if (cfg.hesse) m.hesse(); // Evaluate errors with Hesse
1530
1531 int corrCovQual = -1;
1532
1533 if (m.getNPar()>0) {
1534 if (cfg.doAsymptotic == 1) corrCovQual = calcAsymptoticCorrectedCovariance(m, data); // Asymptotically correct
1535 if (cfg.doSumW2 == 1) corrCovQual = calcSumW2CorrectedCovariance(m, nll);
1536 }
1537
1538 if (cfg.minos) cfg.minosSet ? m.minos(*cfg.minosSet) : m.minos(); // Evaluate errs with Minos
1539
1540 // Optionally return fit result
1541 std::unique_ptr<RooFitResult> ret;
1542 if (cfg.doSave) {
1543 auto name = std::string("fitresult_") + GetName() + "_" + data.GetName();
1544 auto title = std::string("Result of fit of p.d.f. ") + GetName() + " to dataset " + data.GetName();
1545 ret.reset(m.save(name.c_str(),title.c_str()));
1546 if((cfg.doSumW2==1 || cfg.doAsymptotic==1) && m.getNPar()>0) ret->setCovQual(corrCovQual);
1547 }
1548
1549 if (cfg.optConst) m.optimizeConst(0) ;
1550 return ret ;
1551}
1552
1553
1554
1555////////////////////////////////////////////////////////////////////////////////
1556/// Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset
1557/// is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT
1558/// commands MIGRAD, HESSE and MINOS in succession.
1559///
1560/// See RooAbsPdf::fitTo(RooAbsData&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&)
1561///
1562/// for documentation of options
1563
1565{
1566 // Select the pdf-specific commands
1567 RooCmdConfig pc(Form("RooAbsPdf::fitTo(%s)",GetName())) ;
1568
1569 RooLinkedList fitCmdList(cmdList) ;
1570 RooLinkedList nllCmdList = pc.filterCmdList(fitCmdList,"ProjectedObservables,Extended,Range,"
1571 "RangeWithName,SumCoefRange,NumCPU,SplitRange,Constrained,Constrain,ExternalConstraints,"
1572 "CloneData,GlobalObservables,GlobalObservablesSource,GlobalObservablesTag,OffsetLikelihood,"
1573 "BatchMode,IntegrateBins");
1574
1575 // Default-initialized instance of MinimizerConfig to get the default
1576 // minimizer parameter values.
1577 MinimizerConfig minimizerDefaults;
1578
1579 pc.defineDouble("prefit", "Prefit",0,0);
1580 pc.defineDouble("RecoverFromUndefinedRegions", "RecoverFromUndefinedRegions",0,minimizerDefaults.recoverFromNaN);
1581 pc.defineInt("optConst","Optimize",0,minimizerDefaults.optConst) ;
1582 pc.defineInt("verbose","Verbose",0,minimizerDefaults.verbose) ;
1583 pc.defineInt("doSave","Save",0,minimizerDefaults.doSave) ;
1584 pc.defineInt("doTimer","Timer",0,minimizerDefaults.doTimer) ;
1585 pc.defineInt("printLevel","PrintLevel",0,minimizerDefaults.printLevel) ;
1586 pc.defineInt("strat","Strategy",0,minimizerDefaults.strat) ;
1587 pc.defineInt("initHesse","InitialHesse",0,minimizerDefaults.initHesse) ;
1588 pc.defineInt("hesse","Hesse",0,minimizerDefaults.hesse) ;
1589 pc.defineInt("minos","Minos",0,minimizerDefaults.minos) ;
1590 pc.defineInt("numee","PrintEvalErrors",0,minimizerDefaults.numee) ;
1591 pc.defineInt("doEEWall","EvalErrorWall",0,minimizerDefaults.doEEWall) ;
1592 pc.defineInt("doWarn","Warnings",0,minimizerDefaults.doWarn) ;
1593 pc.defineInt("doSumW2","SumW2Error",0,minimizerDefaults.doSumW2) ;
1594 pc.defineInt("doAsymptoticError","AsymptoticError",0,minimizerDefaults.doAsymptotic) ;
1595 pc.defineInt("doOffset","OffsetLikelihood",0,0) ;
1596 pc.defineString("mintype","Minimizer",0,minimizerDefaults.minType.c_str()) ;
1597 pc.defineString("minalg","Minimizer",1,minimizerDefaults.minAlg.c_str()) ;
1598 pc.defineSet("minosSet","Minos",0,minimizerDefaults.minosSet) ;
1599 pc.defineMutex("Range","RangeWithName") ;
1600
1601 // Process and check varargs
1602 pc.process(fitCmdList) ;
1603 if (!pc.ok(true)) {
1604 return 0 ;
1605 }
1606
1607 // Decode command line arguments
1608 double prefit = pc.getDouble("prefit");
1609 Int_t optConst = pc.getInt("optConst") ;
1610
1611 if (optConst > 1) {
1612 // optConst >= 2 is pre-computating values, which are never used when
1613 // the batchMode is on. This just wastes time.
1614
1615 RooCmdConfig conf(Form("RooAbsPdf::fitTo(%s)", GetName()));
1616 conf.defineInt("BatchMode","BatchMode",0,0);
1617 conf.allowUndefined(true);
1618 conf.process(nllCmdList);
1619 if (conf.getInt("BatchMode") != 0) {
1620 optConst = 1;
1621 }
1622 }
1623
1624 if (prefit != 0) {
1625 size_t nEvents = static_cast<size_t>(prefit*data.numEntries());
1626 if (prefit > 0.5 || nEvents < 100) {
1627 coutW(InputArguments) << "PrefitDataFraction should be in suitable range."
1628 << "With the current PrefitDataFraction=" << prefit
1629 << ", the number of events would be " << nEvents<< " out of "
1630 << data.numEntries() << ". Skipping prefit..." << endl;
1631 }
1632 else {
1633 size_t step = data.numEntries()/nEvents;
1634 RooArgSet tinyVars(*data.get());
1635 RooRealVar weight("weight","weight",1);
1636
1637 if (data.isWeighted()) tinyVars.add(weight);
1638
1639 RooDataSet tiny("tiny", "tiny", tinyVars,
1640 data.isWeighted() ? RooFit::WeightVar(weight) : RooCmdArg());
1641
1642 for (int i=0; i<data.numEntries(); i+=step)
1643 {
1644 const RooArgSet *event = data.get(i);
1645 tiny.add(*event, data.weight());
1646 }
1647 RooLinkedList tinyCmdList(cmdList) ;
1648 pc.filterCmdList(tinyCmdList,"Prefit,Hesse,Minos,Verbose,Save,Timer");
1649 RooCmdArg hesse_option = RooFit::Hesse(false);
1650 RooCmdArg print_option = RooFit::PrintLevel(-1);
1651
1652 tinyCmdList.Add(&hesse_option);
1653 tinyCmdList.Add(&print_option);
1654
1655 fitTo(tiny,tinyCmdList);
1656 }
1657 }
1658
1659 std::unique_ptr<RooAbsReal> nll{createNLL(data,nllCmdList)};
1660
1661 MinimizerConfig cfg;
1662 cfg.recoverFromNaN = pc.getDouble("RecoverFromUndefinedRegions");
1663 cfg.optConst = optConst;
1664 cfg.verbose = pc.getInt("verbose");
1665 cfg.doSave = pc.getInt("doSave");
1666 cfg.doTimer = pc.getInt("doTimer");
1667 cfg.printLevel = pc.getInt("printLevel");
1668 cfg.strat = pc.getInt("strat");
1669 cfg.initHesse = pc.getInt("initHesse");
1670 cfg.hesse = pc.getInt("hesse");
1671 cfg.minos = pc.getInt("minos");
1672 cfg.numee = pc.getInt("numee");
1673 cfg.doEEWall = pc.getInt("doEEWall");
1674 cfg.doWarn = pc.getInt("doWarn");
1675 cfg.doSumW2 = pc.getInt("doSumW2");
1676 cfg.doAsymptotic = pc.getInt("doAsymptoticError");
1677 cfg.minosSet = pc.getSet("minosSet");
1678 cfg.minType = pc.getString("mintype","");
1679 cfg.minAlg = pc.getString("minalg","minuit");
1680
1681 return minimizeNLL(*nll, data, cfg).release();
1682}
1683
1684
1685
1686////////////////////////////////////////////////////////////////////////////////
1687/// Calls RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
1688
1690{
1691 // Select the pdf-specific commands
1692 RooCmdConfig pc(Form("RooAbsPdf::chi2FitTo(%s)",GetName())) ;
1693
1694 // Pull arguments to be passed to chi2 construction from list
1695 RooLinkedList fitCmdList(cmdList) ;
1696 RooLinkedList chi2CmdList = pc.filterCmdList(fitCmdList,"Range,RangeWithName,NumCPU,Optimize,ProjectedObservables,AddCoefRange,SplitRange,DataError,Extended,IntegrateBins") ;
1697
1698 std::unique_ptr<RooAbsReal> chi2{createChi2(data,chi2CmdList)};
1699 return chi2FitDriver(*chi2,fitCmdList) ;
1700}
1701
1702
1703
1704
1705////////////////////////////////////////////////////////////////////////////////
1706/// Create a \f$ \chi^2 \f$ from a histogram and this function.
1707///
1708/// Options to control construction of the chi-square
1709/// ------------------------------------------
1710/// The list of supported command arguments is given in the documentation for
1711/// 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&).
1712
1714 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
1715 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1716{
1717 RooLinkedList cmdList ;
1718 cmdList.Add((TObject*)&arg1) ; cmdList.Add((TObject*)&arg2) ;
1719 cmdList.Add((TObject*)&arg3) ; cmdList.Add((TObject*)&arg4) ;
1720 cmdList.Add((TObject*)&arg5) ; cmdList.Add((TObject*)&arg6) ;
1721 cmdList.Add((TObject*)&arg7) ; cmdList.Add((TObject*)&arg8) ;
1722
1723 RooCmdConfig pc(Form("RooAbsPdf::createChi2(%s)",GetName())) ;
1724 pc.defineString("rangeName","RangeWithName",0,"",true) ;
1725 pc.allowUndefined(true) ;
1726 pc.process(cmdList) ;
1727 if (!pc.ok(true)) {
1728 return 0 ;
1729 }
1730 const char* rangeName = pc.getString("rangeName",0,true) ;
1731
1732 // Construct Chi2
1734 RooAbsReal* chi2 ;
1735 string baseName = Form("chi2_%s_%s",GetName(),data.GetName()) ;
1736
1737 // Clear possible range attributes from previous fits.
1738 removeStringAttribute("fitrange");
1739
1740 if (!rangeName || strchr(rangeName,',')==0) {
1741 // Simple case: default range, or single restricted range
1742
1743 chi2 = new RooChi2Var(baseName.c_str(),baseName.c_str(),*this,data,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1744
1745 } else {
1746
1747 // Find which argument is RangeWithName
1748 const RooCmdArg* rarg(0) ;
1749 string rcmd = "RangeWithName" ;
1750 if (arg1.GetName()==rcmd) rarg = &arg1 ;
1751 if (arg2.GetName()==rcmd) rarg = &arg2 ;
1752 if (arg3.GetName()==rcmd) rarg = &arg3 ;
1753 if (arg4.GetName()==rcmd) rarg = &arg4 ;
1754 if (arg5.GetName()==rcmd) rarg = &arg5 ;
1755 if (arg6.GetName()==rcmd) rarg = &arg6 ;
1756 if (arg7.GetName()==rcmd) rarg = &arg7 ;
1757 if (arg8.GetName()==rcmd) rarg = &arg8 ;
1758
1759 // Composite case: multiple ranges
1760 RooArgList chi2List ;
1761 for (std::string& token : ROOT::Split(rangeName, ",")) {
1762 RooCmdArg subRangeCmd = RooFit::Range(token.c_str()) ;
1763 // Construct chi2 while substituting original RangeWithName argument with subrange argument created above
1764 RooAbsReal* chi2Comp = new RooChi2Var(Form("%s_%s", baseName.c_str(), token.c_str()), "chi^2", *this, data,
1765 &arg1==rarg?subRangeCmd:arg1,&arg2==rarg?subRangeCmd:arg2,
1766 &arg3==rarg?subRangeCmd:arg3,&arg4==rarg?subRangeCmd:arg4,
1767 &arg5==rarg?subRangeCmd:arg5,&arg6==rarg?subRangeCmd:arg6,
1768 &arg7==rarg?subRangeCmd:arg7,&arg8==rarg?subRangeCmd:arg8) ;
1769 chi2List.add(*chi2Comp) ;
1770 }
1771 chi2 = new RooAddition(baseName.c_str(),"chi^2",chi2List,true) ;
1772 }
1774
1775
1776 return chi2 ;
1777}
1778
1779
1780
1781
1782////////////////////////////////////////////////////////////////////////////////
1783/// Argument-list version of RooAbsPdf::createChi2()
1784
1786{
1787 // Select the pdf-specific commands
1788 RooCmdConfig pc(Form("RooAbsPdf::createChi2(%s)",GetName())) ;
1789
1790 pc.defineInt("integrate","Integrate",0,0) ;
1791 pc.defineObject("yvar","YVar",0,0) ;
1792
1793 // Process and check varargs
1794 pc.process(cmdList) ;
1795 if (!pc.ok(true)) {
1796 return 0 ;
1797 }
1798
1799 // Decode command line arguments
1800 bool integrate = pc.getInt("integrate") ;
1801 RooRealVar* yvar = (RooRealVar*) pc.getObject("yvar") ;
1802
1803 string name = Form("chi2_%s_%s",GetName(),data.GetName()) ;
1804
1805 if (yvar) {
1806 return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,*yvar,integrate) ;
1807 } else {
1808 return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,integrate) ;
1809 }
1810}
1811
1812
1813
1814
1815////////////////////////////////////////////////////////////////////////////////
1816/// Print value of p.d.f, also print normalization integral that was last used, if any
1817
1818void RooAbsPdf::printValue(ostream& os) const
1819{
1820 // silent warning messages coming when evaluating a RooAddPdf without a normalization set
1822
1823 getVal() ;
1824
1825 if (_norm) {
1826 os << evaluate() << "/" << _norm->getVal() ;
1827 } else {
1828 os << evaluate() ;
1829 }
1830}
1831
1832
1833
1834////////////////////////////////////////////////////////////////////////////////
1835/// Print multi line detailed information of this RooAbsPdf
1836
1837void RooAbsPdf::printMultiline(ostream& os, Int_t contents, bool verbose, TString indent) const
1838{
1840 os << indent << "--- RooAbsPdf ---" << endl;
1841 os << indent << "Cached value = " << _value << endl ;
1842 if (_norm) {
1843 os << indent << " Normalization integral: " << endl ;
1844 auto moreIndent = std::string(indent.Data()) + " " ;
1845 _norm->printStream(os,kName|kAddress|kTitle|kValue|kArgs,kSingleLine,moreIndent.c_str()) ;
1846 }
1847}
1848
1849
1850
1851////////////////////////////////////////////////////////////////////////////////
1852/// Return a binned generator context
1853
1855{
1856 return new RooBinnedGenContext(*this,vars,0,0,verbose) ;
1857}
1858
1859
1860////////////////////////////////////////////////////////////////////////////////
1861/// Interface function to create a generator context from a p.d.f. This default
1862/// implementation returns a 'standard' context that works for any p.d.f
1863
1865 const RooArgSet* auxProto, bool verbose) const
1866{
1867 return new RooGenContext(*this,vars,prototype,auxProto,verbose) ;
1868}
1869
1870
1871////////////////////////////////////////////////////////////////////////////////
1872
1873RooAbsGenContext* RooAbsPdf::autoGenContext(const RooArgSet &vars, const RooDataSet* prototype, const RooArgSet* auxProto,
1874 bool verbose, bool autoBinned, const char* binnedTag) const
1875{
1876 if (prototype || (auxProto && auxProto->getSize()>0)) {
1877 return genContext(vars,prototype,auxProto,verbose);
1878 }
1879
1880 RooAbsGenContext *context(0) ;
1881 if ( (autoBinned && isBinnedDistribution(vars)) || ( binnedTag && strlen(binnedTag) && (getAttribute(binnedTag)||string(binnedTag)=="*"))) {
1882 context = binnedGenContext(vars,verbose) ;
1883 } else {
1884 context= genContext(vars,0,0,verbose);
1885 }
1886 return context ;
1887}
1888
1889
1890
1891////////////////////////////////////////////////////////////////////////////////
1892/// Generate a new dataset containing the specified variables with events sampled from our distribution.
1893/// Generate the specified number of events or expectedEvents() if not specified.
1894/// \param[in] whatVars Choose variables in which to generate events. Variables not listed here will remain
1895/// constant and not be used for event generation.
1896/// \param[in] arg1,arg2,arg3,arg4,arg5,arg6 Optional RooCmdArg() to change behaviour of generate().
1897/// \return RooDataSet *, owned by caller.
1898///
1899/// Any variables of this PDF that are not in whatVars will use their
1900/// current values and be treated as fixed parameters. Returns zero
1901/// in case of an error.
1902///
1903/// <table>
1904/// <tr><th> Type of CmdArg <th> Effect on generate
1905/// <tr><td> `Name(const char* name)` <td> Name of the output dataset
1906/// <tr><td> `Verbose(bool flag)` <td> Print informational messages during event generation
1907/// <tr><td> `NumEvents(int nevt)` <td> Generate specified number of events
1908/// <tr><td> `Extended()` <td> If no number of events to be generated is given,
1909/// use expected number of events from extended likelihood term.
1910/// This evidently only works for extended PDFs.
1911/// <tr><td> `GenBinned(const char* tag)` <td> Use binned generation for all component pdfs that have 'setAttribute(tag)' set
1912/// <tr><td> `AutoBinned(bool flag)` <td> Automatically deploy binned generation for binned distributions (e.g. RooHistPdf, sums and products of
1913/// RooHistPdfs etc)
1914/// \note Datasets that are generated in binned mode are returned as weighted unbinned datasets. This means that
1915/// for each bin, there will be one event in the dataset with a weight corresponding to the (possibly randomised) bin content.
1916///
1917///
1918/// <tr><td> `AllBinned()` <td> As above, but for all components.
1919/// \note The notion of components is only meaningful for simultaneous PDFs
1920/// as binned generation is always executed at the top-level node for a regular
1921/// PDF, so for those it only mattes that the top-level node is tagged.
1922///
1923/// <tr><td> ProtoData(const RooDataSet& data, bool randOrder)
1924/// <td> Use specified dataset as prototype dataset. If randOrder in ProtoData() is set to true,
1925/// the order of the events in the dataset will be read in a random order if the requested
1926/// number of events to be generated does not match the number of events in the prototype dataset.
1927/// \note If ProtoData() is used, the specified existing dataset as a prototype: the new dataset will contain
1928/// the same number of events as the prototype (unless otherwise specified), and any prototype variables not in
1929/// whatVars will be copied into the new dataset for each generated event and also used to set our PDF parameters.
1930/// The user can specify a number of events to generate that will override the default. The result is a
1931/// copy of the prototype dataset with only variables in whatVars randomized. Variables in whatVars that
1932/// are not in the prototype will be added as new columns to the generated dataset.
1933///
1934/// </table>
1935///
1936/// #### Accessing the underlying event generator
1937/// Depending on the fit model (if it is difficult to sample), it may be necessary to change generator settings.
1938/// For the default generator (RooFoamGenerator), the number of samples or cells could be increased by e.g. using
1939/// myPdf->specialGeneratorConfig()->getConfigSection("RooFoamGenerator").setRealValue("nSample",1e4);
1940///
1941/// The foam generator e.g. has the following config options:
1942/// - nCell[123N]D
1943/// - nSample
1944/// - chatLevel
1945/// \see rf902_numgenconfig.C
1946
1947RooDataSet *RooAbsPdf::generate(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
1948 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
1949{
1950 // Select the pdf-specific commands
1951 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
1952 pc.defineObject("proto","PrototypeData",0,0) ;
1953 pc.defineString("dsetName","Name",0,"") ;
1954 pc.defineInt("randProto","PrototypeData",0,0) ;
1955 pc.defineInt("resampleProto","PrototypeData",1,0) ;
1956 pc.defineInt("verbose","Verbose",0,0) ;
1957 pc.defineInt("extended","Extended",0,0) ;
1958 pc.defineInt("nEvents","NumEvents",0,0) ;
1959 pc.defineInt("autoBinned","AutoBinned",0,1) ;
1960 pc.defineInt("expectedData","ExpectedData",0,0) ;
1961 pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
1962 pc.defineString("binnedTag","GenBinned",0,"") ;
1963 pc.defineMutex("GenBinned","ProtoData") ;
1964 pc.defineMutex("Extended", "NumEvents");
1965
1966 // Process and check varargs
1967 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
1968 if (!pc.ok(true)) {
1969 return 0 ;
1970 }
1971
1972 // Decode command line arguments
1973 RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
1974 const char* dsetName = pc.getString("dsetName") ;
1975 bool verbose = pc.getInt("verbose") ;
1976 bool randProto = pc.getInt("randProto") ;
1977 bool resampleProto = pc.getInt("resampleProto") ;
1978 bool extended = pc.getInt("extended") ;
1979 bool autoBinned = pc.getInt("autoBinned") ;
1980 const char* binnedTag = pc.getString("binnedTag") ;
1981 Int_t nEventsI = pc.getInt("nEvents") ;
1982 double nEventsD = pc.getInt("nEventsD") ;
1983 //bool verbose = pc.getInt("verbose") ;
1984 bool expectedData = pc.getInt("expectedData") ;
1985
1986 double nEvents = (nEventsD>0) ? nEventsD : double(nEventsI);
1987
1988 // Force binned mode for expected data mode
1989 if (expectedData) {
1990 binnedTag="*" ;
1991 }
1992
1993 if (extended) {
1994 if (nEvents == 0) nEvents = expectedEvents(&whatVars);
1995 } else if (nEvents==0) {
1996 cxcoutI(Generation) << "No number of events specified , number of events generated is "
1997 << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
1998 }
1999
2000 if (extended && protoData && !randProto) {
2001 cxcoutI(Generation) << "WARNING Using generator option Extended() (Poisson distribution of #events) together "
2002 << "with a prototype dataset implies incomplete sampling or oversampling of proto data. "
2003 << "Set randomize flag in ProtoData() option to randomize prototype dataset order and thus "
2004 << "to randomize the set of over/undersampled prototype events for each generation cycle." << endl ;
2005 }
2006
2007
2008 // Forward to appropriate implementation
2009 RooDataSet* data ;
2010 if (protoData) {
2011 data = generate(whatVars,*protoData,Int_t(nEvents),verbose,randProto,resampleProto) ;
2012 } else {
2013 data = generate(whatVars,nEvents,verbose,autoBinned,binnedTag,expectedData, extended) ;
2014 }
2015
2016 // Rename dataset to given name if supplied
2017 if (dsetName && strlen(dsetName)>0) {
2018 data->SetName(dsetName) ;
2019 }
2020
2021 return data ;
2022}
2023
2024
2025
2026
2027
2028
2029////////////////////////////////////////////////////////////////////////////////
2030/// \note This method does not perform any generation. To generate according to generations specification call RooAbsPdf::generate(RooAbsPdf::GenSpec&) const
2031///
2032/// Details copied from RooAbsPdf::generate():
2033/// --------------------------------------------
2034/// \copydetails RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
2035
2037 const RooCmdArg& arg1,const RooCmdArg& arg2,
2038 const RooCmdArg& arg3,const RooCmdArg& arg4,
2039 const RooCmdArg& arg5,const RooCmdArg& arg6)
2040{
2041
2042 // Select the pdf-specific commands
2043 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
2044 pc.defineObject("proto","PrototypeData",0,0) ;
2045 pc.defineString("dsetName","Name",0,"") ;
2046 pc.defineInt("randProto","PrototypeData",0,0) ;
2047 pc.defineInt("resampleProto","PrototypeData",1,0) ;
2048 pc.defineInt("verbose","Verbose",0,0) ;
2049 pc.defineInt("extended","Extended",0,0) ;
2050 pc.defineInt("nEvents","NumEvents",0,0) ;
2051 pc.defineInt("autoBinned","AutoBinned",0,1) ;
2052 pc.defineString("binnedTag","GenBinned",0,"") ;
2053 pc.defineMutex("GenBinned","ProtoData") ;
2054
2055
2056 // Process and check varargs
2057 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
2058 if (!pc.ok(true)) {
2059 return 0 ;
2060 }
2061
2062 // Decode command line arguments
2063 RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
2064 const char* dsetName = pc.getString("dsetName") ;
2065 Int_t nEvents = pc.getInt("nEvents") ;
2066 bool verbose = pc.getInt("verbose") ;
2067 bool randProto = pc.getInt("randProto") ;
2068 bool resampleProto = pc.getInt("resampleProto") ;
2069 bool extended = pc.getInt("extended") ;
2070 bool autoBinned = pc.getInt("autoBinned") ;
2071 const char* binnedTag = pc.getString("binnedTag") ;
2072
2073 RooAbsGenContext* cx = autoGenContext(whatVars,protoData,0,verbose,autoBinned,binnedTag) ;
2074
2075 return new GenSpec(cx,whatVars,protoData,nEvents,extended,randProto,resampleProto,dsetName) ;
2076}
2077
2078
2079////////////////////////////////////////////////////////////////////////////////
2080/// If many identical generation requests
2081/// are needed, e.g. in toy MC studies, it is more efficient to use the prepareMultiGen()/generate()
2082/// combination than calling the standard generate() multiple times as
2083/// initialization overhead is only incurred once.
2084
2086{
2087 //Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen) : spec._nGen ;
2088 //Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen==0?expectedEvents(spec._whatVars):spec._nGen) : spec._nGen ;
2089 //Int_t nEvt = spec._nGen == 0 ? RooRandom::randomGenerator()->Poisson(expectedEvents(spec._whatVars)) : spec._nGen;
2090
2091 double nEvt = spec._nGen == 0 ? expectedEvents(spec._whatVars) : spec._nGen;
2092
2093 RooDataSet* ret = generate(*spec._genContext,spec._whatVars,spec._protoData, nEvt,false,spec._randProto,spec._resampleProto,
2094 spec._init,spec._extended) ;
2095 spec._init = true ;
2096 return ret ;
2097}
2098
2099
2100
2101
2102
2103////////////////////////////////////////////////////////////////////////////////
2104/// Generate a new dataset containing the specified variables with
2105/// events sampled from our distribution.
2106///
2107/// \param[in] whatVars Generate a dataset with the variables (and categories) in this set.
2108/// Any variables of this PDF that are not in `whatVars` will use their
2109/// current values and be treated as fixed parameters.
2110/// \param[in] nEvents Generate the specified number of events or else try to use
2111/// expectedEvents() if nEvents <= 0 (default).
2112/// \param[in] verbose Show which generator strategies are being used.
2113/// \param[in] autoBinned If original distribution is binned, return bin centers and randomise weights
2114/// instead of generating single events.
2115/// \param[in] binnedTag
2116/// \param[in] expectedData Call setExpectedData on the genContext.
2117/// \param[in] extended Randomise number of events generated according to Poisson(nEvents). Only useful
2118/// if PDF is extended.
2119/// \return New dataset. Returns zero in case of an error. The caller takes ownership of the returned
2120/// dataset.
2121
2122RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, double nEvents, bool verbose, bool autoBinned, const char* binnedTag, bool expectedData, bool extended) const
2123{
2124 if (nEvents==0 && extendMode()==CanNotBeExtended) {
2125 return new RooDataSet("emptyData","emptyData",whatVars) ;
2126 }
2127
2128 // Request for binned generation
2129 std::unique_ptr<RooAbsGenContext> context{autoGenContext(whatVars,0,0,verbose,autoBinned,binnedTag)};
2130 if (expectedData) {
2131 context->setExpectedData(true) ;
2132 }
2133
2134 RooDataSet *generated = 0;
2135 if(0 != context && context->isValid()) {
2136 generated= context->generate(nEvents, false, extended);
2137 }
2138 else {
2139 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") cannot create a valid context" << endl;
2140 }
2141 return generated;
2142}
2143
2144
2145
2146
2147////////////////////////////////////////////////////////////////////////////////
2148/// Internal method
2149
2150RooDataSet *RooAbsPdf::generate(RooAbsGenContext& context, const RooArgSet &whatVars, const RooDataSet *prototype,
2151 double nEvents, bool /*verbose*/, bool randProtoOrder, bool resampleProto,
2152 bool skipInit, bool extended) const
2153{
2154 if (nEvents==0 && (prototype==0 || prototype->numEntries()==0)) {
2155 return new RooDataSet("emptyData","emptyData",whatVars) ;
2156 }
2157
2158 RooDataSet *generated = 0;
2159
2160 // Resampling implies reshuffling in the implementation
2161 if (resampleProto) {
2162 randProtoOrder=true ;
2163 }
2164
2165 if (randProtoOrder && prototype && prototype->numEntries()!=nEvents) {
2166 coutI(Generation) << "RooAbsPdf::generate (Re)randomizing event order in prototype dataset (Nevt=" << nEvents << ")" << endl ;
2167 Int_t* newOrder = randomizeProtoOrder(prototype->numEntries(),Int_t(nEvents),resampleProto) ;
2168 context.setProtoDataOrder(newOrder) ;
2169 delete[] newOrder ;
2170 }
2171
2172 if(context.isValid()) {
2173 generated= context.generate(nEvents,skipInit,extended);
2174 }
2175 else {
2176 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") do not have a valid generator context" << endl;
2177 }
2178 return generated;
2179}
2180
2181
2182
2183
2184////////////////////////////////////////////////////////////////////////////////
2185/// Generate a new dataset using a prototype dataset as a model,
2186/// with values of the variables in `whatVars` sampled from our distribution.
2187///
2188/// \param[in] whatVars Generate for these variables.
2189/// \param[in] prototype Use this dataset
2190/// as a prototype: the new dataset will contain the same number of
2191/// events as the prototype (by default), and any prototype variables not in
2192/// whatVars will be copied into the new dataset for each generated
2193/// event and also used to set our PDF parameters. The user can specify a
2194/// number of events to generate that will override the default. The result is a
2195/// copy of the prototype dataset with only variables in whatVars
2196/// randomized. Variables in whatVars that are not in the prototype
2197/// will be added as new columns to the generated dataset.
2198/// \param[in] nEvents Number of events to generate. Defaults to 0, which means number
2199/// of event in prototype dataset.
2200/// \param[in] verbose Show which generator strategies are being used.
2201/// \param[in] randProtoOrder Randomise order of retrieval of events from proto dataset.
2202/// \param[in] resampleProto Resample from the proto dataset.
2203/// \return The new dataset. Returns zero in case of an error. The caller takes ownership of the
2204/// returned dataset.
2205
2206RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, const RooDataSet& prototype,
2207 Int_t nEvents, bool verbose, bool randProtoOrder, bool resampleProto) const
2208{
2209 std::unique_ptr<RooAbsGenContext> context{genContext(whatVars,&prototype,0,verbose)};
2210 if (context) {
2211 RooDataSet* data = generate(*context,whatVars,&prototype,nEvents,verbose,randProtoOrder,resampleProto) ;
2212 return data ;
2213 } else {
2214 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") ERROR creating generator context" << endl ;
2215 return nullptr;
2216 }
2217}
2218
2219
2220
2221////////////////////////////////////////////////////////////////////////////////
2222/// Return lookup table with randomized order for nProto prototype events.
2223
2224Int_t* RooAbsPdf::randomizeProtoOrder(Int_t nProto, Int_t, bool resampleProto) const
2225{
2226 // Make output list
2227 Int_t* lut = new Int_t[nProto] ;
2228
2229 // Randomly sample input list into output list
2230 if (!resampleProto) {
2231 // In this mode, randomization is a strict reshuffle of the order
2232 std::iota(lut, lut + nProto, 0); // fill the vector with 0 to nProto - 1
2233 // Shuffle code taken from https://en.cppreference.com/w/cpp/algorithm/random_shuffle.
2234 // The std::random_shuffle function was deprecated in C++17. We could have
2235 // used std::shuffle instead, but this is not straight-forward to use with
2236 // RooRandom::integer() and we didn't want to change the random number
2237 // generator. It might cause unwanted effects like reproducibility problems.
2238 for (int i = nProto-1; i > 0; --i) {
2239 std::swap(lut[i], lut[RooRandom::integer(i+1)]);
2240 }
2241 } else {
2242 // In this mode, we resample, i.e. events can be used more than once
2243 std::generate(lut, lut + nProto, [&]{ return RooRandom::integer(nProto); });
2244 }
2245
2246
2247 return lut ;
2248}
2249
2250
2251
2252////////////////////////////////////////////////////////////////////////////////
2253/// Load generatedVars with the subset of directVars that we can generate events for,
2254/// and return a code that specifies the generator algorithm we will use. A code of
2255/// zero indicates that we cannot generate any of the directVars (in this case, nothing
2256/// should be added to generatedVars). Any non-zero codes will be passed to our generateEvent()
2257/// implementation, but otherwise its value is arbitrary. The default implemetation of
2258/// this method returns zero. Subclasses will usually implement this method using the
2259/// matchArgs() methods to advertise the algorithms they provide.
2260
2261Int_t RooAbsPdf::getGenerator(const RooArgSet &/*directVars*/, RooArgSet &/*generatedVars*/, bool /*staticInitOK*/) const
2262{
2263 return 0 ;
2264}
2265
2266
2267
2268////////////////////////////////////////////////////////////////////////////////
2269/// Interface for one-time initialization to setup the generator for the specified code.
2270
2272{
2273}
2274
2275
2276
2277////////////////////////////////////////////////////////////////////////////////
2278/// Interface for generation of an event using the algorithm
2279/// corresponding to the specified code. The meaning of each code is
2280/// defined by the getGenerator() implementation. The default
2281/// implementation does nothing.
2282
2284{
2285}
2286
2287
2288
2289////////////////////////////////////////////////////////////////////////////////
2290/// Check if given observable can be safely generated using the
2291/// pdfs internal generator mechanism (if that existsP). Observables
2292/// on which a PDF depends via more than route are not safe
2293/// for use with internal generators because they introduce
2294/// correlations not known to the internal generator
2295
2297{
2298 // Arg must be direct server of self
2299 if (!findServer(arg.GetName())) return false ;
2300
2301 // There must be no other dependency routes
2302 for (const auto server : _serverList) {
2303 if(server == &arg) continue;
2304 if(server->dependsOn(arg)) {
2305 return false ;
2306 }
2307 }
2308
2309 return true ;
2310}
2311
2312
2313////////////////////////////////////////////////////////////////////////////////
2314/// Generate a new dataset containing the specified variables with events sampled from our distribution.
2315/// \param[in] whatVars Choose variables in which to generate events. Variables not listed here will remain
2316/// constant and not be used for event generation
2317/// \param[in] arg1,arg2,arg3,arg4,arg5,arg6 Optional RooCmdArg to change behaviour of generateBinned()
2318/// \return RooDataHist *, to be managed by caller.
2319///
2320/// Generate the specified number of events or expectedEvents() if not specified.
2321///
2322/// Any variables of this PDF that are not in whatVars will use their
2323/// current values and be treated as fixed parameters. Returns zero
2324/// in case of an error. The caller takes ownership of the returned
2325/// dataset.
2326///
2327/// The following named arguments are supported
2328/// | Type of CmdArg | Effect on generation
2329/// |---------------------------|-----------------------
2330/// | `Name(const char* name)` | Name of the output dataset
2331/// | `Verbose(bool flag)` | Print informational messages during event generation
2332/// | `NumEvents(int nevt)` | Generate specified number of events
2333/// | `Extended()` | The actual number of events generated will be sampled from a Poisson distribution with mu=nevt.
2334/// This can be *much* faster for peaked PDFs, but the number of events is not exactly what was requested.
2335/// | `ExpectedData()` | Return a binned dataset _without_ statistical fluctuations (also aliased as Asimov())
2336///
2337
2338RooDataHist *RooAbsPdf::generateBinned(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
2339 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6) const
2340{
2341
2342 // Select the pdf-specific commands
2343 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
2344 pc.defineString("dsetName","Name",0,"") ;
2345 pc.defineInt("verbose","Verbose",0,0) ;
2346 pc.defineInt("extended","Extended",0,0) ;
2347 pc.defineInt("nEvents","NumEvents",0,0) ;
2348 pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
2349 pc.defineInt("expectedData","ExpectedData",0,0) ;
2350
2351 // Process and check varargs
2352 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
2353 if (!pc.ok(true)) {
2354 return 0 ;
2355 }
2356
2357 // Decode command line arguments
2358 double nEvents = pc.getDouble("nEventsD") ;
2359 if (nEvents<0) {
2360 nEvents = pc.getInt("nEvents") ;
2361 }
2362 //bool verbose = pc.getInt("verbose") ;
2363 bool extended = pc.getInt("extended") ;
2364 bool expectedData = pc.getInt("expectedData") ;
2365 const char* dsetName = pc.getString("dsetName") ;
2366
2367 if (extended) {
2368 //nEvents = (nEvents==0?Int_t(expectedEvents(&whatVars)+0.5):nEvents) ;
2369 nEvents = (nEvents==0 ? expectedEvents(&whatVars) :nEvents) ;
2370 cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
2371 << GetName() << "::expectedEvents() = " << nEvents << endl ;
2372 // If Poisson fluctuation results in zero events, stop here
2373 if (nEvents==0) {
2374 return 0 ;
2375 }
2376 } else if (nEvents==0) {
2377 cxcoutI(Generation) << "No number of events specified , number of events generated is "
2378 << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
2379 }
2380
2381 // Forward to appropriate implementation
2382 RooDataHist* data = generateBinned(whatVars,nEvents,expectedData,extended) ;
2383
2384 // Rename dataset to given name if supplied
2385 if (dsetName && strlen(dsetName)>0) {
2386 data->SetName(dsetName) ;
2387 }
2388
2389 return data ;
2390}
2391
2392
2393
2394
2395////////////////////////////////////////////////////////////////////////////////
2396/// Generate a new dataset containing the specified variables with
2397/// events sampled from our distribution.
2398///
2399/// \param[in] whatVars Variables that values should be generated for.
2400/// \param[in] nEvents How many events to generate. If `nEvents <=0`, use the value returned by expectedEvents() as target.
2401/// \param[in] expectedData If set to true (false by default), the returned histogram returns the 'expected'
2402/// data sample, i.e. no statistical fluctuations are present.
2403/// \param[in] extended For each bin, generate Poisson(x, mu) events, where `mu` is chosen such that *on average*,
2404/// one would obtain `nEvents` events. This means that the true number of events will fluctuate around the desired value,
2405/// but the generation happens a lot faster.
2406/// Especially if the PDF is sharply peaked, the multinomial event generation necessary to generate *exactly* `nEvents` events can
2407/// be very slow.
2408///
2409/// The binning used for generation of events is the currently set binning for the variables.
2410/// It can e.g. be changed using
2411/// ```
2412/// x.setBins(15);
2413/// x.setRange(-5., 5.);
2414/// pdf.generateBinned(RooArgSet(x), 1000);
2415/// ```
2416///
2417/// Any variables of this PDF that are not in `whatVars` will use their
2418/// current values and be treated as fixed parameters.
2419/// \return RooDataHist* owned by the caller. Returns `nullptr` in case of an error.
2420RooDataHist *RooAbsPdf::generateBinned(const RooArgSet &whatVars, double nEvents, bool expectedData, bool extended) const
2421{
2422 // Create empty RooDataHist
2423 RooDataHist* hist = new RooDataHist("genData","genData",whatVars) ;
2424
2425 // Scale to number of events and introduce Poisson fluctuations
2426 if (nEvents<=0) {
2427 if (!canBeExtended()) {
2428 coutE(InputArguments) << "RooAbsPdf::generateBinned(" << GetName() << ") ERROR: No event count provided and p.d.f does not provide expected number of events" << endl ;
2429 delete hist ;
2430 return nullptr;
2431 } else {
2432
2433 // Don't round in expectedData or extended mode
2434 if (expectedData || extended) {
2435 nEvents = expectedEvents(&whatVars) ;
2436 } else {
2437 nEvents = std::round(expectedEvents(&whatVars));
2438 }
2439 }
2440 }
2441
2442 // Sample p.d.f. distribution
2443 fillDataHist(hist,&whatVars,1,true) ;
2444
2445 vector<int> histOut(hist->numEntries()) ;
2446 double histMax(-1) ;
2447 Int_t histOutSum(0) ;
2448 for (int i=0 ; i<hist->numEntries() ; i++) {
2449 hist->get(i) ;
2450 if (expectedData) {
2451
2452 // Expected data, multiply p.d.f by nEvents
2453 double w=hist->weight()*nEvents ;
2454 hist->set(i, w, sqrt(w));
2455
2456 } else if (extended) {
2457
2458 // Extended mode, set contents to Poisson(pdf*nEvents)
2459 double w = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
2460 hist->set(w,sqrt(w)) ;
2461
2462 } else {
2463
2464 // Regular mode, fill array of weights with Poisson(pdf*nEvents), but to not fill
2465 // histogram yet.
2466 if (hist->weight()>histMax) {
2467 histMax = hist->weight() ;
2468 }
2469 histOut[i] = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
2470 histOutSum += histOut[i] ;
2471 }
2472 }
2473
2474
2475 if (!expectedData && !extended) {
2476
2477 // Second pass for regular mode - Trim/Extend dataset to exact number of entries
2478
2479 // Calculate difference between what is generated so far and what is requested
2480 Int_t nEvtExtra = abs(Int_t(nEvents)-histOutSum) ;
2481 Int_t wgt = (histOutSum>nEvents) ? -1 : 1 ;
2482
2483 // Perform simple binned accept/reject procedure to get to exact event count
2484 std::size_t counter = 0;
2485 bool havePrintedInfo = false;
2486 while(nEvtExtra>0) {
2487
2488 Int_t ibinRand = RooRandom::randomGenerator()->Integer(hist->numEntries()) ;
2489 hist->get(ibinRand) ;
2490 double ranY = RooRandom::randomGenerator()->Uniform(histMax) ;
2491
2492 if (ranY<hist->weight()) {
2493 if (wgt==1) {
2494 histOut[ibinRand]++ ;
2495 } else {
2496 // If weight is negative, prior bin content must be at least 1
2497 if (histOut[ibinRand]>0) {
2498 histOut[ibinRand]-- ;
2499 } else {
2500 continue ;
2501 }
2502 }
2503 nEvtExtra-- ;
2504 }
2505
2506 if ((counter++ > 10*nEvents || nEvents > 1.E7) && !havePrintedInfo) {
2507 havePrintedInfo = true;
2508 coutP(Generation) << "RooAbsPdf::generateBinned(" << GetName() << ") Performing costly accept/reject sampling. If this takes too long, use "
2509 << "extended mode to speed up the process." << std::endl;
2510 }
2511 }
2512
2513 // Transfer working array to histogram
2514 for (int i=0 ; i<hist->numEntries() ; i++) {
2515 hist->get(i) ;
2516 hist->set(histOut[i],sqrt(1.0*histOut[i])) ;
2517 }
2518
2519 } else if (expectedData) {
2520
2521 // Second pass for expectedData mode -- Normalize to exact number of requested events
2522 // Minor difference may be present in first round due to difference between
2523 // bin average and bin integral in sampling bins
2524 double corr = nEvents/hist->sumEntries() ;
2525 for (int i=0 ; i<hist->numEntries() ; i++) {
2526 hist->get(i) ;
2527 hist->set(hist->weight()*corr,sqrt(hist->weight()*corr)) ;
2528 }
2529
2530 }
2531
2532 return hist;
2533}
2534
2535
2536
2537////////////////////////////////////////////////////////////////////////////////
2538/// Special generator interface for generation of 'global observables' -- for RooStats tools
2539
2541{
2542 return generate(whatVars,nEvents) ;
2543}
2544
2545namespace {
2546void removeRangeOverlap(std::vector<std::pair<double, double>>& ranges) {
2547 //Sort from left to right
2548 std::sort(ranges.begin(), ranges.end());
2549
2550 for (auto it = ranges.begin(); it != ranges.end(); ++it) {
2551 double& startL = it->first;
2552 double& endL = it->second;
2553
2554 for (auto innerIt = it+1; innerIt != ranges.end(); ++innerIt) {
2555 const double startR = innerIt->first;
2556 const double endR = innerIt->second;
2557
2558 if (startL <= startR && startR <= endL) {
2559 //Overlapping ranges, extend left one
2560 endL = std::max(endL, endR);
2561 *innerIt = make_pair(0., 0.);
2562 }
2563 }
2564 }
2565
2566 auto newEnd = std::remove_if(ranges.begin(), ranges.end(),
2567 [](const std::pair<double,double>& input){
2568 return input.first == input.second;
2569 });
2570 ranges.erase(newEnd, ranges.end());
2571}
2572}
2573
2574
2575////////////////////////////////////////////////////////////////////////////////
2576/// Plot (project) PDF on specified frame.
2577/// - If a PDF is plotted in an empty frame, it
2578/// will show a unit-normalized curve in the frame variable. When projecting a multi-
2579/// dimensional PDF onto the frame axis, hidden parameters are taken are taken at
2580/// their current value.
2581/// - If a PDF is plotted in a frame in which a dataset has already been plotted, it will
2582/// show a projection integrated over all variables that were present in the shown
2583/// dataset (except for the one on the x-axis). The normalization of the curve will
2584/// be adjusted to the event count of the plotted dataset. An informational message
2585/// will be printed for each projection step that is performed.
2586/// - If a PDF is plotted in a frame showing a dataset *after* a fit, the above happens,
2587/// but the PDF will be drawn and normalised only in the fit range. If this is not desired,
2588/// plotting and normalisation range can be overridden using Range() and NormRange() as
2589/// documented in the table below.
2590///
2591/// This function takes the following named arguments (for more arguments, see also
2592/// RooAbsReal::plotOn(RooPlot*,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,
2593/// const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,
2594/// const RooCmdArg&) const )
2595///
2596///
2597/// <table>
2598/// <tr><th> Type of argument <th> Controlling normalisation
2599/// <tr><td> `NormRange(const char* name)` <td> Calculate curve normalization w.r.t. specified range[s].
2600/// See the tutorial rf212_plottingInRanges_blinding.C
2601/// \note Setting a Range() by default also sets a NormRange() on the same range, meaning that the
2602/// PDF is plotted and normalised in the same range. Overriding this can be useful if the PDF was fit
2603/// in limited range[s] such as side bands, `NormRange("sidebandLeft,sidebandRight")`, but the PDF
2604/// should be drawn in the full range, `Range("")`.
2605///
2606/// <tr><td> `Normalization(double scale, ScaleType code)` <td> Adjust normalization by given scale factor.
2607/// Interpretation of number depends on code:
2608/// `RooAbsReal::Relative`: relative adjustment factor
2609/// `RooAbsReal::NumEvent`: scale to match given number of events.
2610///
2611/// <tr><th> Type of argument <th> Misc control
2612/// <tr><td> `Name(const chat* name)` <td> Give curve specified name in frame. Useful if curve is to be referenced later
2613/// <tr><td> `Asymmetry(const RooCategory& c)` <td> Show the asymmetry of the PDF in given two-state category
2614/// \f$ \frac{F(+)-F(-)}{F(+)+F(-)} \f$ rather than the PDF projection. Category must have two
2615/// states with indices -1 and +1 or three states with indeces -1,0 and +1.
2616/// <tr><td> `ShiftToZero(bool flag)` <td> Shift entire curve such that lowest visible point is at exactly zero.
2617/// Mostly useful when plotting -log(L) or \f$ \chi^2 \f$ distributions
2618/// <tr><td> `AddTo(const char* name, double_t wgtSelf, double_t wgtOther)` <td> Create a projection of this PDF onto the x-axis, but
2619/// instead of plotting it directly, add it to an existing curve with given name (and relative weight factors).
2620/// <tr><td> `Components(const char* names)` <td> When plotting sums of PDFs, plot only the named components (*e.g.* only
2621/// the signal of a signal+background model).
2622/// <tr><td> `Components(const RooArgSet& compSet)` <td> As above, but pass a RooArgSet of the components themselves.
2623///
2624/// <tr><th> Type of argument <th> Projection control
2625/// <tr><td> `Slice(const RooArgSet& set)` <td> Override default projection behaviour by omitting observables listed
2626/// in set from the projection, i.e. by not integrating over these.
2627/// Slicing is usually only sensible in discrete observables, by e.g. creating a slice
2628/// of the PDF at the current value of the category observable.
2629/// <tr><td> `Slice(RooCategory& cat, const char* label)` <td> Override default projection behaviour by omitting the specified category
2630/// observable from the projection, i.e., by not integrating over all states of this category.
2631/// The slice is positioned at the given label value. Multiple Slice() commands can be given to specify slices
2632/// in multiple observables, e.g.
2633/// ```{.cpp}
2634/// pdf.plotOn(frame, Slice(tagCategory, "2tag"), Slice(jetCategory, "3jet"));
2635/// ```
2636/// <tr><td> `Project(const RooArgSet& set)` <td> Override default projection behaviour by projecting
2637/// over observables given in set, completely ignoring the default projection behavior. Advanced use only.
2638/// <tr><td> `ProjWData(const RooAbsData& d)` <td> Override default projection _technique_ (integration). For observables
2639/// present in given dataset projection of PDF is achieved by constructing an average over all observable
2640/// values in given set. Consult RooFit plotting tutorial for further explanation of meaning & use of this technique
2641/// <tr><td> `ProjWData(const RooArgSet& s, const RooAbsData& d)` <td> As above but only consider subset 's' of
2642/// observables in dataset 'd' for projection through data averaging
2643/// <tr><td> `ProjectionRange(const char* rn)` <td> When projecting the PDF onto the plot axis, it is usually integrated
2644/// over the full range of the invisible variables. The ProjectionRange overrides this.
2645/// This is useful if the PDF was fitted in a limited range in y, but it is now projected onto x. If
2646/// `ProjectionRange("<name of fit range>")` is passed, the projection is normalised correctly.
2647///
2648/// <tr><th> Type of argument <th> Plotting control
2649/// <tr><td> `LineStyle(Int_t style)` <td> Select line style by ROOT line style code, default is solid
2650/// <tr><td> `LineColor(Int_t color)` <td> Select line color by ROOT color code, default is blue
2651/// <tr><td> `LineWidth(Int_t width)` <td> Select line with in pixels, default is 3
2652/// <tr><td> `FillStyle(Int_t style)` <td> Select fill style, default is not filled. If a filled style is selected,
2653/// also use VLines() to add vertical downward lines at end of curve to ensure proper closure
2654/// <tr><td> `FillColor(Int_t color)` <td> Select fill color by ROOT color code
2655/// <tr><td> `Range(const char* name)` <td> Only draw curve in range defined by given name. Multiple comma-separated ranges can be given.
2656/// An empty string "" or `nullptr` means to use the default range of the variable.
2657/// <tr><td> `Range(double lo, double hi)` <td> Only draw curve in specified range
2658/// <tr><td> `VLines()` <td> Add vertical lines to y=0 at end points of curve
2659/// <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
2660/// result in more and more densely spaced curve points. A negative precision value will disable
2661/// adaptive point spacing and restrict sampling to the grid point of points defined by the binning
2662/// of the plotted observable (recommended for expensive functions such as profile likelihoods)
2663/// <tr><td> `Invisible(bool flag)` <td> Add curve to frame, but do not display. Useful in combination AddTo()
2664/// <tr><td> `VisualizeError(const RooFitResult& fitres, double Z=1, bool linearMethod=true)`
2665/// <td> Visualize the uncertainty on the parameters, as given in fitres, at 'Z' sigma.
2666/// 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.
2667/// 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
2668/// \note To include the uncertainty from the expected number of events,
2669/// the Normalization() argument with `ScaleType` `RooAbsReal::RelativeExpected` has to be passed, e.g.
2670/// ```{.cpp}
2671/// pdf.plotOn(frame, VisualizeError(fitResult), Normalization(1.0, RooAbsReal::RelativeExpected));
2672/// ```
2673///
2674/// <tr><td> `VisualizeError(const RooFitResult& fitres, const RooArgSet& param, double Z=1, bool linearMethod=true)`
2675/// <td> Visualize the uncertainty on the subset of parameters 'param', as given in fitres, at 'Z' sigma
2676/// </table>
2677
2679{
2680
2681 // Pre-processing if p.d.f. contains a fit range and there is no command specifying one,
2682 // add a fit range as default range
2683 std::unique_ptr<RooCmdArg> plotRange;
2684 std::unique_ptr<RooCmdArg> normRange2;
2685 if (getStringAttribute("fitrange") && !cmdList.FindObject("Range") &&
2686 !cmdList.FindObject("RangeWithName")) {
2687 plotRange.reset(static_cast<RooCmdArg*>(RooFit::Range(getStringAttribute("fitrange")).Clone()));
2688 cmdList.Add(plotRange.get());
2689 }
2690
2691 if (getStringAttribute("fitrange") && !cmdList.FindObject("NormRange")) {
2692 normRange2.reset(static_cast<RooCmdArg*>(RooFit::NormRange(getStringAttribute("fitrange")).Clone()));
2693 cmdList.Add(normRange2.get());
2694 }
2695
2696 if (plotRange || normRange2) {
2697 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f was fitted in a subrange and no explicit "
2698 << (plotRange?"Range()":"") << ((plotRange&&normRange2)?" and ":"")
2699 << (normRange2?"NormRange()":"") << " was specified. Plotting / normalising in fit range. To override, do one of the following"
2700 << "\n\t- Clear the automatic fit range attribute: <pdf>.removeStringAttribute(\"fitrange\");"
2701 << "\n\t- Explicitly specify the plotting range: Range(\"<rangeName>\")."
2702 << "\n\t- Explicitly specify where to compute the normalisation: NormRange(\"<rangeName>\")."
2703 << "\n\tThe default (full) range can be denoted with Range(\"\") / NormRange(\"\")."<< endl ;
2704 }
2705
2706 // Sanity checks
2707 if (plotSanityChecks(frame)) return frame ;
2708
2709 // Select the pdf-specific commands
2710 RooCmdConfig pc(Form("RooAbsPdf::plotOn(%s)",GetName())) ;
2711 pc.defineDouble("scaleFactor","Normalization",0,1.0) ;
2712 pc.defineInt("scaleType","Normalization",0,Relative) ;
2713 pc.defineSet("compSet","SelectCompSet",0) ;
2714 pc.defineString("compSpec","SelectCompSpec",0) ;
2715 pc.defineObject("asymCat","Asymmetry",0) ;
2716 pc.defineDouble("rangeLo","Range",0,-999.) ;
2717 pc.defineDouble("rangeHi","Range",1,-999.) ;
2718 pc.defineString("rangeName","RangeWithName",0,"") ;
2719 pc.defineString("normRangeName","NormRange",0,"") ;
2720 pc.defineInt("rangeAdjustNorm","Range",0,0) ;
2721 pc.defineInt("rangeWNAdjustNorm","RangeWithName",0,0) ;
2722 pc.defineMutex("SelectCompSet","SelectCompSpec") ;
2723 pc.defineMutex("Range","RangeWithName") ;
2724 pc.allowUndefined() ; // unknowns may be handled by RooAbsReal
2725
2726 // Process and check varargs
2727 pc.process(cmdList) ;
2728 if (!pc.ok(true)) {
2729 return frame ;
2730 }
2731
2732 // Decode command line arguments
2733 ScaleType stype = (ScaleType) pc.getInt("scaleType") ;
2734 double scaleFactor = pc.getDouble("scaleFactor") ;
2735 const RooAbsCategoryLValue* asymCat = (const RooAbsCategoryLValue*) pc.getObject("asymCat") ;
2736 const char* compSpec = pc.getString("compSpec") ;
2737 const RooArgSet* compSet = pc.getSet("compSet");
2738 bool haveCompSel = ( (compSpec && strlen(compSpec)>0) || compSet) ;
2739
2740 // Suffix for curve name
2741 std::string nameSuffix ;
2742 if (compSpec && strlen(compSpec)>0) {
2743 nameSuffix.append("_Comp[") ;
2744 nameSuffix.append(compSpec) ;
2745 nameSuffix.append("]") ;
2746 } else if (compSet) {
2747 nameSuffix.append("_Comp[") ;
2748 nameSuffix.append(compSet->contentsString().c_str()) ;
2749 nameSuffix.append("]") ;
2750 }
2751
2752 // Remove PDF-only commands from command list
2753 RooCmdConfig::stripCmdList(cmdList,"SelectCompSet,SelectCompSpec") ;
2754
2755 // Adjust normalization, if so requested
2756 if (asymCat) {
2757 RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.c_str(),0,0,0) ;
2758 cmdList.Add(&cnsuffix);
2759 return RooAbsReal::plotOn(frame,cmdList) ;
2760 }
2761
2762 // More sanity checks
2763 double nExpected(1) ;
2764 if (stype==RelativeExpected) {
2765 if (!canBeExtended()) {
2766 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
2767 << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
2768 return frame ;
2769 }
2770 frame->updateNormVars(*frame->getPlotVar()) ;
2771 nExpected = expectedEvents(frame->getNormVars()) ;
2772 }
2773
2774 if (stype != Raw) {
2775
2776 if (frame->getFitRangeNEvt() && stype==Relative) {
2777
2778 bool hasCustomRange(false), adjustNorm(false) ;
2779
2780 std::vector<pair<double,double> > rangeLim;
2781
2782 // Retrieve plot range to be able to adjust normalization to data
2783 if (pc.hasProcessed("Range")) {
2784
2785 double rangeLo = pc.getDouble("rangeLo") ;
2786 double rangeHi = pc.getDouble("rangeHi") ;
2787 rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
2788 adjustNorm = pc.getInt("rangeAdjustNorm") ;
2789 hasCustomRange = true ;
2790
2791 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range ["
2792 << rangeLo << "," << rangeHi << "]" ;
2793 if (!pc.hasProcessed("NormRange")) {
2794 ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " range" << endl ;
2795 } else {
2796 ccoutI(Plotting) << endl ;
2797 }
2798
2799 nameSuffix.append(Form("_Range[%f_%f]",rangeLo,rangeHi)) ;
2800
2801 } else if (pc.hasProcessed("RangeWithName")) {
2802
2803 for (const std::string& rangeNameToken : ROOT::Split(pc.getString("rangeName", "", false), ",")) {
2804 const char* thisRangeName = rangeNameToken.empty() ? nullptr : rangeNameToken.c_str();
2805 if (thisRangeName && !frame->getPlotVar()->hasRange(thisRangeName)) {
2806 coutE(Plotting) << "Range '" << rangeNameToken << "' not defined for variable '"
2807 << frame->getPlotVar()->GetName() << "'. Ignoring ..." << std::endl;
2808 continue;
2809 }
2810 rangeLim.push_back(frame->getPlotVar()->getRange(thisRangeName));
2811 }
2812 adjustNorm = pc.getInt("rangeWNAdjustNorm") ;
2813 hasCustomRange = true ;
2814
2815 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range '" << pc.getString("rangeName", "", false) << "'" ;
2816 if (!pc.hasProcessed("NormRange")) {
2817 ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " range" << endl ;
2818 } else {
2819 ccoutI(Plotting) << endl ;
2820 }
2821
2822 nameSuffix.append(Form("_Range[%s]",pc.getString("rangeName"))) ;
2823 }
2824 // Specification of a normalization range override those in a regular range
2825 if (pc.hasProcessed("NormRange")) {
2826 rangeLim.clear();
2827 for (const auto& rangeNameToken : ROOT::Split(pc.getString("normRangeName", "", false), ",")) {
2828 const char* thisRangeName = rangeNameToken.empty() ? nullptr : rangeNameToken.c_str();
2829 if (thisRangeName && !frame->getPlotVar()->hasRange(thisRangeName)) {
2830 coutE(Plotting) << "Range '" << rangeNameToken << "' not defined for variable '"
2831 << frame->getPlotVar()->GetName() << "'. Ignoring ..." << std::endl;
2832 continue;
2833 }
2834 rangeLim.push_back(frame->getPlotVar()->getRange(thisRangeName));
2835 }
2836 adjustNorm = true ;
2837 hasCustomRange = true ;
2838 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f. curve is normalized using explicit choice of ranges '" << pc.getString("normRangeName", "", false) << "'" << endl ;
2839
2840 nameSuffix.append(Form("_NormRange[%s]",pc.getString("rangeName"))) ;
2841
2842 }
2843
2844 if (hasCustomRange && adjustNorm) {
2845 // If overlapping ranges were given, remove them now
2846 const std::size_t oldSize = rangeLim.size();
2847 removeRangeOverlap(rangeLim);
2848
2849 if (oldSize != rangeLim.size() && !pc.hasProcessed("NormRange")) {
2850 // User gave overlapping ranges. This leads to double-counting events and integrals, and must
2851 // therefore be avoided. If a NormRange has been given, the overlap is alreay gone.
2852 // It's safe to plot even with overlap now.
2853 coutE(Plotting) << "Requested plot/integration ranges overlap. For correct plotting, new ranges "
2854 "will be defined." << std::endl;
2855 auto plotVar = dynamic_cast<RooRealVar*>(frame->getPlotVar());
2856 assert(plotVar);
2857 std::string rangesNoOverlap;
2858 for (auto it = rangeLim.begin(); it != rangeLim.end(); ++it) {
2859 std::stringstream rangeName;
2860 rangeName << "Remove_overlap_range_" << it - rangeLim.begin();
2861 plotVar->setRange(rangeName.str().c_str(), it->first, it->second);
2862 if (!rangesNoOverlap.empty())
2863 rangesNoOverlap += ",";
2864 rangesNoOverlap += rangeName.str();
2865 }
2866
2867 auto rangeArg = static_cast<RooCmdArg*>(cmdList.FindObject("RangeWithName"));
2868 if (rangeArg)
2869 rangeArg->setString(0, rangesNoOverlap.c_str());
2870 else {
2871 plotRange = std::make_unique<RooCmdArg>(RooFit::Range(rangesNoOverlap.c_str()));
2872 cmdList.Add(plotRange.get());
2873 }
2874 }
2875
2876 double rangeNevt(0) ;
2877 for (const auto& riter : rangeLim) {
2878 double nevt= frame->getFitRangeNEvt(riter.first, riter.second);
2879 rangeNevt += nevt ;
2880 }
2881
2882 scaleFactor *= rangeNevt/nExpected ;
2883
2884 } else {
2885 scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
2886 }
2887 } else if (stype==RelativeExpected) {
2888 scaleFactor *= nExpected ;
2889 } else if (stype==NumEvent) {
2890 scaleFactor /= nExpected ;
2891 }
2892 scaleFactor *= frame->getFitRangeBinW() ;
2893 }
2894 frame->updateNormVars(*frame->getPlotVar()) ;
2895
2896 // Append overriding scale factor command at end of original command list
2897 RooCmdArg tmp = RooFit::Normalization(scaleFactor,Raw) ;
2898 tmp.setInt(1,1) ; // Flag this normalization command as created for internal use (so that VisualizeError can strip it)
2899 cmdList.Add(&tmp) ;
2900
2901 // Was a component selected requested
2902 if (haveCompSel) {
2903
2904 // Get complete set of tree branch nodes
2905 RooArgSet branchNodeSet ;
2906 branchNodeServerList(&branchNodeSet) ;
2907
2908 // Discard any non-RooAbsReal nodes
2909 for (const auto arg : branchNodeSet) {
2910 if (!dynamic_cast<RooAbsReal*>(arg)) {
2911 branchNodeSet.remove(*arg) ;
2912 }
2913 }
2914
2915 // Obtain direct selection
2916 std::unique_ptr<RooArgSet> dirSelNodes;
2917 if (compSet) {
2918 dirSelNodes.reset(static_cast<RooArgSet*>(branchNodeSet.selectCommon(*compSet)));
2919 } else {
2920 dirSelNodes.reset(static_cast<RooArgSet*>(branchNodeSet.selectByName(compSpec)));
2921 }
2922 if (dirSelNodes->getSize()>0) {
2923 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") directly selected PDF components: " << *dirSelNodes << endl ;
2924
2925 // Do indirect selection and activate both
2926 plotOnCompSelect(dirSelNodes.get());
2927 } else {
2928 if (compSet) {
2929 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection set " << *compSet << " does not match any components of p.d.f." << endl ;
2930 } else {
2931 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection expression '" << compSpec << "' does not select any components of p.d.f." << endl ;
2932 }
2933 return 0 ;
2934 }
2935 }
2936
2937
2938 RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.c_str(),0,0,0) ;
2939 cmdList.Add(&cnsuffix);
2940
2941 RooPlot* ret = RooAbsReal::plotOn(frame,cmdList) ;
2942
2943 // Restore selection status ;
2944 if (haveCompSel) plotOnCompSelect(0) ;
2945
2946 return ret ;
2947}
2948
2949
2950//_____________________________________________________________________________
2951/// Plot oneself on 'frame'. In addition to features detailed in RooAbsReal::plotOn(),
2952/// the scale factor for a PDF can be interpreted in three different ways. The interpretation
2953/// is controlled by ScaleType
2954/// ```
2955/// Relative - Scale factor is applied on top of PDF normalization scale factor
2956/// NumEvent - Scale factor is interpreted as a number of events. The surface area
2957/// under the PDF curve will match that of a histogram containing the specified
2958/// number of event
2959/// Raw - Scale factor is applied to the raw (projected) probability density.
2960/// Not too useful, option provided for completeness.
2961/// ```
2962// coverity[PASS_BY_VALUE]
2964{
2965
2966 // Sanity checks
2967 if (plotSanityChecks(frame)) return frame ;
2968
2969 // More sanity checks
2970 double nExpected(1) ;
2971 if (o.stype==RelativeExpected) {
2972 if (!canBeExtended()) {
2973 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
2974 << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
2975 return frame ;
2976 }
2977 frame->updateNormVars(*frame->getPlotVar()) ;
2978 nExpected = expectedEvents(frame->getNormVars()) ;
2979 }
2980
2981 // Adjust normalization, if so requested
2982 if (o.stype != Raw) {
2983
2984 if (frame->getFitRangeNEvt() && o.stype==Relative) {
2985 // If non-default plotting range is specified, adjust number of events in fit range
2986 o.scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
2987 } else if (o.stype==RelativeExpected) {
2988 o.scaleFactor *= nExpected ;
2989 } else if (o.stype==NumEvent) {
2990 o.scaleFactor /= nExpected ;
2991 }
2992 o.scaleFactor *= frame->getFitRangeBinW() ;
2993 }
2994 frame->updateNormVars(*frame->getPlotVar()) ;
2995
2996 return RooAbsReal::plotOn(frame,o) ;
2997}
2998
2999
3000
3001
3002////////////////////////////////////////////////////////////////////////////////
3003/// The following named arguments are supported
3004/// <table>
3005/// <tr><th> Type of CmdArg <th> Effect on parameter box
3006/// <tr><td> `Parameters(const RooArgSet& param)` <td> Only the specified subset of parameters will be shown. By default all non-constant parameters are shown.
3007/// <tr><td> `ShowConstants(bool flag)` <td> Also display constant parameters
3008/// <tr><td> `Format(const char* optStr)` <td> \deprecated Classing parameter formatting options, provided for backward compatibility
3009///
3010/// <tr><td> `Format(const char* what,...)` <td> Parameter formatting options.
3011/// | Parameter | Format
3012/// | ---------------------- | --------------------------
3013/// | `const char* what` | Controls what is shown. "N" adds name, "E" adds error, "A" shows asymmetric error, "U" shows unit, "H" hides the value
3014/// | `FixedPrecision(int n)`| Controls precision, set fixed number of digits
3015/// | `AutoPrecision(int n)` | Controls precision. Number of shown digits is calculated from error + n specified additional digits (1 is sensible default)
3016/// <tr><td> `Label(const chat* label)` <td> Add label to parameter box. Use `\n` for multi-line labels.
3017/// <tr><td> `Layout(double xmin, double xmax, double ymax)` <td> Specify relative position of left/right side of box and top of box.
3018/// Coordinates are given as position on the pad between 0 and 1.
3019/// The lower end of the box is calculated automatically from the number of lines in the box.
3020/// </table>
3021///
3022///
3023/// Example use:
3024/// ```
3025/// pdf.paramOn(frame, Label("fit result"), Format("NEU",AutoPrecision(1)) ) ;
3026/// ```
3027///
3028
3029RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
3030 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
3031 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
3032{
3033 // Stuff all arguments in a list
3034 RooLinkedList cmdList;
3035 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
3036 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
3037 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
3038 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
3039
3040 // Select the pdf-specific commands
3041 RooCmdConfig pc(Form("RooAbsPdf::paramOn(%s)",GetName())) ;
3042 pc.defineString("label","Label",0,"") ;
3043 pc.defineDouble("xmin","Layout",0,0.65) ;
3044 pc.defineDouble("xmax","Layout",1,0.9) ;
3045 pc.defineInt("ymaxi","Layout",0,Int_t(0.9*10000)) ;
3046 pc.defineInt("showc","ShowConstants",0,0) ;
3047 pc.defineSet("params","Parameters",0,0) ;
3048 pc.defineString("formatStr","Format",0,"NELU") ;
3049 pc.defineInt("sigDigit","Format",0,2) ;
3050 pc.defineInt("dummy","FormatArgs",0,0) ;
3051 pc.defineMutex("Format","FormatArgs") ;
3052
3053 // Process and check varargs
3054 pc.process(cmdList) ;
3055 if (!pc.ok(true)) {
3056 return frame ;
3057 }
3058
3059 const char* label = pc.getString("label") ;
3060 double xmin = pc.getDouble("xmin") ;
3061 double xmax = pc.getDouble("xmax") ;
3062 double ymax = pc.getInt("ymaxi") / 10000. ;
3063 Int_t showc = pc.getInt("showc") ;
3064
3065
3066 const char* formatStr = pc.getString("formatStr") ;
3067 Int_t sigDigit = pc.getInt("sigDigit") ;
3068
3069 // Decode command line arguments
3070 RooArgSet* params = pc.getSet("params");
3071 if (!params) {
3072 std::unique_ptr<RooArgSet> paramsPtr{getParameters(frame->getNormVars())} ;
3073 if (pc.hasProcessed("FormatArgs")) {
3074 const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
3075 paramOn(frame,*paramsPtr,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
3076 } else {
3077 paramOn(frame,*paramsPtr,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
3078 }
3079 } else {
3080 std::unique_ptr<RooArgSet> pdfParams{getParameters(frame->getNormVars())} ;
3081 std::unique_ptr<RooArgSet> selParams{static_cast<RooArgSet*>(pdfParams->selectCommon(*params))} ;
3082 if (pc.hasProcessed("FormatArgs")) {
3083 const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
3084 paramOn(frame,*selParams,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
3085 } else {
3086 paramOn(frame,*selParams,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
3087 }
3088 }
3089
3090 return frame ;
3091}
3092
3093
3094
3095
3096////////////////////////////////////////////////////////////////////////////////
3097/// \deprecated Obsolete, provided for backward compatibility. Don't use.
3098
3099RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooAbsData* data, const char *label,
3100 Int_t sigDigits, Option_t *options, double xmin,
3101 double xmax ,double ymax)
3102{
3103 std::unique_ptr<RooArgSet> params{getParameters(data)} ;
3104 TString opts(options) ;
3105 paramOn(frame,*params,opts.Contains("c"),label,sigDigits,options,xmin,xmax,ymax) ;
3106 return frame ;
3107}
3108
3109
3110
3111////////////////////////////////////////////////////////////////////////////////
3112/// Add a text box with the current parameter values and their errors to the frame.
3113/// Observables of this PDF appearing in the 'data' dataset will be omitted.
3114///
3115/// An optional label will be inserted if passed. Multi-line labels can be generated
3116/// by adding `\n` to the label string. Use 'sigDigits'
3117/// to modify the default number of significant digits printed. The 'xmin,xmax,ymax'
3118/// values specify the initial relative position of the text box in the plot frame.
3119
3120RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooArgSet& params, bool showConstants, const char *label,
3121 Int_t sigDigits, Option_t *options, double xmin,
3122 double xmax ,double ymax, const RooCmdArg* formatCmd)
3123{
3124
3125 // parse the options
3126 TString opts = options;
3127 opts.ToLower();
3128 bool showLabel= (label != 0 && strlen(label) > 0);
3129
3130 // calculate the box's size, adjusting for constant parameters
3131
3132 double ymin(ymax), dy(0.06);
3133 for (const auto param : params) {
3134 auto var = static_cast<RooRealVar*>(param);
3135 if(showConstants || !var->isConstant()) ymin-= dy;
3136 }
3137
3138 std::string labelString = label;
3139 unsigned int numLines = std::count(labelString.begin(), labelString.end(), '\n') + 1;
3140 if (showLabel) ymin -= numLines * dy;
3141
3142 // create the box and set its options
3143 TPaveText *box= new TPaveText(xmin,ymax,xmax,ymin,"BRNDC");
3144 if(!box) return 0;
3145 box->SetName(Form("%s_paramBox",GetName())) ;
3146 box->SetFillColor(0);
3147 box->SetBorderSize(0);
3148 box->SetTextAlign(12);
3149 box->SetTextSize(0.04F);
3150 box->SetFillStyle(0);
3151
3152 for (const auto param : params) {
3153 auto var = static_cast<const RooRealVar*>(param);
3154 if(var->isConstant() && !showConstants) continue;
3155
3156 std::unique_ptr<TString> formatted{options ? var->format(sigDigits, options) : var->format(*formatCmd)};
3157 box->AddText(formatted->Data());
3158 }
3159
3160 // add the optional label if specified
3161 if (showLabel) {
3162 for (const auto& line : ROOT::Split(label, "\n")) {
3163 box->AddText(line.c_str());
3164 }
3165 }
3166
3167 // Add box to frame
3168 frame->addObject(box) ;
3169
3170 return frame ;
3171}
3172
3173
3174
3175
3176////////////////////////////////////////////////////////////////////////////////
3177/// Return expected number of events from this p.d.f for use in extended
3178/// likelihood calculations. This default implementation returns zero
3179
3181{
3182 return 0 ;
3183}
3184
3185
3186
3187////////////////////////////////////////////////////////////////////////////////
3188/// Change global level of verbosity for p.d.f. evaluations
3189
3191{
3192 _verboseEval = stat ;
3193}
3194
3195
3196
3197////////////////////////////////////////////////////////////////////////////////
3198/// Return global level of verbosity for p.d.f. evaluations
3199
3201{
3202 return _verboseEval ;
3203}
3204
3205
3206
3207////////////////////////////////////////////////////////////////////////////////
3208/// Destructor of normalization cache element. If this element
3209/// provides the 'current' normalization stored in RooAbsPdf::_norm
3210/// zero _norm pointer here before object pointed to is deleted here
3211
3213{
3214 // Zero _norm pointer in RooAbsPdf if it is points to our cache payload
3215 if (_owner) {
3216 RooAbsPdf* pdfOwner = static_cast<RooAbsPdf*>(_owner) ;
3217 if (pdfOwner->_norm == _norm) {
3218 pdfOwner->_norm = 0 ;
3219 }
3220 }
3221
3222 delete _norm ;
3223}
3224
3225
3226
3227////////////////////////////////////////////////////////////////////////////////
3228/// Return a p.d.f that represent a projection of this p.d.f integrated over given observables
3229
3231{
3232 // Construct name for new object
3233 std::string name(GetName()) ;
3234 name.append("_Proj[") ;
3235 if (iset.getSize()>0) {
3236 bool first = true;
3237 for(auto const& arg : iset) {
3238 if (first) {
3239 first = false ;
3240 } else {
3241 name.append(",") ;
3242 }
3243 name.append(arg->GetName()) ;
3244 }
3245 }
3246 name.append("]") ;
3247
3248 // Return projected p.d.f.
3249 return new RooProjectedPdf(name.c_str(),name.c_str(),*this,iset) ;
3250}
3251
3252
3253
3254////////////////////////////////////////////////////////////////////////////////
3255/// Create a cumulative distribution function of this p.d.f in terms
3256/// of the observables listed in iset. If no nset argument is given
3257/// the c.d.f normalization is constructed over the integrated
3258/// observables, so that its maximum value is precisely 1. It is also
3259/// possible to choose a different normalization for
3260/// multi-dimensional p.d.f.s: eg. for a pdf f(x,y,z) one can
3261/// construct a partial cdf c(x,y) that only when integrated itself
3262/// over z results in a maximum value of 1. To construct such a cdf pass
3263/// z as argument to the optional nset argument
3264
3266{
3267 return createCdf(iset,RooFit::SupNormSet(nset)) ;
3268}
3269
3270
3271
3272////////////////////////////////////////////////////////////////////////////////
3273/// Create an object that represents the integral of the function over one or more observables listed in `iset`.
3274/// The actual integration calculation is only performed when the return object is evaluated. The name
3275/// of the integral object is automatically constructed from the name of the input function, the variables
3276/// it integrates and the range integrates over
3277///
3278/// The following named arguments are accepted
3279/// | Type of CmdArg | Effect on CDF
3280/// | ---------------------|-------------------
3281/// | SupNormSet(const RooArgSet&) | Observables over which should be normalized _in addition_ to the integration observables
3282/// | ScanNumCdf() | Apply scanning technique if cdf integral involves numeric integration [ default ]
3283/// | ScanAllCdf() | Always apply scanning technique
3284/// | ScanNoCdf() | Never apply scanning technique
3285/// | 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
3286
3287RooAbsReal* RooAbsPdf::createCdf(const RooArgSet& iset, const RooCmdArg& arg1, const RooCmdArg& arg2,
3288 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
3289 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
3290{
3291 // Define configuration for this method
3292 RooCmdConfig pc(Form("RooAbsReal::createCdf(%s)",GetName())) ;
3293 pc.defineSet("supNormSet","SupNormSet",0,0) ;
3294 pc.defineInt("numScanBins","ScanParameters",0,1000) ;
3295 pc.defineInt("intOrder","ScanParameters",1,2) ;
3296 pc.defineInt("doScanNum","ScanNumCdf",0,1) ;
3297 pc.defineInt("doScanAll","ScanAllCdf",0,0) ;
3298 pc.defineInt("doScanNon","ScanNoCdf",0,0) ;
3299 pc.defineMutex("ScanNumCdf","ScanAllCdf","ScanNoCdf") ;
3300
3301 // Process & check varargs
3302 pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
3303 if (!pc.ok(true)) {
3304 return 0 ;
3305 }
3306
3307 // Extract values from named arguments
3308 const RooArgSet* snset = pc.getSet("supNormSet",0);
3309 RooArgSet nset ;
3310 if (snset) {
3311 nset.add(*snset) ;
3312 }
3313 Int_t numScanBins = pc.getInt("numScanBins") ;
3314 Int_t intOrder = pc.getInt("intOrder") ;
3315 Int_t doScanNum = pc.getInt("doScanNum") ;
3316 Int_t doScanAll = pc.getInt("doScanAll") ;
3317 Int_t doScanNon = pc.getInt("doScanNon") ;
3318
3319 // If scanning technique is not requested make integral-based cdf and return
3320 if (doScanNon) {
3321 return createIntRI(iset,nset) ;
3322 }
3323 if (doScanAll) {
3324 return createScanCdf(iset,nset,numScanBins,intOrder) ;
3325 }
3326 if (doScanNum) {
3327 std::unique_ptr<RooRealIntegral> tmp{static_cast<RooRealIntegral*>(createIntegral(iset))} ;
3328 Int_t isNum= (tmp->numIntRealVars().getSize()>0) ;
3329
3330 if (isNum) {
3331 coutI(NumIntegration) << "RooAbsPdf::createCdf(" << GetName() << ") integration over observable(s) " << iset << " involves numeric integration," << endl
3332 << " constructing cdf though numeric integration of sampled pdf in " << numScanBins << " bins and applying order "
3333 << intOrder << " interpolation on integrated histogram." << endl
3334 << " To override this choice of technique use argument ScanNone(), to change scan parameters use ScanParameters(nbins,order) argument" << endl ;
3335 }
3336
3337 return isNum ? createScanCdf(iset,nset,numScanBins,intOrder) : createIntRI(iset,nset) ;
3338 }
3339 return 0 ;
3340}
3341
3342RooAbsReal* RooAbsPdf::createScanCdf(const RooArgSet& iset, const RooArgSet& nset, Int_t numScanBins, Int_t intOrder)
3343{
3344 string name = string(GetName()) + "_NUMCDF_" + integralNameSuffix(iset,&nset).Data() ;
3345 RooRealVar* ivar = (RooRealVar*) iset.first() ;
3346 ivar->setBins(numScanBins,"numcdf") ;
3347 RooNumCdf* ret = new RooNumCdf(name.c_str(),name.c_str(),*this,*ivar,"numcdf") ;
3348 ret->setInterpolationOrder(intOrder) ;
3349 return ret ;
3350}
3351
3352
3353
3354
3355////////////////////////////////////////////////////////////////////////////////
3356/// This helper function finds and collects all constraints terms of all component p.d.f.s
3357/// and returns a RooArgSet with all those terms.
3358
3359RooArgSet* RooAbsPdf::getAllConstraints(const RooArgSet& observables, RooArgSet& constrainedParams, bool stripDisconnected) const
3360{
3361 RooArgSet* ret = new RooArgSet("AllConstraints") ;
3362
3363 std::unique_ptr<RooArgSet> comps(getComponents());
3364 for (const auto arg : *comps) {
3365 auto pdf = dynamic_cast<const RooAbsPdf*>(arg) ;
3366 if (pdf && !ret->find(pdf->GetName())) {
3367 std::unique_ptr<RooArgSet> compRet(pdf->getConstraints(observables,constrainedParams,stripDisconnected));
3368 if (compRet) {
3369 ret->add(*compRet,false) ;
3370 }
3371 }
3372 }
3373
3374 return ret ;
3375}
3376
3377
3378////////////////////////////////////////////////////////////////////////////////
3379/// Returns the default numeric MC generator configuration for all RooAbsReals
3380
3382{
3384}
3385
3386
3387////////////////////////////////////////////////////////////////////////////////
3388/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3389/// If this object has no specialized configuration, a null pointer is returned
3390
3392{
3393 return _specGeneratorConfig.get();
3394}
3395
3396
3397
3398////////////////////////////////////////////////////////////////////////////////
3399/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3400/// If this object has no specialized configuration, a null pointer is returned,
3401/// unless createOnTheFly is true in which case a clone of the default integrator
3402/// configuration is created, installed as specialized configuration, and returned
3403
3405{
3406 if (!_specGeneratorConfig && createOnTheFly) {
3407 _specGeneratorConfig = std::make_unique<RooNumGenConfig>(*defaultGeneratorConfig()) ;
3408 }
3409 return _specGeneratorConfig.get();
3410}
3411
3412
3413
3414////////////////////////////////////////////////////////////////////////////////
3415/// Return the numeric MC generator configuration used for this object. If
3416/// a specialized configuration was associated with this object, that configuration
3417/// is returned, otherwise the default configuration for all RooAbsReals is returned
3418
3420{
3421 const RooNumGenConfig* config = specialGeneratorConfig() ;
3422 if (config) return config ;
3423 return defaultGeneratorConfig() ;
3424}
3425
3426
3427
3428////////////////////////////////////////////////////////////////////////////////
3429/// Set the given configuration as default numeric MC generator
3430/// configuration for this object
3431
3433{
3434 _specGeneratorConfig = std::make_unique<RooNumGenConfig>(config);
3435}
3436
3437
3438
3439////////////////////////////////////////////////////////////////////////////////
3440/// Remove the specialized numeric MC generator configuration associated
3441/// with this object
3442
3444{
3445 _specGeneratorConfig.reset();
3446}
3447
3448
3449
3450////////////////////////////////////////////////////////////////////////////////
3451
3453{
3454 delete _genContext ;
3455}
3456
3457
3458////////////////////////////////////////////////////////////////////////////////
3459
3460RooAbsPdf::GenSpec::GenSpec(RooAbsGenContext* context, const RooArgSet& whatVars, RooDataSet* protoData, Int_t nGen,
3461 bool extended, bool randProto, bool resampleProto, TString dsetName, bool init) :
3462 _genContext(context), _whatVars(whatVars), _protoData(protoData), _nGen(nGen), _extended(extended),
3463 _randProto(randProto), _resampleProto(resampleProto), _dsetName(dsetName), _init(init)
3464{
3465}
3466
3467
3468
3469////////////////////////////////////////////////////////////////////////////////
3470
3471void RooAbsPdf::setNormRange(const char* rangeName)
3472{
3473 if (rangeName) {
3474 _normRange = rangeName ;
3475 } else {
3476 _normRange.Clear() ;
3477 }
3478
3479 if (_norm) {
3481 _norm = 0 ;
3482 }
3483}
3484
3485
3486////////////////////////////////////////////////////////////////////////////////
3487
3488void RooAbsPdf::setNormRangeOverride(const char* rangeName)
3489{
3490 if (rangeName) {
3491 _normRangeOverride = rangeName ;
3492 } else {
3494 }
3495
3496 if (_norm) {
3498 _norm = 0 ;
3499 }
3500}
3501
3502
3503////////////////////////////////////////////////////////////////////////////////
3504/// Hook function intercepting redirectServer calls. Discard current
3505/// normalization object if any server is redirected
3506
3507bool RooAbsPdf::redirectServersHook(const RooAbsCollection & newServerList, bool mustReplaceAll,
3508 bool nameChange, bool isRecursiveStep)
3509{
3510 // If servers are redirected, the cached normalization integrals and
3511 // normalization sets are most likely invalid.
3513
3514 // Object is own by _normCacheManager that will delete object as soon as cache
3515 // is sterilized by server redirect
3516 _norm = nullptr ;
3517
3518 // Similar to the situation with the normalization integral above: if a
3519 // server is redirected, the cached normalization set might not point to
3520 // the right observables anymore. We need to reset it.
3521 setActiveNormSet(nullptr);
3522 return RooAbsReal::redirectServersHook(newServerList, mustReplaceAll, nameChange, isRecursiveStep);
3523}
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
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
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:3212
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:2036
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:1281
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:1713
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:2283
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:3443
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:3200
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:3180
virtual RooAbsReal * createNLL(RooAbsData &data, const RooLinkedList &cmdList)
Construct representation of -log(L) of PDFwith given dataset.
Definition: RooAbsPdf.cxx:995
virtual RooAbsGenContext * binnedGenContext(const RooArgSet &vars, bool verbose=false) const
Return a binned generator context.
Definition: RooAbsPdf.cxx:1854
RooAbsReal * createScanCdf(const RooArgSet &iset, const RooArgSet &nset, Int_t numScanBins, Int_t intOrder)
Definition: RooAbsPdf.cxx:3342
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:2296
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:2224
void setNormRange(const char *rangeName)
Definition: RooAbsPdf.cxx:3471
~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:1457
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:1689
RooNumGenConfig * specialGeneratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
Definition: RooAbsPdf.cxx:3391
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:3029
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:1837
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:1201
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:3265
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:1480
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:3488
virtual RooDataSet * generateSimGlobal(const RooArgSet &whatVars, Int_t nEvents)
Special generator interface for generation of 'global observables' – for RooStats tools.
Definition: RooAbsPdf.cxx:2540
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:1873
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:3359
const RooNumGenConfig * getGeneratorConfig() const
Return the numeric MC generator configuration used for this object.
Definition: RooAbsPdf.cxx:3419
virtual void initGenerator(Int_t code)
Interface for one-time initialization to setup the generator for the specified code.
Definition: RooAbsPdf.cxx:2271
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:3381
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
The cache manager.
Definition: RooAbsPdf.cxx:3507
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:1818
virtual RooArgSet * getConstraints(const RooArgSet &, RooArgSet &, bool) const
Definition: RooAbsPdf.h:212
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:1864
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:2261
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:3230
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
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Definition: RooFormulaVar.h:30
Class RooGenContext implement a universal generator context for all RooAbsPdf classes that do not hav...
Definition: RooGenContext.h:30
Switches the message service to a different level while the instance is alive.
Definition: RooHelpers.h:42
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:38
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:67
TObject * FindObject(const char *name) const override
Return pointer to obejct with given name.
RooMinimizer is a wrapper class around ROOT::Fit:Fitter that provides a seamless interface between th...
Definition: RooMinimizer.h: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
bool checkIfRangesOverlap(RooAbsPdf const &pdf, RooAbsData const &data, std::vector< std::string > const &rangeNames, bool splitRange)
Check if there is any overlap when a list of ranges is applied to a set of observables.
Definition: RooHelpers.cxx:192
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:303
std::string getColonSeparatedNameString(RooArgSet const &argSet)
Create a string with all sorted names of RooArgSet elements separated by colons.
Definition: RooHelpers.cxx:282
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()