Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooAbsReal.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
19/** \class RooAbsReal
20
21 Abstract base class for objects that represent a
22 real value and implements functionality common to all real-valued objects
23 such as the ability to plot them, to construct integrals of them, the
24 ability to advertise (partial) analytical integrals etc.
25
26 Implementation of RooAbsReal may be derived, thus no interface
27 is provided to modify the contents.
28
29 \ingroup Roofitcore
30*/
31
32#include "RooAbsReal.h"
33
34#include "FitHelpers.h"
36#include "RooAbsData.h"
37#include "RooAddPdf.h"
38#include "RooAddition.h"
39#include "RooArgList.h"
40#include "RooArgProxy.h"
41#include "RooArgSet.h"
42#include "RooBinning.h"
43#include "RooBrentRootFinder.h"
44#include "RooCachedReal.h"
45#include "RooCategory.h"
46#include "RooCmdConfig.h"
47#include "RooConstVar.h"
48#include "RooCurve.h"
49#include "RooCustomizer.h"
50#include "RooDataHist.h"
51#include "RooDataSet.h"
52#include "RooDerivative.h"
53#include "RooFirstMoment.h"
55#include "RooFit/Evaluator.h"
56#include "RooFitResult.h"
57#include "RooFormulaVar.h"
58#include "RooFunctor.h"
59#include "RooGlobalFunc.h"
60#include "RooFitImplHelpers.h"
61#include "RooHist.h"
62#include "RooMoment.h"
63#include "RooMsgService.h"
64#include "RooNumIntConfig.h"
65#include "RooNumRunningInt.h"
66#include "RooParamBinning.h"
67#include "RooPlot.h"
68#include "RooProduct.h"
69#include "RooProfileLL.h"
70#include "RooRealBinding.h"
71#include "RooRealIntegral.h"
72#include "RooRealVar.h"
73#include "RooSecondMoment.h"
74#include "RooVectorDataStore.h"
75#include "TreeReadBuffer.h"
76#include "ValueChecking.h"
77
78#include "ROOT/StringUtils.hxx"
79#include "Compression.h"
80#include "Math/IFunction.h"
81#include "TMath.h"
82#include "TObjString.h"
83#include "TTree.h"
84#include "TH1.h"
85#include "TH2.h"
86#include "TH3.h"
87#include "TBranch.h"
88#include "TLeaf.h"
89#include "TAttLine.h"
90#include "TF1.h"
91#include "TF2.h"
92#include "TF3.h"
93#include "TMatrixD.h"
94#include "TVector.h"
95#include "strlcpy.h"
96#ifndef NDEBUG
97#include <TSystem.h> // To print stack traces when caching errors are detected
98#endif
99
100#include <iomanip>
101#include <iostream>
102#include <limits>
103#include <sstream>
104#include <sys/types.h>
105
106namespace {
107
108// Internal helper RooAbsFunc that evaluates the scaled data-weighted average of
109// given RooAbsReal as a function of a single variable using the RooFit::Evaluator.
110class ScaledDataWeightedAverage : public RooAbsFunc {
111public:
112 ScaledDataWeightedAverage(RooAbsReal const &arg, RooAbsData const &data, double scaleFactor, RooAbsRealLValue &var)
113 : RooAbsFunc{1}, _var{var}, _dataWeights{data.getWeightBatch(0, data.numEntries())}, _scaleFactor{scaleFactor}
114 {
115 _arg = RooFit::Detail::compileForNormSet(arg, *data.get());
116 _arg->recursiveRedirectServers(RooArgList{var});
117 _evaluator = std::make_unique<RooFit::Evaluator>(*_arg);
118 std::stack<std::vector<double>>{}.swap(_vectorBuffers);
119 auto dataSpans = RooFit::BatchModeDataHelpers::getDataSpans(data, "", nullptr, /*skipZeroWeights=*/false,
120 /*takeGlobalObservablesFromData=*/true,
121 _vectorBuffers);
122 for (auto const& item : dataSpans) {
123 _evaluator->setInput(item.first->GetName(), item.second, false);
124 }
125 }
126
127 double operator()(const double xvector[]) const override
128 {
129 double oldVal = _var.getVal();
130 _var.setVal(xvector[0]);
131
132 double out = 0.0;
133 std::span<const double> pdfValues = _evaluator->run();
134 if (_dataWeights.empty()) {
135 out = std::accumulate(pdfValues.begin(), pdfValues.end(), 0.0) / pdfValues.size();
136 } else {
137 double weightsSum = 0.0;
138 for (std::size_t i = 0; i < pdfValues.size(); ++i) {
139 out += pdfValues[i] * _dataWeights[i];
140 weightsSum += _dataWeights[i];
141 }
142 out /= weightsSum;
143 }
144 out *= _scaleFactor;
145
146 _var.setVal(oldVal);
147 return out;
148 }
149 double getMinLimit(UInt_t /*dimension*/) const override { return _var.getMin(); }
150 double getMaxLimit(UInt_t /*dimension*/) const override { return _var.getMax(); }
151
152private:
153 RooAbsRealLValue &_var;
154 std::unique_ptr<RooAbsReal> _arg;
155 std::span<const double> _dataWeights;
156 double _scaleFactor;
157 std::unique_ptr<RooFit::Evaluator> _evaluator;
158 std::stack<std::vector<double>> _vectorBuffers;
159};
160
161struct EvalErrorData {
162 using ErrorList = std::map<const RooAbsArg *, std::pair<std::string, std::list<RooAbsReal::EvalError>>>;
164 int count = 0;
165 ErrorList errorList;
166};
167
168EvalErrorData &evalErrorData()
169{
170 static EvalErrorData data;
171 return data;
172}
173
174} // namespace
175
177{
178 return evalErrorData().errorList.size();
179}
180
181EvalErrorData::ErrorList::iterator RooAbsReal::evalErrorIter()
182{
183 return evalErrorData().errorList.begin();
184}
185
187
189bool RooAbsReal::_hideOffset = true ;
190
191void RooAbsReal::setHideOffset(bool flag) { _hideOffset = flag ; }
193
194
195////////////////////////////////////////////////////////////////////////////////
196/// coverity[UNINIT_CTOR]
197/// Default constructor
198
200
201
202////////////////////////////////////////////////////////////////////////////////
203/// Constructor with unit label
204
205RooAbsReal::RooAbsReal(const char *name, const char *title, const char *unit) : RooAbsReal{name, title, 0.0, 0.0, unit}
206{
207}
208
209
210////////////////////////////////////////////////////////////////////////////////
211/// Constructor with plot range and unit label
212
213RooAbsReal::RooAbsReal(const char *name, const char *title, double inMinVal,
214 double inMaxVal, const char *unit) :
215 RooAbsArg(name,title), _plotMin(inMinVal), _plotMax(inMaxVal), _unit(unit)
216{
217 setValueDirty() ;
218 setShapeDirty() ;
219}
220
221
222////////////////////////////////////////////////////////////////////////////////
223/// Copy constructor
224RooAbsReal::RooAbsReal(const RooAbsReal& other, const char* name) :
225 RooAbsArg(other,name), _plotMin(other._plotMin), _plotMax(other._plotMax),
226 _plotBins(other._plotBins), _value(other._value), _unit(other._unit), _label(other._label),
227 _forceNumInt(other._forceNumInt), _selectComp(other._selectComp)
228{
229 if (other._specIntegratorConfig) {
230 _specIntegratorConfig = std::make_unique<RooNumIntConfig>(*other._specIntegratorConfig) ;
231 }
232}
233
234
235////////////////////////////////////////////////////////////////////////////////
236/// Destructor
237
239{
240 if (_treeReadBuffer) {
241 delete _treeReadBuffer;
242 }
243 _treeReadBuffer = nullptr;
244}
245
246
247////////////////////////////////////////////////////////////////////////////////
248/// Equality operator comparing to a double
249
251{
252 return (getVal()==value) ;
253}
254
255
256
257////////////////////////////////////////////////////////////////////////////////
258/// Equality operator when comparing to another RooAbsArg.
259/// Only functional when the other arg is a RooAbsReal
260
261bool RooAbsReal::operator==(const RooAbsArg& other) const
262{
263 const RooAbsReal* otherReal = dynamic_cast<const RooAbsReal*>(&other) ;
264 return otherReal ? operator==(otherReal->getVal()) : false ;
265}
266
267
268////////////////////////////////////////////////////////////////////////////////
269
270bool RooAbsReal::isIdentical(const RooAbsArg& other, bool assumeSameType) const
271{
272 if (!assumeSameType) {
273 const RooAbsReal* otherReal = dynamic_cast<const RooAbsReal*>(&other) ;
274 return otherReal ? operator==(otherReal->getVal()) : false ;
275 } else {
276 return getVal() == static_cast<const RooAbsReal&>(other).getVal();
277 }
278}
279
280
281////////////////////////////////////////////////////////////////////////////////
282/// Return this variable's title string. If appendUnit is true and
283/// this variable has units, also append a string " (<unit>)".
284
285TString RooAbsReal::getTitle(bool appendUnit) const
286{
287 if(appendUnit && 0 != strlen(getUnit())) {
288 return std::string{GetTitle()} + " (" + getUnit() + ")";
289 }
290 return GetTitle();
291}
292
293
294
295////////////////////////////////////////////////////////////////////////////////
296/// Return value of object. If the cache is clean, return the
297/// cached value, otherwise recalculate on the fly and refill
298/// the cache
299
300double RooAbsReal::getValV(const RooArgSet* nset) const
301{
302 if (nset && nset->uniqueId().value() != _lastNormSetId) {
303 const_cast<RooAbsReal*>(this)->setProxyNormSet(nset);
304 _lastNormSetId = nset->uniqueId().value();
305 }
306
307 if (isValueDirtyAndClear()) {
308 _value = traceEval(nullptr) ;
309 // clearValueDirty() ;
310 }
311
312 return hideOffset() ? _value + offset() : _value;
313}
314
315
316////////////////////////////////////////////////////////////////////////////////
317/// Calculate current value of object, with error tracing wrapper
318
319double RooAbsReal::traceEval(const RooArgSet* /*nset*/) const
320{
321 double value = evaluate() ;
322
323 if (TMath::IsNaN(value)) {
324 logEvalError("function value is NAN") ;
325 }
326
327 //cxcoutD(Tracing) << "RooAbsReal::getValF(" << GetName() << ") operMode = " << _operMode << " recalculated, new value = " << value << std::endl ;
328
329 //Standard tracing code goes here
330 if (!isValidReal(value)) {
331 coutW(Tracing) << "RooAbsReal::traceEval(" << GetName()
332 << "): validation failed: " << value << std::endl ;
333 }
334
335 //Call optional subclass tracing code
336 // traceEvalHook(value) ;
337
338 return value ;
339}
340
341
342
343////////////////////////////////////////////////////////////////////////////////
344/// Variant of getAnalyticalIntegral that is also passed the normalization set
345/// that should be applied to the integrand of which the integral is requested.
346/// For certain operator p.d.f it is useful to overload this function rather
347/// than analyticalIntegralWN() as the additional normalization information
348/// may be useful in determining a more efficient decomposition of the
349/// requested integral.
350
352 const RooArgSet* /*normSet*/, const char* rangeName) const
353{
354 return _forceNumInt ? 0 : getAnalyticalIntegral(allDeps,analDeps,rangeName) ;
355}
356
357
358
359////////////////////////////////////////////////////////////////////////////////
360/// Interface function getAnalyticalIntergral advertises the
361/// analytical integrals that are supported. 'integSet'
362/// is the set of dependents for which integration is requested. The
363/// function should copy the subset of dependents it can analytically
364/// integrate to anaIntSet and return a unique identification code for
365/// this integration configuration. If no integration can be
366/// performed, zero should be returned.
367
368Int_t RooAbsReal::getAnalyticalIntegral(RooArgSet& /*integSet*/, RooArgSet& /*anaIntSet*/, const char* /*rangeName*/) const
369{
370 return 0 ;
371}
372
373
374
375////////////////////////////////////////////////////////////////////////////////
376/// Implements the actual analytical integral(s) advertised by
377/// getAnalyticalIntegral. This functions will only be called with
378/// codes returned by getAnalyticalIntegral, except code zero.
379
380double RooAbsReal::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
381{
382// cout << "RooAbsReal::analyticalIntegralWN(" << GetName() << ") code = " << code << " normSet = " << (normSet?*normSet:RooArgSet()) << std::endl ;
383 if (code==0) return getVal(normSet) ;
384 return analyticalIntegral(code,rangeName) ;
385}
386
387
388
389////////////////////////////////////////////////////////////////////////////////
390/// Implements the actual analytical integral(s) advertised by
391/// getAnalyticalIntegral. This functions will only be called with
392/// codes returned by getAnalyticalIntegral, except code zero.
393
394double RooAbsReal::analyticalIntegral(Int_t code, const char* /*rangeName*/) const
395{
396 // By default no analytical integrals are implemented
397 coutF(Eval) << "RooAbsReal::analyticalIntegral(" << GetName() << ") code " << code << " not implemented" << std::endl ;
398 return 0 ;
399}
400
401
402
403////////////////////////////////////////////////////////////////////////////////
404/// Get the label associated with the variable
405
406const char *RooAbsReal::getPlotLabel() const
407{
408 return _label.IsNull() ? fName.Data() : _label.Data();
409}
410
411
412
413////////////////////////////////////////////////////////////////////////////////
414/// Set the label associated with this variable
415
416void RooAbsReal::setPlotLabel(const char *label)
417{
418 _label= label;
419}
420
421
422
423////////////////////////////////////////////////////////////////////////////////
424///Read object contents from stream (dummy for now)
425
426bool RooAbsReal::readFromStream(std::istream& /*is*/, bool /*compact*/, bool /*verbose*/)
427{
428 return false ;
429}
430
431
432
433////////////////////////////////////////////////////////////////////////////////
434///Write object contents to stream (dummy for now)
435
436void RooAbsReal::writeToStream(std::ostream& /*os*/, bool /*compact*/) const
437{
438}
439
440
441
442////////////////////////////////////////////////////////////////////////////////
443/// Print object value
444
445void RooAbsReal::printValue(std::ostream& os) const
446{
447 os << getVal() ;
448}
449
450
451
452////////////////////////////////////////////////////////////////////////////////
453/// Structure printing
454
455void RooAbsReal::printMultiline(std::ostream& os, Int_t contents, bool verbose, TString indent) const
456{
457 RooAbsArg::printMultiline(os,contents,verbose,indent) ;
458 os << indent << "--- RooAbsReal ---" << std::endl;
459 TString unit(_unit);
460 if(!unit.IsNull()) unit.Prepend(' ');
461 //os << indent << " Value = " << getVal() << unit << std::endl;
462 os << std::endl << indent << " Plot label is \"" << getPlotLabel() << "\"" << "\n";
463}
464
465
466////////////////////////////////////////////////////////////////////////////////
467/// Create a RooProfileLL object that eliminates all nuisance parameters in the
468/// present function. The nuisance parameters are defined as all parameters
469/// of the function except the stated paramsOfInterest
470
472{
473 // Construct name of profile object
474 auto name = std::string(GetName()) + "_Profile[";
475 bool first = true;
476 for (auto const& arg : paramsOfInterest) {
477 if (first) {
478 first = false ;
479 } else {
480 name.append(",") ;
481 }
482 name.append(arg->GetName()) ;
483 }
484 name.append("]") ;
485
486 // Create and return profile object
487 auto out = std::make_unique<RooProfileLL>(name.c_str(),(std::string("Profile of ") + GetTitle()).c_str(),*this,paramsOfInterest);
488 return RooFit::makeOwningPtr<RooAbsReal>(std::move(out));
489}
490
491
492
493
494
495
496////////////////////////////////////////////////////////////////////////////////
497/// Create an object that represents the integral of the function over one or more observables listed in `iset`.
498/// The actual integration calculation is only performed when the returned object is evaluated. The name
499/// of the integral object is automatically constructed from the name of the input function, the variables
500/// it integrates and the range integrates over.
501///
502/// \note The integral over a PDF is usually not normalised (*i.e.*, it is usually not
503/// 1 when integrating the PDF over the full range). In fact, this integral is used *to compute*
504/// the normalisation of each PDF. See the [rf110 tutorial](group__tutorial__roofit.html)
505/// for details on PDF normalisation.
506///
507/// The following named arguments are accepted
508/// | | Effect on integral creation
509/// |--|-------------------------------
510/// | `NormSet(const RooArgSet&)` | Specify normalization set, mostly useful when working with PDFs
511/// | `NumIntConfig(const RooNumIntConfig&)` | Use given configuration for any numeric integration, if necessary
512/// | `Range(const char* name)` | Integrate only over given range. Multiple ranges may be specified by passing multiple Range() arguments
513
515 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
516 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
517{
518 // Define configuration for this method
519 RooCmdConfig pc("RooAbsReal::createIntegral(" + std::string(GetName()) + ")");
520 pc.defineString("rangeName","RangeWithName",0,"",true) ;
521 pc.defineSet("normSet","NormSet",0,nullptr) ;
522 pc.defineObject("numIntConfig","NumIntConfig",0,nullptr) ;
523
524 // Process & check varargs
525 pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
526 if (!pc.ok(true)) {
527 return nullptr;
528 }
529
530 // Extract values from named arguments
531 const char* rangeName = pc.getString("rangeName",nullptr,true) ;
532 const RooArgSet* nset = pc.getSet("normSet",nullptr);
533 const RooNumIntConfig* cfg = static_cast<const RooNumIntConfig*>(pc.getObject("numIntConfig",nullptr)) ;
534
535 return createIntegral(iset,nset,cfg,rangeName) ;
536}
537
538
539
540
541
542////////////////////////////////////////////////////////////////////////////////
543/// Create an object that represents the integral of the function over one or more observables listed in iset.
544/// The actual integration calculation is only performed when the return object is evaluated. The name
545/// of the integral object is automatically constructed from the name of the input function, the variables
546/// it integrates and the range integrates over. If nset is specified the integrand is request
547/// to be normalized over nset (only meaningful when the integrand is a pdf). If rangename is specified
548/// the integral is performed over the named range, otherwise it is performed over the domain of each
549/// integrated observable. If cfg is specified it will be used to configure any numeric integration
550/// aspect of the integral. It will not force the integral to be performed numerically, which is
551/// decided automatically by RooRealIntegral.
552
554 const RooNumIntConfig* cfg, const char* rangeName) const
555{
556 if (!rangeName || strchr(rangeName,',')==nullptr) {
557 // Simple case: integral over full range or single limited range
558 return createIntObj(iset,nset,cfg,rangeName);
559 }
560
561 // Integral over multiple ranges
562 std::vector<std::string> tokens = ROOT::Split(rangeName, ",");
563
564 if(RooHelpers::checkIfRangesOverlap(iset, tokens)) {
565 std::stringstream errMsg;
566 errMsg << GetName() << " : integrating with respect to the variables " << iset << " on the ranges \"" << rangeName
567 << "\" is not possible because the ranges are overlapping";
568 const std::string errMsgString = errMsg.str();
569 coutE(Integration) << errMsgString << std::endl;
570 throw std::invalid_argument(errMsgString);
571 }
572
573 RooArgSet components ;
574 for (const std::string& token : tokens) {
575 components.addOwned(std::unique_ptr<RooAbsReal>{createIntObj(iset,nset,cfg, token.c_str())});
576 }
577
578 const std::string title = std::string("Integral of ") + GetTitle();
579 const std::string fullName = std::string(GetName()) + integralNameSuffix(iset,nset,rangeName).Data();
580
581 auto out = std::make_unique<RooAddition>(fullName.c_str(), title.c_str(), components);
582 out->addOwnedComponents(std::move(components));
583 return RooFit::makeOwningPtr<RooAbsReal>(std::move(out));
584}
585
586
587
588////////////////////////////////////////////////////////////////////////////////
589/// Internal utility function for createIntegral() that creates the actual integral object.
591 const RooNumIntConfig* cfg, const char* rangeName) const
592{
593 // Make internal use copies of iset and nset
594 RooArgSet iset(iset2) ;
595 const RooArgSet* nset = nset2 ;
596
597
598 // Initialize local variables perparing for recursive loop
599 bool error = false ;
600 const RooAbsReal* integrand = this ;
601 std::unique_ptr<RooAbsReal> integral;
602
603 // Handle trivial case of no integration here explicitly
604 if (iset.empty()) {
605
606 const std::string title = std::string("Integral of ") + GetTitle();
607 const std::string name = std::string(GetName()) + integralNameSuffix(iset,nset,rangeName).Data();
608
609 auto out = std::make_unique<RooRealIntegral>(name.c_str(), title.c_str(), *this, iset, nset, cfg, rangeName);
610 return RooFit::makeOwningPtr<RooAbsReal>(std::move(out));
611 }
612
613 // Process integration over remaining integration variables
614 while(!iset.empty()) {
615
616
617 // Find largest set of observables that can be integrated in one go
618 RooArgSet innerSet ;
619 findInnerMostIntegration(iset,innerSet,rangeName) ;
620
621 // If largest set of observables that can be integrated is empty set, problem was ill defined
622 // Postpone error messaging and handling to end of function, exit loop here
623 if (innerSet.empty()) {
624 error = true ;
625 break ;
626 }
627
628 // Prepare name and title of integral to be created
629 const std::string title = std::string("Integral of ") + integrand->GetTitle();
630 const std::string name = std::string(integrand->GetName()) + integrand->integralNameSuffix(innerSet,nset,rangeName).Data();
631
632 std::unique_ptr<RooAbsReal> innerIntegral = std::move(integral);
633
634 // Construct innermost integral
635 integral = std::make_unique<RooRealIntegral>(name.c_str(),title.c_str(),*integrand,innerSet,nset,cfg,rangeName);
636
637 // Integral of integral takes ownership of innermost integral
638 if (innerIntegral) {
639 integral->addOwnedComponents(std::move(innerIntegral));
640 }
641
642 // Remove already integrated observables from to-do list
643 iset.remove(innerSet) ;
644
645 // Send info message on recursion if needed
646 if (integrand == this && !iset.empty()) {
647 coutI(Integration) << GetName() << " : multidimensional integration over observables with parameterized ranges in terms of other integrated observables detected, using recursive integration strategy to construct final integral" << std::endl ;
648 }
649
650 // Prepare for recursion, next integral should integrate last integrand
651 integrand = integral.get();
652
653
654 // Only need normalization set in innermost integration
655 nset = nullptr;
656 }
657
658 if (error) {
659 coutE(Integration) << GetName() << " : ERROR while defining recursive integral over observables with parameterized integration ranges, please check that integration rangs specify uniquely defined integral " << std::endl;
660 return nullptr;
661 }
662
663
664 // After-burner: apply interpolating cache on (numeric) integral if requested by user
665 const char* cacheParamsStr = getStringAttribute("CACHEPARAMINT") ;
666 if (cacheParamsStr && strlen(cacheParamsStr)) {
667
668 std::unique_ptr<RooArgSet> intParams{integral->getVariables()};
669
670 RooArgSet cacheParams = RooHelpers::selectFromArgSet(*intParams, cacheParamsStr);
671
672 if (!cacheParams.empty()) {
673 cxcoutD(Caching) << "RooAbsReal::createIntObj(" << GetName() << ") INFO: constructing " << cacheParams.size()
674 << "-dim value cache for integral over " << iset2 << " as a function of " << cacheParams << " in range " << (rangeName?rangeName:"<none>") << std::endl ;
675 std::string name = Form("%s_CACHE_[%s]",integral->GetName(),cacheParams.contentsString().c_str()) ;
676 auto cachedIntegral = std::make_unique<RooCachedReal>(name.c_str(),name.c_str(),*integral,cacheParams);
677 cachedIntegral->setInterpolationOrder(2) ;
678 cachedIntegral->addOwnedComponents(std::move(integral));
679 cachedIntegral->setCacheSource(true) ;
680 if (integral->operMode()==ADirty) {
681 cachedIntegral->setOperMode(ADirty) ;
682 }
683 //cachedIntegral->disableCache(true) ;
684 return RooFit::makeOwningPtr<RooAbsReal>(std::move(cachedIntegral));
685 }
686 }
687
688 return RooFit::makeOwningPtr(std::move(integral));
689}
690
691
692
693////////////////////////////////////////////////////////////////////////////////
694/// Utility function for createIntObj() that aids in the construct of recursive integrals
695/// over functions with multiple observables with parameterized ranges. This function
696/// finds in a given set allObs over which integration is requested the largeset subset
697/// of observables that can be integrated simultaneously. This subset consists of
698/// observables with fixed ranges and observables with parameterized ranges whose
699/// parameterization does not depend on any observable that is also integrated.
700
701void RooAbsReal::findInnerMostIntegration(const RooArgSet& allObs, RooArgSet& innerObs, const char* rangeName) const
702{
703 // Make lists of
704 // a) integrated observables with fixed ranges,
705 // b) integrated observables with parameterized ranges depending on other integrated observables
706 // c) integrated observables used in definition of any parameterized ranges of integrated observables
707 RooArgSet obsWithFixedRange(allObs) ;
708 RooArgSet obsWithParamRange ;
709 RooArgSet obsServingAsRangeParams ;
710
711 // Loop over all integrated observables
712 for (const auto aarg : allObs) {
713 // Check if observable is real-valued lvalue
714 if (auto arglv = dynamic_cast<RooAbsRealLValue*>(aarg)) {
715
716 // Check if range is parameterized
717 RooAbsBinning& binning = arglv->getBinning(rangeName,false,true) ;
718 if (binning.isParameterized()) {
719 RooArgSet loBoundObs;
720 RooArgSet hiBoundObs;
721 binning.lowBoundFunc()->getObservables(&allObs, loBoundObs) ;
722 binning.highBoundFunc()->getObservables(&allObs, hiBoundObs) ;
723
724 // Check if range parameterization depends on other integrated observables
725 if (loBoundObs.overlaps(allObs) || hiBoundObs.overlaps(allObs)) {
726 obsWithParamRange.add(*aarg) ;
727 obsWithFixedRange.remove(*aarg) ;
728 obsServingAsRangeParams.add(loBoundObs,false) ;
729 obsServingAsRangeParams.add(hiBoundObs,false) ;
730 }
731 }
732 }
733 }
734
735 // Make list of fixed-range observables that are _not_ involved in the parameterization of ranges of other observables
736 RooArgSet obsWithFixedRangeNP(obsWithFixedRange) ;
737 obsWithFixedRangeNP.remove(obsServingAsRangeParams) ;
738
739 // Make list of param-range observables that are _not_ involved in the parameterization of ranges of other observables
740 RooArgSet obsWithParamRangeNP(obsWithParamRange) ;
741 obsWithParamRangeNP.remove(obsServingAsRangeParams) ;
742
743 // Construct inner-most integration: over observables (with fixed or param range) not used in any other param range definitions
744 innerObs.removeAll() ;
745 innerObs.add(obsWithFixedRangeNP) ;
746 innerObs.add(obsWithParamRangeNP) ;
747
748}
749
750
751////////////////////////////////////////////////////////////////////////////////
752/// Construct string with unique suffix name to give to integral object that encodes
753/// integrated observables, normalization observables and the integration range name
754
755TString RooAbsReal::integralNameSuffix(const RooArgSet& iset, const RooArgSet* nset, const char* rangeName, bool omitEmpty) const
756{
757 TString name ;
758 if (!iset.empty()) {
760 if (rangeName) {
761 name.Append("|" + std::string{rangeName});
762 }
763 name.Append("]");
764 } else if (!omitEmpty) {
765 name.Append("_Int[]") ;
766 }
767
768 if (nset && !nset->empty()) {
770 const RooAbsPdf* thisPdf = dynamic_cast<const RooAbsPdf*>(this) ;
771 if (thisPdf && thisPdf->normRange()) {
772 name.Append("|" + std::string{thisPdf->normRange()}) ;
773 }
774 name.Append("]") ;
775 }
776
777 return name ;
778}
779
780
781
782////////////////////////////////////////////////////////////////////////////////
783/// Utility function for plotOn() that creates a projection of a function or p.d.f
784/// to be plotted on a RooPlot.
785/// \ref createPlotProjAnchor "createPlotProjection()"
786
787const RooAbsReal* RooAbsReal::createPlotProjection(const RooArgSet& depVars, const RooArgSet& projVars,
788 RooArgSet*& cloneSet) const
789{
790 return createPlotProjection(depVars,&projVars,cloneSet) ;
791}
792
793
794////////////////////////////////////////////////////////////////////////////////
795/// Utility function for plotOn() that creates a projection of a function or p.d.f
796/// to be plotted on a RooPlot.
797/// \anchor createPlotProjAnchor
798///
799/// Create a new object \f$ G \f$ that represents the normalized projection:
800/// \f[
801/// G[x,p] = \frac{\int F[x,y,p] \; \mathrm{d}\{y\}}
802/// {\int F[x,y,p] \; \mathrm{d}\{x\} \, \mathrm{d}\{y\}}
803/// \f]
804/// where \f$ F[x,y,p] \f$ is the function we represent, and
805/// \f$ \{ p \} \f$ are the remaining variables ("parameters").
806///
807/// \param[in] dependentVars Dependent variables over which to normalise, \f$ \{x\} \f$.
808/// \param[in] projectedVars Variables to project out, \f$ \{ y \} \f$.
809/// \param[out] cloneSet Will be set to a RooArgSet*, which will contain a clone of *this plus its projection integral object.
810/// The latter will also be returned. The caller takes ownership of this set.
811/// \param[in] rangeName Optional range for projection integrals
812/// \param[in] condObs Conditional observables, which are not integrated for normalisation, even if they
813/// are in `dependentVars` or `projectedVars`.
814/// \return A pointer to the newly created object, or zero in case of an
815/// error. The caller is responsible for deleting the `cloneSet` (which includes the returned projection object).
816const RooAbsReal *RooAbsReal::createPlotProjection(const RooArgSet &dependentVars, const RooArgSet *projectedVars,
817 RooArgSet *&cloneSet, const char* rangeName, const RooArgSet* condObs) const
818{
819 // Get the set of our leaf nodes
820 RooArgSet leafNodes;
821 RooArgSet treeNodes;
822 leafNodeServerList(&leafNodes,this);
823 treeNodeServerList(&treeNodes,this) ;
824
825
826 // Check that the dependents are all fundamental. Filter out any that we
827 // do not depend on, and make substitutions by name in our leaf list.
828 // Check for overlaps with the projection variables.
829 for (const auto arg : dependentVars) {
830 if(!arg->isFundamental() && !dynamic_cast<const RooAbsLValue*>(arg)) {
831 coutE(Plotting) << ClassName() << "::" << GetName() << ":createPlotProjection: variable \"" << arg->GetName()
832 << "\" of wrong type: " << arg->ClassName() << std::endl;
833 return nullptr;
834 }
835
836 RooAbsArg *found= treeNodes.find(arg->GetName());
837 if(!found) {
838 coutE(Plotting) << ClassName() << "::" << GetName() << ":createPlotProjection: \"" << arg->GetName()
839 << "\" is not a dependent and will be ignored." << std::endl;
840 continue;
841 }
842 if(found != arg) {
843 if (leafNodes.find(found->GetName())) {
844 leafNodes.replace(*found,*arg);
845 } else {
846 leafNodes.add(*arg) ;
847
848 // Remove any dependents of found, replace by dependents of LV node
849 RooArgSet lvDep;
850 arg->getObservables(&leafNodes, lvDep);
851 for (const auto lvs : lvDep) {
852 RooAbsArg* tmp = leafNodes.find(lvs->GetName()) ;
853 if (tmp) {
854 leafNodes.remove(*tmp) ;
855 leafNodes.add(*lvs) ;
856 }
857 }
858 }
859 }
860
861 // check if this arg is also in the projection set
862 if(nullptr != projectedVars && projectedVars->find(arg->GetName())) {
863 coutE(Plotting) << ClassName() << "::" << GetName() << ":createPlotProjection: \"" << arg->GetName()
864 << "\" cannot be both a dependent and a projected variable." << std::endl;
865 return nullptr;
866 }
867 }
868
869 // Remove the projected variables from the list of leaf nodes, if necessary.
870 if(nullptr != projectedVars) leafNodes.remove(*projectedVars,true);
871
872 // Make a deep-clone of ourself so later operations do not disturb our original state
873 cloneSet = new RooArgSet;
874 if (RooArgSet(*this).snapshot(*cloneSet, true)) {
875 coutE(Plotting) << "RooAbsPdf::createPlotProjection(" << GetName() << ") Couldn't deep-clone PDF, abort," << std::endl ;
876 return nullptr ;
877 }
878 RooAbsReal *theClone= static_cast<RooAbsReal*>(cloneSet->find(GetName()));
879
880 // The remaining entries in our list of leaf nodes are the external
881 // dependents (x) and parameters (p) of the projection. Patch them back
882 // into the theClone. This orphans the nodes they replace, but the orphans
883 // are still in the cloneList and so will be cleaned up eventually.
884 //cout << "redirection leafNodes : " ; leafNodes.Print("1") ;
885
886 std::unique_ptr<RooArgSet> plotLeafNodes{leafNodes.selectCommon(dependentVars)};
887 theClone->recursiveRedirectServers(*plotLeafNodes,false,false,false);
888
889 // Create the set of normalization variables to use in the projection integrand
890 RooArgSet normSet(dependentVars);
891 if(nullptr != projectedVars) normSet.add(*projectedVars);
892 if(nullptr != condObs) {
893 normSet.remove(*condObs,true,true) ;
894 }
895
896 // Try to create a valid projection integral. If no variables are to be projected,
897 // create a null projection anyway to bind our normalization over the dependents
898 // consistently with the way they would be bound with a non-trivial projection.
899 RooArgSet empty;
900 if(nullptr == projectedVars) projectedVars= &empty;
901
902 std::string name = GetName();
903 name += integralNameSuffix(*projectedVars,&normSet,rangeName,true) ;
904
905 std::string title = std::string{"Projection of "} + GetTitle();
906
907 std::unique_ptr<RooAbsReal> projected{theClone->createIntegral(*projectedVars,normSet,rangeName)};
908
909 if(nullptr == projected || !projected->isValid()) {
910 coutE(Plotting) << ClassName() << "::" << GetName() << ":createPlotProjection: cannot integrate out ";
911 projectedVars->printStream(std::cout,kName|kArgs,kSingleLine);
912 return nullptr;
913 }
914
915 if(projected->InheritsFrom(RooRealIntegral::Class())){
916 static_cast<RooRealIntegral&>(*projected).setAllowComponentSelection(true);
917 }
918
919 projected->SetName(name.c_str()) ;
920 projected->SetTitle(title.c_str()) ;
921
922 // Add the projection integral to the cloneSet so that it eventually gets cleaned up by the caller.
923 RooAbsReal *projectedPtr = projected.get();
924 cloneSet->addOwned(std::move(projected));
925
926 // return a const pointer to remind the caller that they do not delete the returned object
927 // directly (it is contained in the cloneSet instead).
928 return projectedPtr;
929}
930
931
932
933////////////////////////////////////////////////////////////////////////////////
934/// Fill the ROOT histogram 'hist' with values sampled from this
935/// function at the bin centers. Our value is calculated by first
936/// integrating out any variables in projectedVars and then scaling
937/// the result by scaleFactor. Returns a pointer to the input
938/// histogram, or zero in case of an error. The input histogram can
939/// be any TH1 subclass, and therefore of arbitrary
940/// dimension. Variables are matched with the (x,y,...) dimensions of
941/// the input histogram according to the order in which they appear
942/// in the input plotVars list. If scaleForDensity is true the
943/// histogram is filled with a the functions density rather than
944/// the functions value (i.e. the value at the bin center is multiplied
945/// with bin volume)
946
948 double scaleFactor, const RooArgSet *projectedVars, bool scaleForDensity,
949 const RooArgSet* condObs, bool setError) const
950{
951 // Do we have a valid histogram to use?
952 if(nullptr == hist) {
953 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: no valid histogram to fill" << std::endl;
954 return nullptr;
955 }
956
957 // Check that the number of plotVars matches the input histogram's dimension
958 Int_t hdim= hist->GetDimension();
959 if(hdim != int(plotVars.size())) {
960 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: plotVars has the wrong dimension" << std::endl;
961 return nullptr;
962 }
963
964
965 // Check that the plot variables are all actually RooRealVars and print a warning if we do not
966 // explicitly depend on one of them. Fill a set (not list!) of cloned plot variables.
967 RooArgSet plotClones;
968 for(std::size_t index= 0; index < plotVars.size(); index++) {
969 const RooAbsArg *var= plotVars.at(index);
970 const RooRealVar *realVar= dynamic_cast<const RooRealVar*>(var);
971 if(nullptr == realVar) {
972 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot plot variable \"" << var->GetName()
973 << "\" of type " << var->ClassName() << std::endl;
974 return nullptr;
975 }
976 if(!this->dependsOn(*realVar)) {
977 coutE(InputArguments) << ClassName() << "::" << GetName()
978 << ":fillHistogram: WARNING: variable is not an explicit dependent: " << realVar->GetName() << std::endl;
979 }
980 plotClones.addClone(*realVar,true); // do not complain about duplicates
981 }
982
983 // Reconnect all plotClones to each other, imported when plotting N-dim integrals with entangled parameterized ranges
984 for(RooAbsArg * pc : plotClones) {
985 pc->recursiveRedirectServers(plotClones,false,false,true) ;
986 }
987
988 // Call checkObservables
989 RooArgSet allDeps(plotClones) ;
990 if (projectedVars) {
991 allDeps.add(*projectedVars) ;
992 }
993 if (checkObservables(&allDeps)) {
994 coutE(InputArguments) << "RooAbsReal::fillHistogram(" << GetName() << ") error in checkObservables, abort" << std::endl ;
995 return hist ;
996 }
997
998 // Create a standalone projection object to use for calculating bin contents
999 RooArgSet *cloneSet = nullptr;
1000 const RooAbsReal *projected= createPlotProjection(plotClones,projectedVars,cloneSet,nullptr,condObs);
1001
1002 cxcoutD(Plotting) << "RooAbsReal::fillHistogram(" << GetName() << ") plot projection object is " << projected->GetName() << std::endl ;
1003
1004 // Prepare to loop over the histogram bins
1005 Int_t xbins(0);
1006 Int_t ybins(1);
1007 Int_t zbins(1);
1008 RooRealVar *xvar = nullptr;
1009 RooRealVar *yvar = nullptr;
1010 RooRealVar *zvar = nullptr;
1011 TAxis *xaxis = nullptr;
1012 TAxis *yaxis = nullptr;
1013 TAxis *zaxis = nullptr;
1014 switch(hdim) {
1015 case 3:
1016 zbins= hist->GetNbinsZ();
1017 zvar= dynamic_cast<RooRealVar*>(plotClones.find(plotVars.at(2)->GetName()));
1018 zaxis= hist->GetZaxis();
1019 assert(nullptr != zvar && nullptr != zaxis);
1020 if (scaleForDensity) {
1021 scaleFactor*= (zaxis->GetXmax() - zaxis->GetXmin())/zbins;
1022 }
1023 // fall through to next case...
1024 case 2:
1025 ybins= hist->GetNbinsY();
1026 yvar= dynamic_cast<RooRealVar*>(plotClones.find(plotVars.at(1)->GetName()));
1027 yaxis= hist->GetYaxis();
1028 assert(nullptr != yvar && nullptr != yaxis);
1029 if (scaleForDensity) {
1030 scaleFactor*= (yaxis->GetXmax() - yaxis->GetXmin())/ybins;
1031 }
1032 // fall through to next case...
1033 case 1:
1034 xbins= hist->GetNbinsX();
1035 xvar= dynamic_cast<RooRealVar*>(plotClones.find(plotVars.at(0)->GetName()));
1036 xaxis= hist->GetXaxis();
1037 assert(nullptr != xvar && nullptr != xaxis);
1038 if (scaleForDensity) {
1039 scaleFactor*= (xaxis->GetXmax() - xaxis->GetXmin())/xbins;
1040 }
1041 break;
1042 default:
1043 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot fill histogram with "
1044 << hdim << " dimensions" << std::endl;
1045 break;
1046 }
1047
1048 // Loop over the input histogram's bins and fill each one with our projection's
1049 // value, calculated at the center.
1051 Int_t xbin(0);
1052 Int_t ybin(0);
1053 Int_t zbin(0);
1054 Int_t bins= xbins*ybins*zbins;
1055 for(Int_t bin= 0; bin < bins; bin++) {
1056 switch(hdim) {
1057 case 3:
1058 if(bin % (xbins*ybins) == 0) {
1059 zbin++;
1060 zvar->setVal(zaxis->GetBinCenter(zbin));
1061 }
1062 // fall through to next case...
1063 case 2:
1064 if(bin % xbins == 0) {
1065 ybin= (ybin%ybins) + 1;
1066 yvar->setVal(yaxis->GetBinCenter(ybin));
1067 }
1068 // fall through to next case...
1069 case 1:
1070 xbin= (xbin%xbins) + 1;
1071 xvar->setVal(xaxis->GetBinCenter(xbin));
1072 break;
1073 default:
1074 coutE(InputArguments) << "RooAbsReal::fillHistogram: Internal Error!" << std::endl;
1075 break;
1076 }
1077
1078 double result= scaleFactor*projected->getVal();
1079 if (RooAbsReal::numEvalErrors()>0) {
1080 coutW(Plotting) << "WARNING: Function evaluation error(s) at coordinates [x]=" << xvar->getVal() ;
1081 if (hdim==2) ccoutW(Plotting) << " [y]=" << yvar->getVal() ;
1082 if (hdim==3) ccoutW(Plotting) << " [z]=" << zvar->getVal() ;
1083 ccoutW(Plotting) << std::endl ;
1084 // RooAbsReal::printEvalErrors(ccoutW(Plotting),10) ;
1085 result = 0 ;
1086 }
1088
1089 hist->SetBinContent(hist->GetBin(xbin,ybin,zbin),result);
1090 if (setError) {
1091 hist->SetBinError(hist->GetBin(xbin,ybin,zbin),sqrt(result)) ;
1092 }
1093
1094 //cout << "bin " << bin << " -> (" << xbin << "," << ybin << "," << zbin << ") = " << result << std::endl;
1095 }
1097
1098 // cleanup
1099 delete cloneSet;
1100
1101 return hist;
1102}
1103
1104
1105
1106////////////////////////////////////////////////////////////////////////////////
1107/// Fill a RooDataHist with values sampled from this function at the
1108/// bin centers. If extendedMode is true, the p.d.f. values is multiplied
1109/// by the number of expected events in each bin
1110///
1111/// An optional scaling by a given scaleFactor can be performed.
1112/// Returns a pointer to the input RooDataHist, or zero
1113/// in case of an error.
1114///
1115/// If correctForBinSize is true the RooDataHist
1116/// is filled with the functions density (function value times the
1117/// bin volume) rather than function value.
1118///
1119/// If showProgress is true
1120/// a process indicator is printed on stdout in steps of one percent,
1121/// which is mostly useful for the sampling of expensive functions
1122/// such as likelihoods
1123
1124RooDataHist* RooAbsReal::fillDataHist(RooDataHist *hist, const RooArgSet* normSet, double scaleFactor,
1125 bool correctForBinSize, bool showProgress) const
1126{
1127 // Do we have a valid histogram to use?
1128 if(nullptr == hist) {
1129 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillDataHist: no valid RooDataHist to fill" << std::endl;
1130 return nullptr;
1131 }
1132
1133 // Call checkObservables
1134 RooArgSet allDeps(*hist->get()) ;
1135 if (checkObservables(&allDeps)) {
1136 coutE(InputArguments) << "RooAbsReal::fillDataHist(" << GetName() << ") error in checkObservables, abort" << std::endl ;
1137 return hist ;
1138 }
1139
1140 // Make deep clone of self and attach to dataset observables
1141 //RooArgSet* origObs = getObservables(hist) ;
1142 RooArgSet cloneSet;
1143 RooArgSet(*this).snapshot(cloneSet, true);
1144 RooAbsReal* theClone = static_cast<RooAbsReal*>(cloneSet.find(GetName()));
1145 theClone->recursiveRedirectServers(*hist->get()) ;
1146 //const_cast<RooAbsReal*>(this)->recursiveRedirectServers(*hist->get()) ;
1147
1148 // Iterator over all bins of RooDataHist and fill weights
1149 Int_t onePct = hist->numEntries()/100 ;
1150 if (onePct==0) {
1151 onePct++ ;
1152 }
1153 for (Int_t i=0 ; i<hist->numEntries() ; i++) {
1154 if (showProgress && (i%onePct==0)) {
1155 ccoutP(Eval) << "." << std::flush ;
1156 }
1157 const RooArgSet* obs = hist->get(i) ;
1158 double binVal = theClone->getVal(normSet?normSet:obs)*scaleFactor ;
1159 if (correctForBinSize) {
1160 binVal*= hist->binVolume() ;
1161 }
1162 hist->set(i, binVal, 0.);
1163 }
1164
1165 return hist;
1166}
1167
1168
1169
1170
1171////////////////////////////////////////////////////////////////////////////////
1172/// Create and fill a ROOT histogram TH1, TH2 or TH3 with the values of this function for the variables with given names.
1173/// \param[in] varNameList List of variables to use for x, y, z axis, separated by ':'
1174/// \param[in] xbins Number of bins for first variable
1175/// \param[in] ybins Number of bins for second variable
1176/// \param[in] zbins Number of bins for third variable
1177/// \return TH1*, which is one of TH[1-3]. The histogram is owned by the caller.
1178///
1179/// For a greater degree of control use
1180/// RooAbsReal::createHistogram(const char *, const RooAbsRealLValue&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&) const
1181///
1182
1183TH1* RooAbsReal::createHistogram(RooStringView varNameList, Int_t xbins, Int_t ybins, Int_t zbins) const
1184{
1185 std::unique_ptr<RooArgSet> vars{getVariables()};
1186
1187 auto varNames = ROOT::Split(varNameList, ",:");
1188 std::vector<RooRealVar*> histVars(3, nullptr);
1189
1190 for(std::size_t iVar = 0; iVar < varNames.size(); ++iVar) {
1191 if(varNames[iVar].empty()) continue;
1192 if(iVar >= 3) {
1193 std::stringstream errMsg;
1194 errMsg << "RooAbsPdf::createHistogram(" << GetName() << ") ERROR more than three variable names passed, but maximum number of supported variables is three";
1195 coutE(Plotting) << errMsg.str() << std::endl;
1196 throw std::invalid_argument(errMsg.str());
1197 }
1198 auto var = static_cast<RooRealVar*>(vars->find(varNames[iVar].c_str()));
1199 if(!var) {
1200 std::stringstream errMsg;
1201 errMsg << "RooAbsPdf::createHistogram(" << GetName() << ") ERROR variable " << varNames[iVar] << " does not exist in argset: " << *vars;
1202 coutE(Plotting) << errMsg.str() << std::endl;
1203 throw std::runtime_error(errMsg.str());
1204 }
1205 histVars[iVar] = var;
1206 }
1207
1208 // Construct list of named arguments to pass to the implementation version of createHistogram()
1209
1210 RooLinkedList argList ;
1211 if (xbins>0) {
1212 argList.Add(RooFit::Binning(xbins).Clone()) ;
1213 }
1214
1215 if (histVars[1]) {
1216 argList.Add(RooFit::YVar(*histVars[1], ybins > 0 ? RooFit::Binning(ybins) : RooCmdArg::none()).Clone()) ;
1217 }
1218
1219 if (histVars[2]) {
1220 argList.Add(RooFit::ZVar(*histVars[2], zbins > 0 ? RooFit::Binning(zbins) : RooCmdArg::none()).Clone()) ;
1221 }
1222
1223 // Call implementation function
1224 TH1* result = createHistogram(GetName(), *histVars[0], argList) ;
1225
1226 // Delete temporary list of RooCmdArgs
1227 argList.Delete() ;
1228
1229 return result ;
1230}
1231
1232
1233
1234////////////////////////////////////////////////////////////////////////////////
1235/// Create and fill a ROOT histogram TH1, TH2 or TH3 with the values of this function.
1236///
1237/// \param[in] name Name of the ROOT histogram
1238/// \param[in] xvar Observable to be std::mapped on x axis of ROOT histogram
1239/// \param[in] arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8 Arguments according to list below
1240/// \return TH1 *, one of TH{1,2,3}. The caller takes ownership.
1241///
1242/// <table>
1243/// <tr><th><th> Effect on histogram creation
1244/// <tr><td> `IntrinsicBinning()` <td> Apply binning defined by function or pdf (as advertised via binBoundaries() method)
1245/// <tr><td> `Binning(const char* name)` <td> Apply binning with given name to x axis of histogram
1246/// <tr><td> `Binning(RooAbsBinning& binning)` <td> Apply specified binning to x axis of histogram
1247/// <tr><td> `Binning(int nbins, [double lo, double hi])` <td> Apply specified binning to x axis of histogram
1248/// <tr><td> `ConditionalObservables(Args_t &&... argsOrArgSet)` <td> Do not normalise PDF over following observables when projecting PDF into histogram.
1249// Arguments can either be multiple RooRealVar or a single RooArgSet containing them.
1250/// <tr><td> `Scaling(bool)` <td> Apply density-correction scaling (multiply by bin volume), default is true
1251/// <tr><td> `Extended(bool)` <td> Plot event yield instead of probability density (for extended pdfs only)
1252///
1253/// <tr><td> `YVar(const RooAbsRealLValue& var,...)` <td> Observable to be std::mapped on y axis of ROOT histogram.
1254/// The YVar() and ZVar() arguments can be supplied with optional Binning() arguments to control the binning of the Y and Z axes, e.g.
1255/// ```
1256/// createHistogram("histo",x,Binning(-1,1,20), YVar(y,Binning(-1,1,30)), ZVar(z,Binning("zbinning")))
1257/// ```
1258/// <tr><td> `ZVar(const RooAbsRealLValue& var,...)` <td> Observable to be std::mapped on z axis of ROOT histogram
1259/// </table>
1260///
1261///
1262
1264 const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
1265 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
1266{
1267
1269 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
1270 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
1271 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
1272 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
1273
1274 return createHistogram(name,xvar,l) ;
1275}
1276
1277
1278////////////////////////////////////////////////////////////////////////////////
1279/// Internal method implementing createHistogram
1280
1281TH1* RooAbsReal::createHistogram(const char *name, const RooAbsRealLValue& xvar, RooLinkedList& argList) const
1282{
1283
1284 // Define configuration for this method
1285 RooCmdConfig pc("RooAbsReal::createHistogram(" + std::string(GetName()) + ")");
1286 pc.defineInt("scaling","Scaling",0,1) ;
1287 pc.defineInt("intBinning","IntrinsicBinning",0,2) ;
1288 pc.defineInt("extended","Extended",0,2) ;
1289
1290 pc.defineSet("compSet","SelectCompSet",0);
1291 pc.defineString("compSpec","SelectCompSpec",0) ;
1292 pc.defineSet("projObs","ProjectedObservables",0,nullptr) ;
1293 pc.defineObject("yvar","YVar",0,nullptr) ;
1294 pc.defineObject("zvar","ZVar",0,nullptr) ;
1295 pc.defineMutex("SelectCompSet","SelectCompSpec") ;
1296 pc.defineMutex("IntrinsicBinning","Binning") ;
1297 pc.defineMutex("IntrinsicBinning","BinningName") ;
1298 pc.defineMutex("IntrinsicBinning","BinningSpec") ;
1299 pc.allowUndefined() ;
1300
1301 // Process & check varargs
1302 pc.process(argList) ;
1303 if (!pc.ok(true)) {
1304 return nullptr ;
1305 }
1306
1307 RooArgList vars(xvar) ;
1308 RooAbsArg* yvar = static_cast<RooAbsArg*>(pc.getObject("yvar")) ;
1309 if (yvar) {
1310 vars.add(*yvar) ;
1311 }
1312 RooAbsArg* zvar = static_cast<RooAbsArg*>(pc.getObject("zvar")) ;
1313 if (zvar) {
1314 vars.add(*zvar) ;
1315 }
1316
1317 auto projObs = pc.getSet("projObs");
1318 RooArgSet* intObs = nullptr ;
1319
1320 bool doScaling = pc.getInt("scaling") ;
1321 Int_t doIntBinning = pc.getInt("intBinning") ;
1322 Int_t doExtended = pc.getInt("extended") ;
1323
1324 // If doExtended is two, selection is automatic, set to 1 of pdf is extended, to zero otherwise
1325 const RooAbsPdf* pdfSelf = dynamic_cast<const RooAbsPdf*>(this) ;
1326 if (!pdfSelf && doExtended == 1) {
1327 coutW(InputArguments) << "RooAbsReal::createHistogram(" << GetName() << ") WARNING extended mode requested for a non-pdf object, ignored" << std::endl ;
1328 doExtended=0 ;
1329 }
1330 if (pdfSelf && doExtended==1 && pdfSelf->extendMode()==RooAbsPdf::CanNotBeExtended) {
1331 coutW(InputArguments) << "RooAbsReal::createHistogram(" << GetName() << ") WARNING extended mode requested for a non-extendable pdf, ignored" << std::endl ;
1332 doExtended=0 ;
1333 }
1334 if (pdfSelf && doExtended==2) {
1335 doExtended = pdfSelf->extendMode()==RooAbsPdf::CanNotBeExtended ? 0 : 1 ;
1336 } else if(!pdfSelf) {
1337 doExtended = 0;
1338 }
1339
1340 const char* compSpec = pc.getString("compSpec") ;
1341 const RooArgSet* compSet = pc.getSet("compSet");
1342 bool haveCompSel = ( (compSpec && strlen(compSpec)>0) || compSet) ;
1343
1344 std::unique_ptr<RooBinning> intBinning;
1345 if (doIntBinning>0) {
1346 // Given RooAbsPdf* pdf and RooRealVar* obs
1347 std::unique_ptr<std::list<double>> bl{binBoundaries(const_cast<RooAbsRealLValue&>(xvar),xvar.getMin(),xvar.getMax())};
1348 if (!bl) {
1349 // Only emit warning when intrinsic binning is explicitly requested
1350 if (doIntBinning==1) {
1351 coutW(InputArguments) << "RooAbsReal::createHistogram(" << GetName()
1352 << ") WARNING, intrinsic model binning requested for histogram, but model does not define bin boundaries, reverting to default binning"<< std::endl ;
1353 }
1354 } else {
1355 if (doIntBinning==2) {
1356 coutI(InputArguments) << "RooAbsReal::createHistogram(" << GetName()
1357 << ") INFO: Model has intrinsic binning definition, selecting that binning for the histogram"<< std::endl ;
1358 }
1359 std::vector<double> edges(bl->size());
1360 int i=0 ;
1361 for (auto const& elem : *bl) { edges[i++] = elem ; }
1362 intBinning = std::make_unique<RooBinning>(bl->size()-1,edges.data()) ;
1363 }
1364 }
1365
1366 RooLinkedList argListCreate(argList) ;
1367 RooCmdConfig::stripCmdList(argListCreate,"Scaling,ProjectedObservables,IntrinsicBinning,SelectCompSet,SelectCompSpec,Extended") ;
1368
1369 TH1* histo(nullptr) ;
1370 if (intBinning) {
1371 RooCmdArg tmp = RooFit::Binning(*intBinning) ;
1372 argListCreate.Add(&tmp) ;
1373 histo = xvar.createHistogram(name,argListCreate) ;
1374 } else {
1375 histo = xvar.createHistogram(name,argListCreate) ;
1376 }
1377
1378 // Do component selection here
1379 if (haveCompSel) {
1380
1381 // Get complete set of tree branch nodes
1382 RooArgSet branchNodeSet ;
1383 branchNodeServerList(&branchNodeSet) ;
1384
1385 // Discard any non-RooAbsReal nodes
1386 for(RooAbsArg * arg : branchNodeSet) {
1387 if (!dynamic_cast<RooAbsReal*>(arg)) {
1388 branchNodeSet.remove(*arg) ;
1389 }
1390 }
1391
1392 std::unique_ptr<RooArgSet> dirSelNodes;
1393 if (compSet) {
1394 dirSelNodes = std::unique_ptr<RooArgSet>{branchNodeSet.selectCommon(*compSet)};
1395 } else {
1396 dirSelNodes = std::unique_ptr<RooArgSet>{branchNodeSet.selectByName(compSpec)};
1397 }
1398 if (!dirSelNodes->empty()) {
1399 coutI(Plotting) << "RooAbsPdf::createHistogram(" << GetName() << ") directly selected PDF components: " << *dirSelNodes << std::endl ;
1400
1401 // Do indirect selection and activate both
1402 plotOnCompSelect(dirSelNodes.get()) ;
1403 } else {
1404 if (compSet) {
1405 coutE(Plotting) << "RooAbsPdf::createHistogram(" << GetName() << ") ERROR: component selection set " << *compSet << " does not match any components of p.d.f." << std::endl ;
1406 } else {
1407 coutE(Plotting) << "RooAbsPdf::createHistogram(" << GetName() << ") ERROR: component selection expression '" << compSpec << "' does not select any components of p.d.f." << std::endl ;
1408 }
1409 return nullptr ;
1410 }
1411 }
1412
1413 double scaleFactor(1.0) ;
1414 if (doExtended) {
1415 scaleFactor = pdfSelf->expectedEvents(vars) ;
1416 doScaling=false ;
1417 }
1418
1419 fillHistogram(histo,vars,scaleFactor,intObs,doScaling,projObs,false) ;
1420
1421 // Deactivate component selection
1422 if (haveCompSel) {
1423 plotOnCompSelect(nullptr) ;
1424 }
1425
1426
1427 return histo ;
1428}
1429
1430
1431////////////////////////////////////////////////////////////////////////////////
1432/// Helper function for plotting of composite p.d.fs. Given
1433/// a set of selected components that should be plotted,
1434/// find all nodes that (in)directly depend on these selected
1435/// nodes. Mark all directly and indirectly selected nodes
1436/// as 'selected' using the selectComp() method
1437
1439{
1440 // Get complete set of tree branch nodes
1441 RooArgSet branchNodeSet;
1442 branchNodeServerList(&branchNodeSet);
1443
1444 // Discard any non-PDF nodes
1445 // Iterate by number because collection is being modified! Iterators may invalidate ...
1446 for (unsigned int i = 0; i < branchNodeSet.size(); ++i) {
1447 const auto arg = branchNodeSet[i];
1448 if (!dynamic_cast<RooAbsReal*>(arg)) {
1449 branchNodeSet.remove(*arg) ;
1450 }
1451 }
1452
1453 // If no set is specified, restored all selection bits to true
1454 if (!selNodes) {
1455 // Reset PDF selection bits to true
1456 for (const auto arg : branchNodeSet) {
1457 static_cast<RooAbsReal*>(arg)->selectComp(true);
1458 }
1459 return ;
1460 }
1461
1462
1463 // Add all nodes below selected nodes that are value servers
1464 RooArgSet tmp;
1465 for (const auto arg : branchNodeSet) {
1466 for (const auto selNode : *selNodes) {
1467 if (selNode->dependsOn(*arg, nullptr, /*valueOnly=*/true)) {
1468 tmp.add(*arg,true);
1469 }
1470 }
1471 }
1472
1473 // Add all nodes that depend on selected nodes by value
1474 for (const auto arg : branchNodeSet) {
1475 if (arg->dependsOn(*selNodes, nullptr, /*valueOnly=*/true)) {
1476 tmp.add(*arg,true);
1477 }
1478 }
1479
1480 tmp.remove(*selNodes, true);
1481 tmp.remove(*this);
1482 selNodes->add(tmp);
1483 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") indirectly selected PDF components: " << tmp << std::endl ;
1484
1485 // Set PDF selection bits according to selNodes
1486 for (const auto arg : branchNodeSet) {
1487 bool select = selNodes->find(arg->GetName()) != nullptr;
1488 static_cast<RooAbsReal*>(arg)->selectComp(select);
1489 }
1490}
1491
1492
1493
1494////////////////////////////////////////////////////////////////////////////////
1495/// Plot (project) PDF on specified frame. If a PDF is plotted in an empty frame, it
1496/// will show a unit normalized curve in the frame variable, taken at the present value
1497/// of other observables defined for this PDF.
1498///
1499/// \param[in] frame pointer to RooPlot
1500/// \param[in] arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10 Ordered arguments
1501///
1502/// If a PDF is plotted in a frame in which a dataset has already been plotted, it will
1503/// show a projected curve integrated over all variables that were present in the shown
1504/// dataset except for the one on the x-axis. The normalization of the curve will also
1505/// be adjusted to the event count of the plotted dataset. An informational message
1506/// will be printed for each projection step that is performed.
1507///
1508/// This function takes the following named arguments
1509/// <table>
1510/// <tr><th><th> Projection control
1511/// <tr><td> `Slice(const RooArgSet& set)` <td> Override default projection behaviour by omitting observables listed
1512/// in set from the projection, i.e. by not integrating over these.
1513/// Slicing is usually only sensible in discrete observables, by e.g. creating a slice
1514/// of the PDF at the current value of the category observable.
1515///
1516/// <tr><td> `Slice(RooCategory& cat, const char* label)` <td> Override default projection behaviour by omitting the specified category
1517/// observable from the projection, i.e., by not integrating over all states of this category.
1518/// The slice is positioned at the given label value. To pass multiple Slice() commands, please use the
1519/// Slice(std::map<RooCategory*, std::string> const&) argument explained below.
1520///
1521/// <tr><td> `Slice(std::map<RooCategory*, std::string> const&)` <td> Omits multiple categories from the projection, as explianed above.
1522/// Can be used with initializer lists for convenience, e.g.
1523/// ```{.cpp}
1524/// pdf.plotOn(frame, Slice({{&tagCategory, "2tag"}, {&jetCategory, "3jet"}});
1525/// ```
1526///
1527/// <tr><td> `Project(const RooArgSet& set)` <td> Override default projection behaviour by projecting over observables
1528/// given in the set, ignoring the default projection behavior. Advanced use only.
1529///
1530/// <tr><td> `ProjWData(const RooAbsData& d)` <td> Override default projection _technique_ (integration). For observables present in given dataset
1531/// projection of PDF is achieved by constructing an average over all observable values in given set.
1532/// Consult RooFit plotting tutorial for further explanation of meaning & use of this technique
1533///
1534/// <tr><td> `ProjWData(const RooArgSet& s, const RooAbsData& d)` <td> As above but only consider subset 's' of observables in dataset 'd' for projection through data averaging
1535///
1536/// <tr><td> `ProjectionRange(const char* rn)` <td> Override default range of projection integrals to a different range specified by given range name.
1537/// This technique allows you to project a finite width slice in a real-valued observable
1538///
1539/// <tr><td> `NumCPU(Int_t ncpu)` <td> Number of CPUs to use simultaneously to calculate data-weighted projections (only in combination with ProjWData)
1540///
1541///
1542/// <tr><th><th> Misc content control
1543/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per curve. A negative
1544/// value suppress output completely, a zero value will only print the error count per p.d.f component,
1545/// a positive value is will print details of each error up to numErr messages per p.d.f component.
1546///
1547/// <tr><td> `EvalErrorValue(double value)` <td> Set curve points at which (pdf) evaluation errors occur to specified value. By default the
1548/// function value is plotted.
1549///
1550/// <tr><td> `Normalization(double scale, ScaleType code)` <td> Adjust normalization by given scale factor. Interpretation of number depends on code:
1551/// - Relative: relative adjustment factor for a normalized function,
1552/// - NumEvent: scale to match given number of events.
1553/// - Raw: relative adjustment factor for an un-normalized function.
1554///
1555/// <tr><td> `Name(const chat* name)` <td> Give curve specified name in frame. Useful if curve is to be referenced later
1556///
1557/// <tr><td> `Asymmetry(const RooCategory& c)` <td> Show the asymmetry of the PDF in given two-state category [F(+)-F(-)] / [F(+)+F(-)] rather than
1558/// the PDF projection. Category must have two states with indices -1 and +1 or three states with
1559/// indices -1,0 and +1.
1560///
1561/// <tr><td> `ShiftToZero(bool flag)` <td> Shift entire curve such that lowest visible point is at exactly zero. Mostly useful when plotting \f$ -\log(L) \f$ or \f$ \chi^2 \f$ distributions
1562///
1563/// <tr><td> `AddTo(const char* name, double_t wgtSelf, double_t wgtOther)` <td> Add constructed projection to already existing curve with given name and relative weight factors
1564/// <tr><td> `Components(const char* names)` <td> When plotting sums of PDFs, plot only the named components (*e.g.* only
1565/// the signal of a signal+background model).
1566/// <tr><td> `Components(const RooArgSet& compSet)` <td> As above, but pass a RooArgSet of the components themselves.
1567///
1568/// <tr><th><th> Plotting control
1569/// <tr><td> `DrawOption(const char* opt)` <td> Select ROOT draw option for resulting TGraph object. Currently supported options are "F" (fill), "L" (line), and "P" (points).
1570/// \note Option "P" will cause RooFit to plot (and treat) this pdf as if it were data! This is intended for plotting "corrected data"-type pdfs such as "data-minus-background" or unfolded datasets.
1571///
1572/// <tr><td> `LineStyle(Int_t style)` <td> Select line style by ROOT line style code, default is solid
1573///
1574/// <tr><td> `LineColor(Int_t color)` <td> Select line color by ROOT color code, default is blue
1575///
1576/// <tr><td> `LineWidth(Int_t width)` <td> Select line with in pixels, default is 3
1577///
1578/// <tr><td> `MarkerStyle(Int_t style)` <td> Select the ROOT marker style, default is 21
1579///
1580/// <tr><td> `MarkerColor(Int_t color)` <td> Select the ROOT marker color, default is black
1581///
1582/// <tr><td> `MarkerSize(double size)` <td> Select the ROOT marker size
1583///
1584/// <tr><td> `FillStyle(Int_t style)` <td> Select fill style, default is not filled. If a filled style is selected, also use VLines()
1585/// to add vertical downward lines at end of curve to ensure proper closure. Add `DrawOption("F")` for filled drawing.
1586/// <tr><td> `FillColor(Int_t color)` <td> Select fill color by ROOT color code
1587///
1588/// <tr><td> `Range(const char* name)` <td> Only draw curve in range defined by given name
1589///
1590/// <tr><td> `Range(double lo, double hi)` <td> Only draw curve in specified range
1591///
1592/// <tr><td> `VLines()` <td> Add vertical lines to y=0 at end points of curve
1593///
1594/// <tr><td> `Precision(double eps)` <td> Control precision of drawn curve w.r.t to scale of plot, default is 1e-3. Higher precision
1595/// will result in more and more densely spaced curve points
1596///
1597/// <tr><td> `Invisible(bool flag)` <td> Add curve to frame, but do not display. Useful in combination AddTo()
1598///
1599/// <tr><td> `VisualizeError(const RooFitResult& fitres, double Z=1, bool linearMethod=true)`
1600/// <td> Visualize the uncertainty on the parameters, as given in fitres, at 'Z' sigma'. 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. 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
1601///
1602/// <tr><td> `VisualizeError(const RooFitResult& fitres, const RooArgSet& param, double Z=1, bool linearMethod=true)`
1603/// <td> Visualize the uncertainty on the subset of parameters 'param', as given in fitres, at 'Z' sigma'
1604/// </table>
1605///
1606/// Details on error band visualization
1607/// -----------------------------------
1608/// *VisualizeError() uses plotOnWithErrorBand(). Documentation of the latter:*
1609/// \see plotOnWithErrorBand()
1610
1611RooPlot* RooAbsReal::plotOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
1612 const RooCmdArg& arg3, const RooCmdArg& arg4,
1613 const RooCmdArg& arg5, const RooCmdArg& arg6,
1614 const RooCmdArg& arg7, const RooCmdArg& arg8,
1615 const RooCmdArg& arg9, const RooCmdArg& arg10) const
1616{
1618 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
1619 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
1620 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
1621 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
1622 l.Add((TObject*)&arg9) ; l.Add((TObject*)&arg10) ;
1623 return plotOn(frame,l) ;
1624}
1625
1626
1627
1628////////////////////////////////////////////////////////////////////////////////
1629/// Internal back-end function of plotOn() with named arguments
1630
1632{
1633 // Special handling here if argList contains RangeWithName argument with multiple
1634 // range names -- Need to translate this call into multiple calls
1635
1636 RooCmdArg* rcmd = static_cast<RooCmdArg*>(argList.FindObject("RangeWithName")) ;
1637 if (rcmd && TString(rcmd->getString(0)).Contains(",")) {
1638
1639 // List joint ranges as choice of normalization for all later processing
1640 RooCmdArg rnorm = RooFit::NormRange(rcmd->getString(0)) ;
1641 argList.Add(&rnorm) ;
1642
1643 for (const auto& rangeString : ROOT::Split(rcmd->getString(0), ",")) {
1644 // Process each range with a separate command with a single range to be plotted
1645 rcmd->setString(0, rangeString.c_str());
1646 RooAbsReal::plotOn(frame,argList);
1647 }
1648 return frame ;
1649
1650 }
1651
1652 // Define configuration for this method
1653 RooCmdConfig pc("RooAbsReal::plotOn(" + std::string(GetName()) + ")");
1654 pc.defineString("drawOption","DrawOption",0,"L") ;
1655 pc.defineString("projectionRangeName","ProjectionRange",0,"",true) ;
1656 pc.defineString("curveNameSuffix","CurveNameSuffix",0,"") ;
1657 pc.defineString("sliceCatState","SliceCat",0,"",true) ;
1658 pc.defineDouble("scaleFactor","Normalization",0,1.0) ;
1659 pc.defineInt("scaleType","Normalization",0,Relative) ;
1660 pc.defineSet("sliceSet","SliceVars",0) ;
1661 pc.defineObject("sliceCatList","SliceCat",0,nullptr,true) ;
1662 // This dummy is needed for plotOn to recognize the "SliceCatMany" command.
1663 // It is not used directly, but the "SliceCat" commands are nested in it.
1664 // Removing this dummy definition results in "ERROR: unrecognized command: SliceCatMany".
1665 pc.defineObject("dummy1","SliceCatMany",0) ;
1666 pc.defineSet("projSet","Project",0) ;
1667 pc.defineObject("asymCat","Asymmetry",0) ;
1668 pc.defineDouble("precision","Precision",0,1e-3) ;
1669 pc.defineDouble("evalErrorVal","EvalErrorValue",0,0) ;
1670 pc.defineInt("doEvalError","EvalErrorValue",0,0) ;
1671 pc.defineInt("shiftToZero","ShiftToZero",0,0) ;
1672 pc.defineSet("projDataSet","ProjData",0) ;
1673 pc.defineObject("projData","ProjData",1) ;
1674 pc.defineObject("errorFR","VisualizeError",0) ;
1675 pc.defineDouble("errorZ","VisualizeError",0,1.) ;
1676 pc.defineSet("errorPars","VisualizeError",0) ;
1677 pc.defineInt("linearMethod","VisualizeError",0,0) ;
1678 pc.defineInt("binProjData","ProjData",0,0) ;
1679 pc.defineDouble("rangeLo","Range",0,-999.) ;
1680 pc.defineDouble("rangeHi","Range",1,-999.) ;
1681 pc.defineInt("numee","PrintEvalErrors",0,10) ;
1682 pc.defineInt("rangeAdjustNorm","Range",0,0) ;
1683 pc.defineInt("rangeWNAdjustNorm","RangeWithName",0,0) ;
1684 pc.defineInt("VLines","VLines",0,2) ; // 2==ExtendedWings
1685 pc.defineString("rangeName","RangeWithName",0,"") ;
1686 pc.defineString("normRangeName","NormRange",0,"") ;
1687 pc.defineInt("markerColor","MarkerColor",0,-999) ;
1688 pc.defineInt("markerStyle","MarkerStyle",0,-999) ;
1689 pc.defineDouble("markerSize","MarkerSize",0,-999) ;
1690 pc.defineInt("lineColor","LineColor",0,-999) ;
1691 pc.defineInt("lineStyle","LineStyle",0,-999) ;
1692 pc.defineInt("lineWidth","LineWidth",0,-999) ;
1693 pc.defineInt("fillColor","FillColor",0,-999) ;
1694 pc.defineInt("fillStyle","FillStyle",0,-999) ;
1695 pc.defineString("curveName","Name",0,"") ;
1696 pc.defineInt("curveInvisible","Invisible",0,0) ;
1697 pc.defineInt("showProg","ShowProgress",0,0) ;
1698 pc.defineInt("numCPU","NumCPU",0,1) ;
1699 pc.defineInt("interleave","NumCPU",1,0) ;
1700 pc.defineString("addToCurveName","AddTo",0,"") ;
1701 pc.defineDouble("addToWgtSelf","AddTo",0,1.) ;
1702 pc.defineDouble("addToWgtOther","AddTo",1,1.) ;
1703 pc.defineInt("moveToBack","MoveToBack",0,0) ;
1704 pc.defineMutex("SliceVars","Project") ;
1705 pc.defineMutex("AddTo","Asymmetry") ;
1706 pc.defineMutex("Range","RangeWithName") ;
1707 pc.defineMutex("VisualizeError","VisualizeErrorData") ;
1708
1709 // Process & check varargs
1710 pc.process(argList) ;
1711 if (!pc.ok(true)) {
1712 return frame ;
1713 }
1714
1715 TString drawOpt(pc.getString("drawOption"));
1716
1717 RooFitResult* errFR = static_cast<RooFitResult*>(pc.getObject("errorFR")) ;
1718 if (!drawOpt.Contains("P") && errFR) {
1719 return plotOnWithErrorBand(frame, *errFR, pc.getDouble("errorZ"), pc.getSet("errorPars"), argList,
1720 pc.getInt("linearMethod"));
1721 }
1722
1723 // Extract values from named arguments
1724 PlotOpt o ;
1725 o.numee = pc.getInt("numee") ;
1726 o.drawOptions = drawOpt.Data();
1727 o.curveNameSuffix = pc.getString("curveNameSuffix") ;
1728 o.scaleFactor = pc.getDouble("scaleFactor") ;
1729 o.stype = (ScaleType) pc.getInt("scaleType") ;
1730 o.projData = static_cast<const RooAbsData*>(pc.getObject("projData")) ;
1731 o.binProjData = pc.getInt("binProjData") ;
1732 o.projDataSet = pc.getSet("projDataSet");
1733 o.numCPU = pc.getInt("numCPU") ;
1734 o.interleave = (RooFit::MPSplit) pc.getInt("interleave") ;
1735 o.eeval = pc.getDouble("evalErrorVal") ;
1736 o.doeeval = pc.getInt("doEvalError") ;
1737 o.errorFR = errFR;
1738
1739 const RooArgSet* sliceSetTmp = pc.getSet("sliceSet");
1740 std::unique_ptr<RooArgSet> sliceSet{sliceSetTmp ? static_cast<RooArgSet*>(sliceSetTmp->Clone()) : nullptr};
1741 const RooArgSet* projSet = pc.getSet("projSet") ;
1742 const RooAbsCategoryLValue* asymCat = static_cast<const RooAbsCategoryLValue*>(pc.getObject("asymCat")) ;
1743
1744
1745 // Look for category slice arguments and add them to the master slice list if found
1746 if (const char* sliceCatState = pc.getString("sliceCatState",nullptr,true)) {
1747 const RooLinkedList& sliceCatList = pc.getObjectList("sliceCatList") ;
1748
1749 // Make the master slice set if it doesnt exist
1750 if (!sliceSet) {
1751 sliceSet = std::make_unique<RooArgSet>();
1752 }
1753
1754 // Loop over all categories provided by (multiple) Slice() arguments
1755 auto iter = sliceCatList.begin();
1756 for (auto const& catToken : ROOT::Split(sliceCatState, ",")) {
1757 if (auto scat = static_cast<RooCategory*>(*iter)) {
1758 // Set the slice position to the value indicate by slabel
1759 scat->setLabel(catToken);
1760 // Add the slice category to the master slice set
1761 sliceSet->add(*scat,false) ;
1762 }
1763 ++iter;
1764 }
1765 }
1766
1767 o.precision = pc.getDouble("precision") ;
1768 o.shiftToZero = (pc.getInt("shiftToZero")!=0) ;
1769 Int_t vlines = pc.getInt("VLines");
1770 if (pc.hasProcessed("Range")) {
1771 o.rangeLo = pc.getDouble("rangeLo") ;
1772 o.rangeHi = pc.getDouble("rangeHi") ;
1773 o.postRangeFracScale = pc.getInt("rangeAdjustNorm") ;
1774 if (vlines==2) vlines=0 ; // Default is NoWings if range was specified
1775 } else if (pc.hasProcessed("RangeWithName")) {
1776 o.normRangeName = pc.getString("rangeName",nullptr,true) ;
1777 o.rangeLo = frame->getPlotVar()->getMin(pc.getString("rangeName",nullptr,true)) ;
1778 o.rangeHi = frame->getPlotVar()->getMax(pc.getString("rangeName",nullptr,true)) ;
1779 o.postRangeFracScale = pc.getInt("rangeWNAdjustNorm") ;
1780 if (vlines==2) vlines=0 ; // Default is NoWings if range was specified
1781 }
1782
1783
1784 // If separate normalization range was specified this overrides previous settings
1785 if (pc.hasProcessed("NormRange")) {
1786 o.normRangeName = pc.getString("normRangeName") ;
1787 o.postRangeFracScale = true ;
1788 }
1789
1790 o.wmode = (vlines==2)?RooCurve::Extended:(vlines==1?RooCurve::Straight:RooCurve::NoWings) ;
1791 o.projectionRangeName = pc.getString("projectionRangeName",nullptr,true) ;
1792 o.curveName = pc.getString("curveName",nullptr,true) ;
1793 o.curveInvisible = pc.getInt("curveInvisible") ;
1794 o.progress = pc.getInt("showProg") ;
1795 o.addToCurveName = pc.getString("addToCurveName",nullptr,true) ;
1796 o.addToWgtSelf = pc.getDouble("addToWgtSelf") ;
1797 o.addToWgtOther = pc.getDouble("addToWgtOther") ;
1798
1800 coutE(InputArguments) << "RooAbsReal::plotOn(" << GetName() << ") cannot find existing curve " << o.addToCurveName << " to add to in RooPlot" << std::endl ;
1801 return frame ;
1802 }
1803
1804 RooArgSet projectedVars ;
1805 if (sliceSet) {
1806 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") Preprocessing: have slice " << *sliceSet << std::endl ;
1807
1808 makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,true) ;
1809
1810 // Take out the sliced variables
1811 for (const auto sliceArg : *sliceSet) {
1812 if (RooAbsArg* arg = projectedVars.find(sliceArg->GetName())) {
1813 projectedVars.remove(*arg) ;
1814 } else {
1815 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") slice variable "
1816 << sliceArg->GetName() << " was not projected anyway" << std::endl ;
1817 }
1818 }
1819 } else if (projSet) {
1820 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") Preprocessing: have projSet " << *projSet << std::endl ;
1821 makeProjectionSet(frame->getPlotVar(),projSet,projectedVars,false) ;
1822 } else {
1823 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") Preprocessing: have neither sliceSet nor projSet " << std::endl ;
1824 makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,true) ;
1825 }
1826 o.projSet = &projectedVars ;
1827
1828 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") Preprocessing: projectedVars = " << projectedVars << std::endl ;
1829
1830
1831 // Forward to actual calculation
1832 RooPlot* ret = asymCat ? RooAbsReal::plotAsymOn(frame,*asymCat,o) : RooAbsReal::plotOn(frame,o);
1833
1834 // Optionally adjust line/fill attributes
1835 Int_t lineColor = pc.getInt("lineColor") ;
1836 Int_t lineStyle = pc.getInt("lineStyle") ;
1837 Int_t lineWidth = pc.getInt("lineWidth") ;
1838 Int_t markerColor = pc.getInt("markerColor") ;
1839 Int_t markerStyle = pc.getInt("markerStyle") ;
1840 Size_t markerSize = pc.getDouble("markerSize") ;
1841 Int_t fillColor = pc.getInt("fillColor") ;
1842 Int_t fillStyle = pc.getInt("fillStyle") ;
1843 if (lineColor!=-999) ret->getAttLine()->SetLineColor(lineColor) ;
1844 if (lineStyle!=-999) ret->getAttLine()->SetLineStyle(lineStyle) ;
1845 if (lineWidth!=-999) ret->getAttLine()->SetLineWidth(lineWidth) ;
1846 if (fillColor!=-999) ret->getAttFill()->SetFillColor(fillColor) ;
1847 if (fillStyle!=-999) ret->getAttFill()->SetFillStyle(fillStyle) ;
1848 if (markerColor!=-999) ret->getAttMarker()->SetMarkerColor(markerColor) ;
1849 if (markerStyle!=-999) ret->getAttMarker()->SetMarkerStyle(markerStyle) ;
1850 if (markerSize!=-999) ret->getAttMarker()->SetMarkerSize(markerSize) ;
1851
1852 if ((fillColor != -999 || fillStyle != -999) && !drawOpt.Contains("F")) {
1853 coutW(Plotting) << "Fill color or style was set for plotting \"" << GetName()
1854 << "\", but these only have an effect when 'DrawOption(\"F\")' for fill is used at the same time." << std::endl;
1855 }
1856
1857 // Move last inserted object to back to drawing stack if requested
1858 if (pc.getInt("moveToBack") && frame->numItems()>1) {
1859 frame->drawBefore(frame->getObject(0)->GetName(), frame->getCurve()->GetName());
1860 }
1861
1862 return ret ;
1863}
1864
1865
1866
1867/// Plotting engine function for internal use
1868///
1869/// Plot ourselves on given frame. If frame contains a histogram, all dimensions of the plotted
1870/// function that occur in the previously plotted dataset are projected via partial integration,
1871/// otherwise no projections are performed. Optionally, certain projections can be performed
1872/// by summing over the values present in a provided dataset ('projData'), to correctly
1873/// project out data dependents that are not properly described by the PDF (e.g. per-event errors).
1874///
1875/// The functions value can be multiplied with an optional scale factor. The interpretation
1876/// of the scale factor is unique for generic real functions, for PDFs there are various interpretations
1877/// possible, which can be selection with 'stype' (see RooAbsPdf::plotOn() for details).
1878///
1879/// The default projection behaviour can be overridden by supplying an optional set of dependents
1880/// to project via RooFit command arguments.
1881//_____________________________________________________________________________
1882// coverity[PASS_BY_VALUE]
1884{
1885 // Sanity checks
1886 if (plotSanityChecks(frame)) return frame ;
1887
1888 // ProjDataVars is either all projData observables, or the user indicated subset of it
1889 RooArgSet projDataVars ;
1890 if (o.projData) {
1891 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") have ProjData with observables = " << *o.projData->get() << std::endl ;
1892 if (o.projDataSet) {
1893 projDataVars.add(*std::unique_ptr<RooArgSet>{o.projData->get()->selectCommon(*o.projDataSet)}) ;
1894 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") have ProjDataSet = " << *o.projDataSet << " will only use this subset of projData" << std::endl ;
1895 } else {
1896 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") using full ProjData" << std::endl ;
1897 projDataVars.add(*o.projData->get()) ;
1898 }
1899 }
1900
1901 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") ProjDataVars = " << projDataVars << std::endl ;
1902
1903 // Make list of variables to be projected
1904 RooArgSet projectedVars ;
1905 RooArgSet sliceSet ;
1906 if (o.projSet) {
1907 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") have input projSet = " << *o.projSet << std::endl ;
1908 makeProjectionSet(frame->getPlotVar(),o.projSet,projectedVars,false) ;
1909 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") calculated projectedVars = " << *o.projSet << std::endl ;
1910
1911 // Print list of non-projected variables
1912 if (frame->getNormVars()) {
1913 RooArgSet sliceSetTmp;
1914 getObservables(frame->getNormVars(), sliceSetTmp) ;
1915
1916 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") frame->getNormVars() that are also observables = " << sliceSetTmp << std::endl ;
1917
1918 sliceSetTmp.remove(projectedVars,true,true) ;
1919 sliceSetTmp.remove(*frame->getPlotVar(),true,true) ;
1920
1921 if (o.projData) {
1922 std::unique_ptr<RooArgSet> tmp{projDataVars.selectCommon(*o.projSet)};
1923 sliceSetTmp.remove(*tmp,true,true) ;
1924 }
1925
1926 if (!sliceSetTmp.empty()) {
1927 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on "
1928 << frame->getPlotVar()->GetName() << " represents a slice in " << sliceSetTmp << std::endl ;
1929 }
1930 sliceSet.add(sliceSetTmp) ;
1931 }
1932 } else {
1933 makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,true) ;
1934 }
1935
1936 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") projectedVars = " << projectedVars << " sliceSet = " << sliceSet << std::endl ;
1937
1938
1939 RooArgSet* projDataNeededVars = nullptr ;
1940 // Take out data-projected dependents from projectedVars
1941 if (o.projData) {
1942 projDataNeededVars = projectedVars.selectCommon(projDataVars);
1943 projectedVars.remove(projDataVars,true,true) ;
1944 }
1945
1946 // Get the plot variable and remember its original value
1947 auto* plotVar = static_cast<RooRealVar*>(frame->getPlotVar());
1948 double oldPlotVarVal = plotVar->getVal();
1949
1950 // Inform user about projections
1951 if (!projectedVars.empty()) {
1952 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
1953 << " integrates over variables " << projectedVars
1954 << (o.projectionRangeName?Form(" in range %s",o.projectionRangeName):"") << std::endl;
1955 }
1956 if (projDataNeededVars && !projDataNeededVars->empty()) {
1957 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
1958 << " averages using data variables " << *projDataNeededVars << std::endl ;
1959 }
1960
1961 // Create projection integral
1962 RooArgSet* projectionCompList = nullptr ;
1963
1964 RooArgSet deps;
1965 getObservables(frame->getNormVars(), deps) ;
1966 deps.remove(projectedVars,true,true) ;
1967 if (projDataNeededVars) {
1968 deps.remove(*projDataNeededVars,true,true) ;
1969 }
1970 deps.remove(*plotVar,true,true) ;
1971 deps.add(*plotVar) ;
1972
1973 // Now that we have the final set of dependents, call checkObservables()
1974
1975 // WVE take out conditional observables
1976 if (checkObservables(&deps)) {
1977 coutE(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") error in checkObservables, abort" << std::endl ;
1978 if (projDataNeededVars) delete projDataNeededVars ;
1979 return frame ;
1980 }
1981
1982 RooAbsReal *projection = const_cast<RooAbsReal*>(createPlotProjection(deps, &projectedVars, projectionCompList, o.projectionRangeName));
1983 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot projection object is " << projection->GetName() << std::endl ;
1984 if (dologD(Plotting)) {
1985 projection->printStream(ccoutD(Plotting),0,kVerbose) ;
1986 }
1987
1988 // Always fix RooAddPdf normalizations
1989 RooArgSet fullNormSet(deps) ;
1990 fullNormSet.add(projectedVars) ;
1991 if (projDataNeededVars && !projDataNeededVars->empty()) {
1992 fullNormSet.add(*projDataNeededVars) ;
1993 }
1994
1995 std::unique_ptr<RooArgSet> projectionComponents(projection->getComponents());
1996 for(auto * pdf : dynamic_range_cast<RooAbsPdf*>(*projectionComponents)) {
1997 if (pdf) {
1998 pdf->selectNormalization(&fullNormSet) ;
1999 }
2000 }
2001
2002 // Apply data projection, if requested
2003 if (o.projData && projDataNeededVars && !projDataNeededVars->empty()) {
2004
2005 // If data set contains more rows than needed, make reduced copy first
2006 RooAbsData* projDataSel = const_cast<RooAbsData*>(o.projData);
2007 std::unique_ptr<RooAbsData> projDataSelOwned;
2008
2009 if (projDataNeededVars->size() < o.projData->get()->size()) {
2010
2011 // Determine if there are any slice variables in the projection set
2012 std::unique_ptr<RooArgSet> sliceDataSet{sliceSet.selectCommon(*o.projData->get())};
2013 TString cutString ;
2014 if (!sliceDataSet->empty()) {
2015 bool first(true) ;
2016 for(RooAbsArg * sliceVar : *sliceDataSet) {
2017 if (!first) {
2018 cutString.Append("&&") ;
2019 } else {
2020 first=false ;
2021 }
2022
2023 RooAbsRealLValue* real ;
2025 if ((real = dynamic_cast<RooAbsRealLValue*>(sliceVar))) {
2026 cutString.Append(Form("%s==%f",real->GetName(),real->getVal())) ;
2027 } else if ((cat = dynamic_cast<RooAbsCategoryLValue*>(sliceVar))) {
2028 cutString.Append(Form("%s==%d",cat->GetName(),cat->getCurrentIndex())) ;
2029 }
2030 }
2031 }
2032
2033 if (!cutString.IsNull()) {
2034 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") reducing given projection dataset to entries with " << cutString << std::endl ;
2035 }
2036 projDataSelOwned = std::unique_ptr<RooAbsData>{const_cast<RooAbsData*>(o.projData)->reduce(*projDataNeededVars, cutString.IsNull() ? nullptr : cutString)};
2037 projDataSel = projDataSelOwned.get();
2038 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName()
2039 << ") only the following components of the projection data will be used: " << *projDataNeededVars << std::endl ;
2040 }
2041
2042 // Request binning of unbinned projection dataset that consists exclusively of category observables
2043 if (!o.binProjData && dynamic_cast<RooDataSet*>(projDataSel)!=nullptr) {
2044
2045 // Determine if dataset contains only categories
2046 bool allCat(true) ;
2047 for(RooAbsArg * arg2 : *projDataSel->get()) {
2048 if (!dynamic_cast<RooCategory*>(arg2)) allCat = false ;
2049 }
2050 if (allCat) {
2051 o.binProjData = true ;
2052 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") unbinned projection dataset consist only of discrete variables,"
2053 << " performing projection with binned copy for optimization." << std::endl ;
2054
2055 }
2056 }
2057
2058 // Bin projection dataset if requested
2059 if (o.binProjData) {
2060 projDataSelOwned = std::make_unique<RooDataHist>(std::string(projDataSel->GetName()) + "_binned","Binned projection data",*projDataSel->get(),*projDataSel);
2061 projDataSel = projDataSelOwned.get();
2062 }
2063
2064 // Construct scaled data weighted average
2065 ScaledDataWeightedAverage scaleBind{*projection, *projDataSel, o.scaleFactor, *plotVar};
2066
2067 // Set default range, if not specified
2068 if (o.rangeLo==0 && o.rangeHi==0) {
2069 o.rangeLo = frame->GetXaxis()->GetXmin() ;
2070 o.rangeHi = frame->GetXaxis()->GetXmax() ;
2071 }
2072
2073 // Construct name of curve for data weighed average
2074 std::string curveName(projection->GetName()) ;
2075 curveName.append("_DataAvg[" + projDataSel->get()->contentsString() + "]");
2076 // Append slice set specification if any
2077 if (!sliceSet.empty()) {
2078 curveName.append("_Slice[" + sliceSet.contentsString() + "]");
2079 }
2080 // Append any suffixes imported from RooAbsPdf::plotOn
2081 if (o.curveNameSuffix) {
2082 curveName.append(o.curveNameSuffix) ;
2083 }
2084
2085 // Curve constructor for data weighted average
2087 RooCurve *curve = new RooCurve(projection->GetName(),projection->GetTitle(),scaleBind,
2090
2091 curve->SetName(curveName.c_str()) ;
2092
2093 // Add self to other curve if requested
2094 if (o.addToCurveName) {
2095 RooCurve* otherCurve = static_cast<RooCurve*>(frame->findObject(o.addToCurveName,RooCurve::Class())) ;
2096
2097 // Curve constructor for sum of curves
2098 RooCurve* sumCurve = new RooCurve(projection->GetName(),projection->GetTitle(),*curve,*otherCurve,o.addToWgtSelf,o.addToWgtOther) ;
2099 sumCurve->SetName(Form("%s_PLUS_%s",curve->GetName(),otherCurve->GetName())) ;
2100 delete curve ;
2101 curve = sumCurve ;
2102
2103 }
2104
2105 if (o.curveName) {
2106 curve->SetName(o.curveName) ;
2107 }
2108
2109 // add this new curve to the specified plot frame
2110 frame->addPlotable(curve, o.drawOptions, o.curveInvisible);
2111
2112 } else {
2113
2114 // Set default range, if not specified
2115 if (o.rangeLo==0 && o.rangeHi==0) {
2116 o.rangeLo = frame->GetXaxis()->GetXmin() ;
2117 o.rangeHi = frame->GetXaxis()->GetXmax() ;
2118 }
2119
2120 // Calculate a posteriori range fraction scaling if requested (2nd part of normalization correction for
2121 // result fit on subrange of data)
2122 if (o.postRangeFracScale) {
2123 if (!o.normRangeName) {
2124 o.normRangeName = "plotRange" ;
2125 plotVar->setRange("plotRange",o.rangeLo,o.rangeHi) ;
2126 }
2127
2128 // Evaluate fractional correction integral always on full p.d.f, not component.
2129 GlobalSelectComponentRAII selectCompRAII(true);
2130 std::unique_ptr<RooAbsReal> intFrac{projection->createIntegral(*plotVar,*plotVar,o.normRangeName)};
2131 if(o.stype != RooAbsReal::Raw || this->InheritsFrom(RooAbsPdf::Class())){
2132 // this scaling should only be !=1 when plotting partial ranges
2133 // still, raw means raw
2134 o.scaleFactor /= intFrac->getVal() ;
2135 }
2136 }
2137
2138 // create a new curve of our function using the clone to do the evaluations
2139 // Curve constructor for regular projections
2140
2141 // Set default name of curve
2142 std::string curveName(projection->GetName()) ;
2143 if (!sliceSet.empty()) {
2144 curveName.append("_Slice[" + sliceSet.contentsString() + "]");
2145 }
2146 if (o.curveNameSuffix) {
2147 // Append any suffixes imported from RooAbsPdf::plotOn
2148 curveName.append(o.curveNameSuffix) ;
2149 }
2150
2151 TString opt(o.drawOptions);
2152 if(opt.Contains("P")){
2154 RooHist *graph= new RooHist(*projection,*plotVar,1.,o.scaleFactor,frame->getNormVars(),o.errorFR);
2156
2157 // Override name of curve by user name, if specified
2158 if (o.curveName) {
2159 graph->SetName(o.curveName) ;
2160 }
2161
2162 // add this new curve to the specified plot frame
2164 } else {
2166 RooCurve *curve = new RooCurve(*projection,*plotVar,o.rangeLo,o.rangeHi,frame->GetNbinsX(),
2169 curve->SetName(curveName.c_str()) ;
2170
2171 // Add self to other curve if requested
2172 if (o.addToCurveName) {
2173 RooCurve* otherCurve = static_cast<RooCurve*>(frame->findObject(o.addToCurveName,RooCurve::Class())) ;
2174 RooCurve* sumCurve = new RooCurve(projection->GetName(),projection->GetTitle(),*curve,*otherCurve,o.addToWgtSelf,o.addToWgtOther) ;
2175 sumCurve->SetName(Form("%s_PLUS_%s",curve->GetName(),otherCurve->GetName())) ;
2176 delete curve ;
2177 curve = sumCurve ;
2178 }
2179
2180 // Override name of curve by user name, if specified
2181 if (o.curveName) {
2182 curve->SetName(o.curveName) ;
2183 }
2184
2185 // add this new curve to the specified plot frame
2186 frame->addPlotable(curve, o.drawOptions, o.curveInvisible);
2187 }
2188 }
2189
2190 if (projDataNeededVars) delete projDataNeededVars ;
2191 delete projectionCompList ;
2192 plotVar->setVal(oldPlotVarVal); // reset the plot variable value to not disturb the original state
2193 return frame;
2194}
2195
2196
2197//_____________________________________________________________________________
2198// coverity[PASS_BY_VALUE]
2200
2201{
2202 // Plotting engine for asymmetries. Implements the functionality if plotOn(frame,Asymmetry(...)))
2203 //
2204 // Plot asymmetry of ourselves, defined as
2205 //
2206 // asym = f(asymCat=-1) - f(asymCat=+1) / ( f(asymCat=-1) + f(asymCat=+1) )
2207 //
2208 // on frame. If frame contains a histogram, all dimensions of the plotted
2209 // asymmetry function that occur in the previously plotted dataset are projected via partial integration.
2210 // Otherwise no projections are performed,
2211 //
2212 // The asymmetry function can be multiplied with an optional scale factor. The default projection
2213 // behaviour can be overridden by supplying an optional set of dependents to project.
2214
2215 // Sanity checks
2216 if (plotSanityChecks(frame)) return frame ;
2217
2218 // ProjDataVars is either all projData observables, or the user indicated subset of it
2219 RooArgSet projDataVars ;
2220 if (o.projData) {
2221 if (o.projDataSet) {
2222 std::unique_ptr<RooArgSet> tmp{o.projData->get()->selectCommon(*o.projDataSet)};
2223 projDataVars.add(*tmp) ;
2224 } else {
2225 projDataVars.add(*o.projData->get()) ;
2226 }
2227 }
2228
2229 // Must depend on asymCat
2230 if (!dependsOn(asymCat)) {
2231 coutE(Plotting) << "RooAbsReal::plotAsymOn(" << GetName()
2232 << ") function doesn't depend on asymmetry category " << asymCat.GetName() << std::endl ;
2233 return frame ;
2234 }
2235
2236 // asymCat must be a signCat
2237 if (!asymCat.isSignType()) {
2238 coutE(Plotting) << "RooAbsReal::plotAsymOn(" << GetName()
2239 << ") asymmetry category must have 2 or 3 states with index values -1,0,1" << std::endl ;
2240 return frame ;
2241 }
2242
2243 // Make list of variables to be projected
2244 RooArgSet projectedVars ;
2245 RooArgSet sliceSet ;
2246 if (o.projSet) {
2247 makeProjectionSet(frame->getPlotVar(),o.projSet,projectedVars,false) ;
2248
2249 // Print list of non-projected variables
2250 if (frame->getNormVars()) {
2251 RooArgSet sliceSetTmp;
2252 getObservables(frame->getNormVars(), sliceSetTmp) ;
2253 sliceSetTmp.remove(projectedVars,true,true) ;
2254 sliceSetTmp.remove(*frame->getPlotVar(),true,true) ;
2255
2256 if (o.projData) {
2257 std::unique_ptr<RooArgSet> tmp{projDataVars.selectCommon(*o.projSet)};
2258 sliceSetTmp.remove(*tmp,true,true) ;
2259 }
2260
2261 if (!sliceSetTmp.empty()) {
2262 coutI(Plotting) << "RooAbsReal::plotAsymOn(" << GetName() << ") plot on "
2263 << frame->getPlotVar()->GetName() << " represents a slice in " << sliceSetTmp << std::endl ;
2264 }
2265 sliceSet.add(sliceSetTmp) ;
2266 }
2267 } else {
2268 makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,true) ;
2269 }
2270
2271
2272 // Take out data-projected dependens from projectedVars
2273 RooArgSet* projDataNeededVars = nullptr ;
2274 if (o.projData) {
2275 projDataNeededVars = projectedVars.selectCommon(projDataVars);
2276 projectedVars.remove(projDataVars,true,true) ;
2277 }
2278
2279 // Take out plotted asymmetry from projection
2280 if (projectedVars.find(asymCat.GetName())) {
2281 projectedVars.remove(*projectedVars.find(asymCat.GetName())) ;
2282 }
2283
2284 // Clone the plot variable
2285 RooAbsReal* realVar = static_cast<RooRealVar*>(frame->getPlotVar()) ;
2286 RooRealVar* plotVar = static_cast<RooRealVar*>(realVar->Clone()) ;
2287
2288 // Inform user about projections
2289 if (!projectedVars.empty()) {
2290 coutI(Plotting) << "RooAbsReal::plotAsymOn(" << GetName() << ") plot on " << plotVar->GetName()
2291 << " projects variables " << projectedVars << std::endl ;
2292 }
2293 if (projDataNeededVars && !projDataNeededVars->empty()) {
2294 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
2295 << " averages using data variables "<< *projDataNeededVars << std::endl ;
2296 }
2297
2298
2299 // Customize two copies of projection with fixed negative and positive asymmetry
2300 std::unique_ptr<RooAbsCategoryLValue> asymPos{static_cast<RooAbsCategoryLValue*>(asymCat.Clone("asym_pos"))};
2301 std::unique_ptr<RooAbsCategoryLValue> asymNeg{static_cast<RooAbsCategoryLValue*>(asymCat.Clone("asym_neg"))};
2302 asymPos->setIndex(1) ;
2303 asymNeg->setIndex(-1) ;
2304 RooCustomizer custPos{*this,"pos"};
2305 RooCustomizer custNeg{*this,"neg"};
2306 //custPos->setOwning(true) ;
2307 //custNeg->setOwning(true) ;
2308 custPos.replaceArg(asymCat,*asymPos) ;
2309 custNeg.replaceArg(asymCat,*asymNeg) ;
2310 std::unique_ptr<RooAbsReal> funcPos{static_cast<RooAbsReal*>(custPos.build())};
2311 std::unique_ptr<RooAbsReal> funcNeg{static_cast<RooAbsReal*>(custNeg.build())};
2312
2313 // Create projection integral
2314 RooArgSet *posProjCompList;
2315 RooArgSet *negProjCompList;
2316
2317 // Add projDataVars to normalized dependents of projection
2318 // This is needed only for asymmetries (why?)
2319 RooArgSet depPos(*plotVar,*asymPos) ;
2320 RooArgSet depNeg(*plotVar,*asymNeg) ;
2321 depPos.add(projDataVars) ;
2322 depNeg.add(projDataVars) ;
2323
2324 const RooAbsReal *posProj = funcPos->createPlotProjection(depPos, &projectedVars, posProjCompList, o.projectionRangeName) ;
2325 const RooAbsReal *negProj = funcNeg->createPlotProjection(depNeg, &projectedVars, negProjCompList, o.projectionRangeName) ;
2326 if (!posProj || !negProj) {
2327 coutE(Plotting) << "RooAbsReal::plotAsymOn(" << GetName() << ") Unable to create projections, abort" << std::endl ;
2328 return frame ;
2329 }
2330
2331 // Create a RooFormulaVar representing the asymmetry
2332 TString asymName(GetName()) ;
2333 asymName.Append("_Asym[") ;
2334 asymName.Append(asymCat.GetName()) ;
2335 asymName.Append("]") ;
2336 TString asymTitle(asymCat.GetName()) ;
2337 asymTitle.Append(" Asymmetry of ") ;
2338 asymTitle.Append(GetTitle()) ;
2339 RooFormulaVar funcAsym{asymName,asymTitle,"(@0-@1)/(@0+@1)",RooArgSet(*posProj,*negProj)};
2340
2341 if (o.projData) {
2342
2343 // If data set contains more rows than needed, make reduced copy first
2344 RooAbsData* projDataSel = const_cast<RooAbsData*>(o.projData);
2345 std::unique_ptr<RooAbsData> projDataSelOwned;
2346 if (projDataNeededVars && projDataNeededVars->size() < o.projData->get()->size()) {
2347
2348 // Determine if there are any slice variables in the projection set
2349 RooArgSet sliceDataSet;
2350 sliceSet.selectCommon(*o.projData->get(), sliceDataSet);
2351 TString cutString ;
2352 if (!sliceDataSet.empty()) {
2353 bool first(true) ;
2354 for(RooAbsArg * sliceVar : sliceDataSet) {
2355 if (!first) {
2356 cutString.Append("&&") ;
2357 } else {
2358 first=false ;
2359 }
2360
2361 RooAbsRealLValue* real ;
2363 if ((real = dynamic_cast<RooAbsRealLValue*>(sliceVar))) {
2364 cutString.Append(Form("%s==%f",real->GetName(),real->getVal())) ;
2365 } else if ((cat = dynamic_cast<RooAbsCategoryLValue*>(sliceVar))) {
2366 cutString.Append(Form("%s==%d",cat->GetName(),cat->getCurrentIndex())) ;
2367 }
2368 }
2369 }
2370
2371 if (!cutString.IsNull()) {
2372 coutI(Plotting) << "RooAbsReal::plotAsymOn(" << GetName()
2373 << ") reducing given projection dataset to entries with " << cutString << std::endl ;
2374 }
2375 projDataSelOwned = std::unique_ptr<RooAbsData>{const_cast<RooAbsData*>(o.projData)->reduce(*projDataNeededVars,cutString.IsNull() ? nullptr : cutString)};
2376 projDataSel = projDataSelOwned.get();
2377 coutI(Plotting) << "RooAbsReal::plotAsymOn(" << GetName()
2378 << ") only the following components of the projection data will be used: " << *projDataNeededVars << std::endl ;
2379 }
2380
2381
2382 // Construct scaled data weighted average
2383 ScaledDataWeightedAverage scaleBind{funcAsym, *projDataSel, o.scaleFactor, *plotVar};
2384
2385 // Set default range, if not specified
2386 if (o.rangeLo==0 && o.rangeHi==0) {
2387 o.rangeLo = frame->GetXaxis()->GetXmin() ;
2388 o.rangeHi = frame->GetXaxis()->GetXmax() ;
2389 }
2390
2391 // Construct name of curve for data weighed average
2392 TString curveName(funcAsym.GetName()) ;
2393 curveName.Append(Form("_DataAvg[%s]",projDataSel->get()->contentsString().c_str())) ;
2394 // Append slice set specification if any
2395 if (!sliceSet.empty()) {
2396 curveName.Append(Form("_Slice[%s]",sliceSet.contentsString().c_str())) ;
2397 }
2398 // Append any suffixes imported from RooAbsPdf::plotOn
2399 if (o.curveNameSuffix) {
2400 curveName.Append(o.curveNameSuffix) ;
2401 }
2402
2403
2405 RooCurve *curve = new RooCurve(funcAsym.GetName(),funcAsym.GetTitle(),scaleBind,
2406 o.rangeLo,o.rangeHi,frame->GetNbinsX(),o.precision,o.precision,false,o.wmode,o.numee,o.doeeval,o.eeval) ;
2408
2409 dynamic_cast<TAttLine*>(curve)->SetLineColor(2) ;
2410 // add this new curve to the specified plot frame
2411 frame->addPlotable(curve, o.drawOptions);
2412
2413 ccoutW(Eval) << std::endl ;
2414 } else {
2415
2416 // Set default range, if not specified
2417 if (o.rangeLo==0 && o.rangeHi==0) {
2418 o.rangeLo = frame->GetXaxis()->GetXmin() ;
2419 o.rangeHi = frame->GetXaxis()->GetXmax() ;
2420 }
2421
2423 RooCurve* curve= new RooCurve(funcAsym,*plotVar,o.rangeLo,o.rangeHi,frame->GetNbinsX(),
2424 o.scaleFactor,nullptr,o.precision,o.precision,false,o.wmode,o.numee,o.doeeval,o.eeval);
2426
2427 dynamic_cast<TAttLine*>(curve)->SetLineColor(2) ;
2428
2429
2430 // Set default name of curve
2431 TString curveName(funcAsym.GetName()) ;
2432 if (!sliceSet.empty()) {
2433 curveName.Append(Form("_Slice[%s]",sliceSet.contentsString().c_str())) ;
2434 }
2435 if (o.curveNameSuffix) {
2436 // Append any suffixes imported from RooAbsPdf::plotOn
2437 curveName.Append(o.curveNameSuffix) ;
2438 }
2439 curve->SetName(curveName.Data()) ;
2440
2441 // add this new curve to the specified plot frame
2442 frame->addPlotable(curve, o.drawOptions);
2443
2444 }
2445
2446 // Cleanup
2447 delete posProjCompList ;
2448 delete negProjCompList ;
2449
2450 delete plotVar ;
2451
2452 return frame;
2453}
2454
2455
2456
2457////////////////////////////////////////////////////////////////////////////////
2458/// \brief Propagates parameter uncertainties to an uncertainty estimate for this RooAbsReal.
2459///
2460/// Estimates the uncertainty \f$\sigma_f(x;\theta)\f$ on a function \f$f(x;\theta)\f$ represented by this RooAbsReal.
2461/// Here, \f$\theta\f$ is a vector of parameters with uncertainties \f$\sigma_\theta\f$, and \f$x\f$ are usually observables.
2462/// The uncertainty is estimated by *linearly* propagating the parameter uncertainties using the correlation matrix from a fit result.
2463///
2464/// The square of the uncertainty on \f$f(x;\theta)\f$ is calculated as follows:
2465/// \f[
2466/// \sigma_f(x)^2 = \Delta f_i(x) \cdot \mathrm{Corr}_{i, j} \cdot \Delta f_j(x),
2467/// \f]
2468/// where \f$ \Delta f_i(x) = \frac{1}{2} \left(f(x;\theta_i + \sigma_{\theta_i}) - f(x; \theta_i - \sigma_{\theta_i}) \right) \f$
2469/// is the vector of function variations when changing the parameters one at a time, and
2470/// \f$ \mathrm{Corr}_{i,j} = \left(\sigma_{\theta_i} \sigma_{\theta_j}\right)^{-1} \cdot \mathrm{Cov}_{i,j} \f$ is the correlation matrix from the fit result.
2471
2472double RooAbsReal::getPropagatedError(const RooFitResult &fr, const RooArgSet &nset) const
2473{
2474 // Calling getParameters() might be costly, but necessary to get the right
2475 // parameters in the RooAbsReal. The RooFitResult only stores snapshots.
2476 RooArgSet allParamsInAbsReal;
2477 getParameters(&nset, allParamsInAbsReal);
2478
2479 RooArgList paramList;
2480 for(auto * rrvFitRes : static_range_cast<RooRealVar*>(fr.floatParsFinal())) {
2481
2482 auto rrvInAbsReal = static_cast<RooRealVar const*>(allParamsInAbsReal.find(*rrvFitRes));
2483
2484 // If this RooAbsReal is a RooRealVar in the fit result, we don't need to
2485 // propagate anything and can just return the error in the fit result
2486 if(rrvFitRes->namePtr() == namePtr()) return rrvFitRes->getError();
2487
2488 // Strip out parameters with zero error
2489 if (rrvFitRes->getError() <= std::abs(rrvFitRes->getVal()) * std::numeric_limits<double>::epsilon()) continue;
2490
2491 // Ignore parameters in the fit result that this RooAbsReal doesn't depend on
2492 if(!rrvInAbsReal) continue;
2493
2494 // Checking for float equality is a bad. We check if the values are
2495 // negligibly far away from each other, relative to the uncertainty.
2496 if(std::abs(rrvInAbsReal->getVal() - rrvFitRes->getVal()) > 0.01 * rrvFitRes->getError()) {
2497 std::stringstream errMsg;
2498 errMsg << "RooAbsReal::getPropagatedError(): the parameters of the RooAbsReal don't have"
2499 << " the same values as in the fit result! The logic of getPropagatedError is broken in this case.";
2500
2501 throw std::runtime_error(errMsg.str());
2502 }
2503
2504 paramList.add(*rrvInAbsReal);
2505 }
2506
2507 std::vector<double> plusVar;
2508 std::vector<double> minusVar;
2509 plusVar.reserve(paramList.size());
2510 minusVar.reserve(paramList.size());
2511
2512 // Create std::vector of plus,minus variations for each parameter
2513 TMatrixDSym V(paramList.size() == fr.floatParsFinal().size() ?
2514 fr.covarianceMatrix() :
2515 fr.reducedCovarianceMatrix(paramList)) ;
2516
2517 for (std::size_t ivar=0 ; ivar<paramList.size() ; ivar++) {
2518
2519 auto& rrv = static_cast<RooRealVar&>(paramList[ivar]);
2520
2521 double cenVal = rrv.getVal() ;
2522 double errVal = sqrt(V(ivar,ivar)) ;
2523
2524 // Make Plus variation
2525 rrv.setVal(cenVal+errVal) ;
2526 plusVar.push_back(getVal(nset)) ;
2527
2528 // Make Minus variation
2529 rrv.setVal(cenVal-errVal) ;
2530 minusVar.push_back(getVal(nset)) ;
2531
2532 rrv.setVal(cenVal) ;
2533 }
2534
2535 // Re-evaluate this RooAbsReal with the central parameters just to be
2536 // extra-safe that a call to `getPropagatedError()` doesn't change any state.
2537 // It should not be necessary because thanks to the dirty flag propagation
2538 // the RooAbsReal is re-evaluated anyway the next time getVal() is called.
2539 // Still there are imaginable corner cases where it would not be triggered,
2540 // for example if the user changes the RooFit operation more after the error
2541 // propagation.
2542 getVal(nset);
2543
2544 TMatrixDSym C(paramList.size()) ;
2545 std::vector<double> errVec(paramList.size()) ;
2546 for (std::size_t i=0 ; i<paramList.size() ; i++) {
2547 errVec[i] = std::sqrt(V(i,i)) ;
2548 for (std::size_t j=i ; j<paramList.size() ; j++) {
2549 C(i,j) = V(i,j) / std::sqrt(V(i,i)*V(j,j));
2550 C(j,i) = C(i,j) ;
2551 }
2552 }
2553
2554 // Make std::vector of variations
2555 TVectorD F(plusVar.size()) ;
2556 for (std::size_t j=0 ; j<plusVar.size() ; j++) {
2557 F[j] = (plusVar[j]-minusVar[j]) * 0.5;
2558 }
2559
2560 // Calculate error in linear approximation from variations and correlation coefficient
2561 double sum = F*(C*F) ;
2562
2563 return sqrt(sum) ;
2564}
2565
2566
2567
2568////////////////////////////////////////////////////////////////////////////////
2569/// Plot function or PDF on frame with support for visualization of the uncertainty encoded in the given fit result fr.
2570/// \param[in] frame RooPlot to plot on
2571/// \param[in] fr The RooFitResult, where errors can be extracted
2572/// \param[in] Z The desired significance (width) of the error band
2573/// \param[in] params If non-zero, consider only the subset of the parameters in fr for the error evaluation
2574/// \param[in] argList Optional `RooCmdArg` that can be applied to a regular plotOn() operation
2575/// \param[in] linMethod By default (linMethod=true), a linearized error is shown.
2576/// \return The RooPlot the band was plotted on (for chaining of plotting commands).
2577///
2578/// The linearized error is calculated as follows:
2579/// \f[
2580/// \mathrm{error}(x) = Z * F_a(x) * \mathrm{Corr}(a,a') * F_{a'}^\mathrm{T}(x),
2581/// \f]
2582///
2583/// where
2584/// \f[
2585/// F_a(x) = \frac{ f(x,a+\mathrm{d}a) - f(x,a-\mathrm{d}a) }{2},
2586/// \f]
2587/// with \f$ f(x) \f$ the plotted curve and \f$ \mathrm{d}a \f$ taken from the fit result, and
2588/// \f$ \mathrm{Corr}(a,a') \f$ = the correlation matrix from the fit result, and \f$ Z \f$ = requested signifance (\f$ Z \sigma \f$ band)
2589///
2590/// The linear method is fast (required 2*N evaluations of the curve, where N is the number of parameters), but may
2591/// not be accurate in the presence of strong correlations (~>0.9) and at Z>2 due to linear and Gaussian approximations made
2592///
2593/// Alternatively, a more robust error is calculated using a sampling method. In this method a number of curves
2594/// is calculated with variations of the parameter values, as drawn from a multi-variate Gaussian p.d.f. that is constructed
2595/// from the fit results covariance matrix. The error(x) is determined by calculating a central interval that capture N% of the variations
2596/// for each value of x, where N% is controlled by Z (i.e. Z=1 gives N=68%). The number of sampling curves is chosen to be such
2597/// that at least 30 curves are expected to be outside the N% interval, and is minimally 100 (e.g. Z=1->Ncurve=100, Z=2->Ncurve=659, Z=3->Ncurve=11111)
2598/// Intervals from the sampling method can be asymmetric, and may perform better in the presence of strong correlations, but may take (much)
2599/// longer to calculate.
2600
2601RooPlot* RooAbsReal::plotOnWithErrorBand(RooPlot* frame,const RooFitResult& fr, double Z,const RooArgSet* params, const RooLinkedList& argList, bool linMethod) const
2602{
2603 RooLinkedList plotArgListTmp(argList) ;
2604 RooCmdConfig::stripCmdList(plotArgListTmp,"VisualizeError,MoveToBack") ;
2605
2606 // Strip any 'internal normalization' arguments from list
2607 RooLinkedList plotArgList ;
2608 for (auto * cmd : static_range_cast<RooCmdArg*>(plotArgListTmp)) {
2609 if (std::string("Normalization")==cmd->GetName()) {
2610 if (((RooCmdArg*)cmd)->getInt(1)!=0) {
2611 } else {
2612 plotArgList.Add(cmd) ;
2613 }
2614 } else {
2615 plotArgList.Add(cmd) ;
2616 }
2617 }
2618
2619 // Function to plot a single curve, creating a copy of the plotArgList to
2620 // pass as plot command arguments. The "FillColor" command is removed because
2621 // it has no effect on plotting single curves and would cause a warning.
2622 auto plotFunc = [&](RooAbsReal const& absReal) {
2623 RooLinkedList tmp(plotArgList) ;
2624 RooCmdConfig::stripCmdList(tmp, "FillColor");
2625 absReal.plotOn(frame, tmp);
2626 };
2627
2628 // Generate central value curve
2629 plotFunc(*this);
2630 RooCurve* cenCurve = frame->getCurve() ;
2631 if(!cenCurve){
2632 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOnWithErrorBand: no curve for central value available" << std::endl;
2633 return frame;
2634 }
2635 frame->remove(nullptr,false) ;
2636
2637 RooCurve* band(nullptr) ;
2638 if (!linMethod) {
2639
2640 // *** Interval method ***
2641 //
2642 // Make N variations of parameters samples from V and visualize N% central interval where N% is defined from Z
2643
2644 // Clone self for internal use
2645 RooAbsReal* cloneFunc = static_cast<RooAbsReal*>(cloneTree()) ;
2646 RooArgSet cloneParams;
2647 cloneFunc->getObservables(&fr.floatParsFinal(), cloneParams) ;
2648 RooArgSet errorParams{cloneParams};
2649 if(params) {
2650 // clear and fill errorParams only with parameters that both in params and cloneParams
2651 cloneParams.selectCommon(*params, errorParams);
2652 }
2653
2654 // Generate 100 random parameter points distributed according to fit result covariance matrix
2655 RooAbsPdf* paramPdf = fr.createHessePdf(errorParams) ;
2656 Int_t n = Int_t(100./TMath::Erfc(Z/sqrt(2.))) ;
2657 if (n<100) n=100 ;
2658
2659 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") INFO: visualizing " << Z << "-sigma uncertainties in parameters "
2660 << errorParams << " from fit result " << fr.GetName() << " using " << n << " samplings." << std::endl ;
2661
2662 // Generate variation curves with above set of parameter values
2663 double ymin = frame->GetMinimum() ;
2664 double ymax = frame->GetMaximum() ;
2665 std::unique_ptr<RooDataSet> generatedData{paramPdf->generate(errorParams,n)};
2666 std::vector<RooCurve*> cvec ;
2667 for (int i=0 ; i<generatedData->numEntries() ; i++) {
2668 cloneParams.assign(*generatedData->get(i)) ;
2669 plotFunc(*cloneFunc);
2670 cvec.push_back(frame->getCurve()) ;
2671 frame->remove(nullptr,false) ;
2672 }
2673 frame->SetMinimum(ymin) ;
2674 frame->SetMaximum(ymax) ;
2675
2676
2677 // Generate upper and lower curve points from 68% interval around each point of central curve
2678 band = cenCurve->makeErrorBand(cvec,Z) ;
2679
2680 // Cleanup
2681 delete paramPdf ;
2682 delete cloneFunc ;
2683 for (std::vector<RooCurve*>::iterator i=cvec.begin() ; i!=cvec.end() ; ++i) {
2684 delete (*i) ;
2685 }
2686
2687 } else {
2688
2689 // *** Linear Method ***
2690 //
2691 // Make a one-sigma up- and down fluctation for each parameter and visualize
2692 // a from a linearized calculation as follows
2693 //
2694 // error(x) = F(a) C_aa' F(a')
2695 //
2696 // Where F(a) = (f(x,a+da) - f(x,a-da))/2
2697 // and C_aa' is the correlation matrix
2698
2699 // Strip out parameters with zero error
2700 RooArgList fpf_stripped;
2701 for (auto const* frv : static_range_cast<RooRealVar*>(fr.floatParsFinal())) {
2702 if (frv->getError() > frv->getVal() * std::numeric_limits<double>::epsilon()) {
2703 fpf_stripped.add(*frv);
2704 }
2705 }
2706
2707 // Clone self for internal use
2708 RooAbsReal* cloneFunc = static_cast<RooAbsReal*>(cloneTree()) ;
2709 RooArgSet cloneParams;
2710 cloneFunc->getObservables(&fpf_stripped, cloneParams) ;
2711 RooArgSet errorParams{cloneParams};
2712 if(params) {
2713 // clear and fill errorParams only with parameters that both in params and cloneParams
2714 cloneParams.selectCommon(*params, errorParams);
2715 }
2716
2717
2718 // Make list of parameter instances of cloneFunc in order of error matrix
2719 RooArgList paramList ;
2720 const RooArgList& fpf = fr.floatParsFinal() ;
2721 std::vector<int> fpf_idx ;
2722 for (std::size_t i=0 ; i<fpf.size() ; i++) {
2723 RooAbsArg* par = errorParams.find(fpf[i].GetName()) ;
2724 if (par) {
2725 paramList.add(*par) ;
2726 fpf_idx.push_back(i) ;
2727 }
2728 }
2729
2730 std::vector<RooCurve *> plusVar;
2731 std::vector<RooCurve *> minusVar;
2732
2733 // Create std::vector of plus,minus variations for each parameter
2734
2735 TMatrixDSym V(paramList.size() == fr.floatParsFinal().size() ?
2736 fr.covarianceMatrix():
2737 fr.reducedCovarianceMatrix(paramList)) ;
2738
2739
2740 for (std::size_t ivar=0 ; ivar<paramList.size() ; ivar++) {
2741
2742 RooRealVar& rrv = static_cast<RooRealVar&>(fpf[fpf_idx[ivar]]) ;
2743
2744 double cenVal = rrv.getVal() ;
2745 double errVal = sqrt(V(ivar,ivar)) ;
2746
2747 // Make Plus variation
2748 (static_cast<RooRealVar*>(paramList.at(ivar)))->setVal(cenVal+Z*errVal) ;
2749
2750
2751 plotFunc(*cloneFunc);
2752 plusVar.push_back(frame->getCurve()) ;
2753 frame->remove(nullptr,false) ;
2754
2755
2756 // Make Minus variation
2757 (static_cast<RooRealVar*>(paramList.at(ivar)))->setVal(cenVal-Z*errVal) ;
2758 plotFunc(*cloneFunc);
2759 minusVar.push_back(frame->getCurve()) ;
2760 frame->remove(nullptr,false) ;
2761
2762 (static_cast<RooRealVar*>(paramList.at(ivar)))->setVal(cenVal) ;
2763 }
2764
2765 TMatrixDSym C(paramList.size()) ;
2766 std::vector<double> errVec(paramList.size()) ;
2767 for (std::size_t i=0 ; i<paramList.size() ; i++) {
2768 errVec[i] = sqrt(V(i,i)) ;
2769 for (std::size_t j=i ; j<paramList.size() ; j++) {
2770 C(i,j) = V(i,j)/sqrt(V(i,i)*V(j,j)) ;
2771 C(j,i) = C(i,j) ;
2772 }
2773 }
2774
2775 band = cenCurve->makeErrorBand(plusVar,minusVar,C,Z) ;
2776
2777
2778 // Cleanup
2779 delete cloneFunc ;
2780 for (std::vector<RooCurve*>::iterator i=plusVar.begin() ; i!=plusVar.end() ; ++i) {
2781 delete (*i) ;
2782 }
2783 for (std::vector<RooCurve*>::iterator i=minusVar.begin() ; i!=minusVar.end() ; ++i) {
2784 delete (*i) ;
2785 }
2786
2787 }
2788
2789 delete cenCurve ;
2790 if (!band) return frame ;
2791
2792 // Define configuration for this method
2793 RooCmdConfig pc("RooAbsPdf::plotOn(" + std::string(GetName()) + ")");
2794 pc.defineString("drawOption","DrawOption",0,"F") ;
2795 pc.defineString("curveNameSuffix","CurveNameSuffix",0,"") ;
2796 pc.defineInt("lineColor","LineColor",0,-999) ;
2797 pc.defineInt("lineStyle","LineStyle",0,-999) ;
2798 pc.defineInt("lineWidth","LineWidth",0,-999) ;
2799 pc.defineInt("markerColor","MarkerColor",0,-999) ;
2800 pc.defineInt("markerStyle","MarkerStyle",0,-999) ;
2801 pc.defineDouble("markerSize","MarkerSize",0,-999) ;
2802 pc.defineInt("fillColor","FillColor",0,-999) ;
2803 pc.defineInt("fillStyle","FillStyle",0,-999) ;
2804 pc.defineString("curveName","Name",0,"") ;
2805 pc.defineInt("curveInvisible","Invisible",0,0) ;
2806 pc.defineInt("moveToBack","MoveToBack",0,0) ;
2807 pc.allowUndefined() ;
2808
2809 // Process & check varargs
2810 pc.process(argList) ;
2811 if (!pc.ok(true)) {
2812 return frame ;
2813 }
2814
2815 // Insert error band in plot frame
2816 frame->addPlotable(band,pc.getString("drawOption"),pc.getInt("curveInvisible")) ;
2817
2818 // Optionally adjust line/fill attributes
2819 Int_t lineColor = pc.getInt("lineColor") ;
2820 Int_t lineStyle = pc.getInt("lineStyle") ;
2821 Int_t lineWidth = pc.getInt("lineWidth") ;
2822 Int_t markerColor = pc.getInt("markerColor") ;
2823 Int_t markerStyle = pc.getInt("markerStyle") ;
2824 Size_t markerSize = pc.getDouble("markerSize") ;
2825 Int_t fillColor = pc.getInt("fillColor") ;
2826 Int_t fillStyle = pc.getInt("fillStyle") ;
2827 if (lineColor!=-999) frame->getAttLine()->SetLineColor(lineColor) ;
2828 if (lineStyle!=-999) frame->getAttLine()->SetLineStyle(lineStyle) ;
2829 if (lineWidth!=-999) frame->getAttLine()->SetLineWidth(lineWidth) ;
2830 if (fillColor!=-999) frame->getAttFill()->SetFillColor(fillColor) ;
2831 if (fillStyle!=-999) frame->getAttFill()->SetFillStyle(fillStyle) ;
2832 if (markerColor!=-999) frame->getAttMarker()->SetMarkerColor(markerColor) ;
2833 if (markerStyle!=-999) frame->getAttMarker()->SetMarkerStyle(markerStyle) ;
2834 if (markerSize!=-999) frame->getAttMarker()->SetMarkerSize(markerSize) ;
2835
2836 // Adjust name if requested
2837 if (pc.getString("curveName",nullptr,true)) {
2838 band->SetName(pc.getString("curveName",nullptr,true)) ;
2839 } else if (pc.getString("curveNameSuffix",nullptr,true)) {
2840 TString name(band->GetName()) ;
2841 name.Append(pc.getString("curveNameSuffix",nullptr,true)) ;
2842 band->SetName(name.Data()) ;
2843 }
2844
2845 // Move last inserted object to back to drawing stack if requested
2846 if (pc.getInt("moveToBack") && frame->numItems()>1) {
2847 frame->drawBefore(frame->getObject(0)->GetName(), frame->getCurve()->GetName());
2848 }
2849
2850
2851 return frame ;
2852}
2853
2854
2855
2856
2857////////////////////////////////////////////////////////////////////////////////
2858/// Utility function for plotOn(), perform general sanity check on frame to ensure safe plotting operations
2859
2861{
2862 // check that we are passed a valid plot frame to use
2863 if(nullptr == frame) {
2864 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: frame is null" << std::endl;
2865 return true;
2866 }
2867
2868 // check that this frame knows what variable to plot
2869 RooAbsReal* var = frame->getPlotVar() ;
2870 if(!var) {
2871 coutE(Plotting) << ClassName() << "::" << GetName()
2872 << ":plotOn: frame does not specify a plot variable" << std::endl;
2873 return true;
2874 }
2875
2876 // check that the plot variable is not derived
2877 if(!dynamic_cast<RooAbsRealLValue*>(var)) {
2878 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: cannot plot variable \""
2879 << var->GetName() << "\" of type " << var->ClassName() << std::endl;
2880 return true;
2881 }
2882
2883 // check if we actually depend on the plot variable
2884 if(!this->dependsOn(*var)) {
2885 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: WARNING: variable is not an explicit dependent: "
2886 << var->GetName() << std::endl;
2887 }
2888
2889 return false ;
2890}
2891
2892
2893
2894
2895////////////////////////////////////////////////////////////////////////////////
2896/// Utility function for plotOn() that constructs the set of
2897/// observables to project when plotting ourselves as function of
2898/// 'plotVar'. 'allVars' is the list of variables that must be
2899/// projected, but may contain variables that we do not depend on. If
2900/// 'silent' is cleared, warnings about inconsistent input parameters
2901/// will be printed.
2902
2903void RooAbsReal::makeProjectionSet(const RooAbsArg* plotVar, const RooArgSet* allVars,
2904 RooArgSet& projectedVars, bool silent) const
2905{
2906 cxcoutD(Plotting) << "RooAbsReal::makeProjectionSet(" << GetName() << ") plotVar = " << plotVar->GetName()
2907 << " allVars = " << (allVars?(*allVars):RooArgSet()) << std::endl ;
2908
2909 projectedVars.removeAll() ;
2910 if (!allVars) return ;
2911
2912 // Start out with suggested list of variables
2913 projectedVars.add(*allVars) ;
2914
2915 // Take out plot variable
2916 RooAbsArg *found= projectedVars.find(plotVar->GetName());
2917 if(found) {
2918 projectedVars.remove(*found);
2919
2920 // Take out eventual servers of plotVar
2921 std::unique_ptr<RooArgSet> plotServers{plotVar->getObservables(&projectedVars)};
2922 for(RooAbsArg * ps : *plotServers) {
2923 RooAbsArg* tmp = projectedVars.find(ps->GetName()) ;
2924 if (tmp) {
2925 cxcoutD(Plotting) << "RooAbsReal::makeProjectionSet(" << GetName() << ") removing " << tmp->GetName()
2926 << " from projection set because it a server of " << plotVar->GetName() << std::endl ;
2927 projectedVars.remove(*tmp) ;
2928 }
2929 }
2930
2931 if (!silent) {
2932 coutW(Plotting) << "RooAbsReal::plotOn(" << GetName()
2933 << ") WARNING: cannot project out frame variable ("
2934 << found->GetName() << "), ignoring" << std::endl ;
2935 }
2936 }
2937
2938 // Take out all non-dependents of function
2939 for(RooAbsArg * arg : *allVars) {
2940 if (!dependsOnValue(*arg)) {
2941 projectedVars.remove(*arg,true) ;
2942
2943 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName()
2944 << ") function doesn't depend on projection variable "
2945 << arg->GetName() << ", ignoring" << std::endl ;
2946 }
2947 }
2948}
2949
2950
2951
2952
2953////////////////////////////////////////////////////////////////////////////////
2954/// If true, the current pdf is a selected component (for use in plotting)
2955
2957{
2958 return _selectComp || _globalSelectComp ;
2959}
2960
2961
2962
2963////////////////////////////////////////////////////////////////////////////////
2964/// Global switch controlling the activation of the selectComp() functionality
2965
2967{
2968 _globalSelectComp = flag ;
2969}
2970
2971
2972
2973
2974////////////////////////////////////////////////////////////////////////////////
2975/// Create an interface adaptor f(vars) that binds us to the specified variables
2976/// (in arbitrary order). For example, calling bindVars({x1,x3}) on an object
2977/// F(x1,x2,x3,x4) returns an object f(x1,x3) that is evaluated using the
2978/// current values of x2 and x4. The caller takes ownership of the returned adaptor.
2979
2980RooFit::OwningPtr<RooAbsFunc> RooAbsReal::bindVars(const RooArgSet &vars, const RooArgSet* nset, bool clipInvalid) const
2981{
2982 auto binding = std::make_unique<RooRealBinding>(*this,vars,nset,clipInvalid);
2983 if(!binding->isValid()) {
2984 coutE(InputArguments) << ClassName() << "::" << GetName() << ":bindVars: cannot bind to " << vars << std::endl ;
2985 return nullptr;
2986 }
2987 return RooFit::makeOwningPtr(std::unique_ptr<RooAbsFunc>{std::move(binding)});
2988}
2989
2990
2991
2992////////////////////////////////////////////////////////////////////////////////
2993/// Copy the cached value of another RooAbsArg to our cache.
2994/// Warning: This function just copies the cached values of source,
2995/// it is the callers responsibility to make sure the cache is clean.
2996
2997void RooAbsReal::copyCache(const RooAbsArg* source, bool /*valueOnly*/, bool setValDirty)
2998{
2999 auto other = static_cast<const RooAbsReal*>(source);
3000 assert(dynamic_cast<const RooAbsReal*>(source));
3001
3002 _value = other->_treeReadBuffer ? other->_treeReadBuffer->operator double() : other->_value;
3003
3004 if (setValDirty) {
3005 setValueDirty() ;
3006 }
3007}
3008
3009
3010////////////////////////////////////////////////////////////////////////////////
3011
3013{
3014 vstore.addReal(this)->setBuffer(this,&_value);
3015}
3016
3017
3018////////////////////////////////////////////////////////////////////////////////
3019/// Attach object to a branch of given TTree. By default it will
3020/// register the internal value cache RooAbsReal::_value as branch
3021/// buffer for a double tree branch with the same name as this
3022/// object. If no double branch is found with the name of this
3023/// object, this method looks for a Float_t Int_t, UChar_t and UInt_t, etc
3024/// branch. If any of these are found, a TreeReadBuffer
3025/// that branch is created, and saved in _treeReadBuffer.
3026/// TreeReadBuffer::operator double() can be used to convert the values.
3027/// This is used by copyCache().
3029{
3030 // First determine if branch is taken
3031 TString cleanName(cleanBranchName()) ;
3032 TBranch* branch = t.GetBranch(cleanName) ;
3033 if (branch) {
3034
3035 // Determine if existing branch is Float_t or double
3036 TLeaf* leaf = static_cast<TLeaf*>(branch->GetListOfLeaves()->At(0)) ;
3037
3038 // Check that leaf is _not_ an array
3039 Int_t dummy ;
3040 TLeaf* counterLeaf = leaf->GetLeafCounter(dummy) ;
3041 if (counterLeaf) {
3042 coutE(Eval) << "RooAbsReal::attachToTree(" << GetName() << ") ERROR: TTree branch " << GetName()
3043 << " is an array and cannot be attached to a RooAbsReal" << std::endl ;
3044 return ;
3045 }
3046
3047 TString typeName(leaf->GetTypeName()) ;
3048
3049
3050 // For different type names, store three items:
3051 // first: A tag attached to this instance. Not used inside RooFit, any more, but users might rely on it.
3052 // second: A function to attach
3053 std::map<std::string, std::pair<std::string, std::function<std::unique_ptr<TreeReadBuffer>()>>> typeMap {
3054 {"Float_t", {"FLOAT_TREE_BRANCH", [&](){ return createTreeReadBuffer<Float_t >(cleanName, t); }}},
3055 {"Int_t", {"INTEGER_TREE_BRANCH", [&](){ return createTreeReadBuffer<Int_t >(cleanName, t); }}},
3056 {"UChar_t", {"BYTE_TREE_BRANCH", [&](){ return createTreeReadBuffer<UChar_t >(cleanName, t); }}},
3057 {"Bool_t", {"BOOL_TREE_BRANCH", [&](){ return createTreeReadBuffer<Bool_t >(cleanName, t); }}},
3058 {"Char_t", {"SIGNEDBYTE_TREE_BRANCH", [&](){ return createTreeReadBuffer<Char_t >(cleanName, t); }}},
3059 {"UInt_t", {"UNSIGNED_INTEGER_TREE_BRANCH", [&](){ return createTreeReadBuffer<UInt_t >(cleanName, t); }}},
3060 {"Long64_t", {"LONG_TREE_BRANCH", [&](){ return createTreeReadBuffer<Long64_t >(cleanName, t); }}},
3061 {"ULong64_t", {"UNSIGNED_LONG_TREE_BRANCH", [&](){ return createTreeReadBuffer<ULong64_t>(cleanName, t); }}},
3062 {"Short_t", {"SHORT_TREE_BRANCH", [&](){ return createTreeReadBuffer<Short_t >(cleanName, t); }}},
3063 {"UShort_t", {"UNSIGNED_SHORT_TREE_BRANCH", [&](){ return createTreeReadBuffer<UShort_t >(cleanName, t); }}},
3064 };
3065
3066 auto typeDetails = typeMap.find(typeName.Data());
3067 if (typeDetails != typeMap.end()) {
3068 coutI(DataHandling) << "RooAbsReal::attachToTree(" << GetName() << ") TTree " << typeDetails->first << " branch " << GetName()
3069 << " will be converted to double precision." << std::endl ;
3070 setAttribute(typeDetails->second.first.c_str(), true);
3071 _treeReadBuffer = typeDetails->second.second().release();
3072 } else {
3073 if (_treeReadBuffer) {
3074 delete _treeReadBuffer;
3075 }
3076 _treeReadBuffer = nullptr;
3077
3078 if (!typeName.CompareTo("Double_t")) {
3079 t.SetBranchAddress(cleanName, &_value);
3080 }
3081 else {
3082 coutE(InputArguments) << "RooAbsReal::attachToTree(" << GetName() << ") data type " << typeName << " is not supported." << std::endl ;
3083 }
3084 }
3085 } else {
3086
3087 TString format(cleanName);
3088 format.Append("/D");
3089 branch = t.Branch(cleanName, &_value, (const Text_t*)format, bufSize);
3090 }
3091
3092}
3093
3094
3095
3096////////////////////////////////////////////////////////////////////////////////
3097/// Fill the tree branch that associated with this object with its current value
3098
3100{
3101 // First determine if branch is taken
3102 TBranch* branch = t.GetBranch(cleanBranchName()) ;
3103 if (!branch) {
3104 coutE(Eval) << "RooAbsReal::fillTreeBranch(" << GetName() << ") ERROR: not attached to tree: " << cleanBranchName() << std::endl ;
3105 assert(0) ;
3106 }
3107 branch->Fill() ;
3108
3109}
3110
3111
3112
3113////////////////////////////////////////////////////////////////////////////////
3114/// (De)Activate associated tree branch
3115
3117{
3118 TBranch* branch = t.GetBranch(cleanBranchName()) ;
3119 if (branch) {
3120 t.SetBranchStatus(cleanBranchName(),active?true:false) ;
3121 }
3122}
3123
3124
3125
3126////////////////////////////////////////////////////////////////////////////////
3127/// Create a RooRealVar fundamental object with our properties. The new
3128/// object will be created without any fit limits.
3129
3131{
3132 auto fund = std::make_unique<RooRealVar>(newname?newname:GetName(),GetTitle(),_value,getUnit());
3133 fund->removeRange();
3134 fund->setPlotLabel(getPlotLabel());
3135 fund->setAttribute("fundamentalCopy");
3136 return RooFit::makeOwningPtr<RooAbsArg>(std::move(fund));
3137}
3138
3139
3140
3141////////////////////////////////////////////////////////////////////////////////
3142/// Utility function for use in getAnalyticalIntegral(). If the
3143/// content of proxy 'a' occurs in set 'allDeps' then the argument
3144/// held in 'a' is copied from allDeps to analDeps
3145
3146bool RooAbsReal::matchArgs(const RooArgSet& allDeps, RooArgSet& analDeps,
3147 const RooArgProxy& a) const
3148{
3149 TList nameList ;
3150 nameList.Add(new TObjString(a.absArg()->GetName())) ;
3151 bool result = matchArgsByName(allDeps,analDeps,nameList) ;
3152 nameList.Delete() ;
3153 return result ;
3154}
3155
3156
3157
3158////////////////////////////////////////////////////////////////////////////////
3159/// Utility function for use in getAnalyticalIntegral(). If the
3160/// contents of proxies a,b occur in set 'allDeps' then the arguments
3161/// held in a,b are copied from allDeps to analDeps
3162
3163bool RooAbsReal::matchArgs(const RooArgSet& allDeps, RooArgSet& analDeps,
3164 const RooArgProxy& a, const RooArgProxy& b) const
3165{
3166 TList nameList ;
3167 nameList.Add(new TObjString(a.absArg()->GetName())) ;
3168 nameList.Add(new TObjString(b.absArg()->GetName())) ;
3169 bool result = matchArgsByName(allDeps,analDeps,nameList) ;
3170 nameList.Delete() ;
3171 return result ;
3172}
3173
3174
3175
3176////////////////////////////////////////////////////////////////////////////////
3177/// Utility function for use in getAnalyticalIntegral(). If the
3178/// contents of proxies a,b,c occur in set 'allDeps' then the arguments
3179/// held in a,b,c are copied from allDeps to analDeps
3180
3181bool RooAbsReal::matchArgs(const RooArgSet& allDeps, RooArgSet& analDeps,
3182 const RooArgProxy& a, const RooArgProxy& b,
3183 const RooArgProxy& c) const
3184{
3185 TList nameList ;
3186 nameList.Add(new TObjString(a.absArg()->GetName())) ;
3187 nameList.Add(new TObjString(b.absArg()->GetName())) ;
3188 nameList.Add(new TObjString(c.absArg()->GetName())) ;
3189 bool result = matchArgsByName(allDeps,analDeps,nameList) ;
3190 nameList.Delete() ;
3191 return result ;
3192}
3193
3194
3195
3196////////////////////////////////////////////////////////////////////////////////
3197/// Utility function for use in getAnalyticalIntegral(). If the
3198/// contents of proxies a,b,c,d occur in set 'allDeps' then the arguments
3199/// held in a,b,c,d are copied from allDeps to analDeps
3200
3201bool RooAbsReal::matchArgs(const RooArgSet& allDeps, RooArgSet& analDeps,
3202 const RooArgProxy& a, const RooArgProxy& b,
3203 const RooArgProxy& c, const RooArgProxy& d) const
3204{
3205 TList nameList ;
3206 nameList.Add(new TObjString(a.absArg()->GetName())) ;
3207 nameList.Add(new TObjString(b.absArg()->GetName())) ;
3208 nameList.Add(new TObjString(c.absArg()->GetName())) ;
3209 nameList.Add(new TObjString(d.absArg()->GetName())) ;
3210 bool result = matchArgsByName(allDeps,analDeps,nameList) ;
3211 nameList.Delete() ;
3212 return result ;
3213}
3214
3215
3216////////////////////////////////////////////////////////////////////////////////
3217/// Utility function for use in getAnalyticalIntegral(). If the
3218/// contents of 'refset' occur in set 'allDeps' then the arguments
3219/// held in 'refset' are copied from allDeps to analDeps.
3220
3221bool RooAbsReal::matchArgs(const RooArgSet& allDeps, RooArgSet& analDeps,
3222 const RooArgSet& refset) const
3223{
3224 TList nameList ;
3225 for(RooAbsArg * arg : refset) {
3226 nameList.Add(new TObjString(arg->GetName())) ;
3227 }
3228
3229 bool result = matchArgsByName(allDeps,analDeps,nameList) ;
3230 nameList.Delete() ;
3231 return result ;
3232}
3233
3234
3235
3236////////////////////////////////////////////////////////////////////////////////
3237/// Check if allArgs contains matching elements for each name in nameList. If it does,
3238/// add the corresponding args from allArgs to matchedArgs and return true. Otherwise
3239/// return false and do not change matchedArgs.
3240
3241bool RooAbsReal::matchArgsByName(const RooArgSet &allArgs, RooArgSet &matchedArgs,
3242 const TList &nameList) const
3243{
3244 RooArgSet matched("matched");
3245 bool isMatched(true);
3246 for(auto * name : static_range_cast<TObjString*>(nameList)) {
3247 RooAbsArg *found= allArgs.find(name->String().Data());
3248 if(found) {
3249 matched.add(*found);
3250 }
3251 else {
3252 isMatched= false;
3253 break;
3254 }
3255 }
3256
3257 // nameList may not contain multiple entries with the same name
3258 // that are both matched
3259 if (isMatched && int(matched.size())!=nameList.GetSize()) {
3260 isMatched = false ;
3261 }
3262
3263 if(isMatched) matchedArgs.add(matched);
3264 return isMatched;
3265}
3266
3267
3268
3269////////////////////////////////////////////////////////////////////////////////
3270/// Returns the default numeric integration configuration for all RooAbsReals
3271
3273{
3275}
3276
3277
3278////////////////////////////////////////////////////////////////////////////////
3279/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3280/// If this object has no specialized configuration, a null pointer is returned.
3281
3283{
3284 return _specIntegratorConfig.get();
3285}
3286
3287
3288////////////////////////////////////////////////////////////////////////////////
3289/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3290/// If this object has no specialized configuration, a null pointer is returned,
3291/// unless createOnTheFly is true in which case a clone of the default integrator
3292/// configuration is created, installed as specialized configuration, and returned
3293
3295{
3296 if (!_specIntegratorConfig && createOnTheFly) {
3297 _specIntegratorConfig = std::make_unique<RooNumIntConfig>(*defaultIntegratorConfig()) ;
3298 }
3299 return _specIntegratorConfig.get();
3300}
3301
3302
3303
3304////////////////////////////////////////////////////////////////////////////////
3305/// Return the numeric integration configuration used for this object. If
3306/// a specialized configuration was associated with this object, that configuration
3307/// is returned, otherwise the default configuration for all RooAbsReals is returned
3308
3310{
3311 const RooNumIntConfig* config = specialIntegratorConfig() ;
3312 if (config) return config ;
3313 return defaultIntegratorConfig() ;
3314}
3315
3316
3317////////////////////////////////////////////////////////////////////////////////
3318/// Return the numeric integration configuration used for this object. If
3319/// a specialized configuration was associated with this object, that configuration
3320/// is returned, otherwise the default configuration for all RooAbsReals is returned
3321
3323{
3325 if (config) return config ;
3326 return defaultIntegratorConfig() ;
3327}
3328
3329
3330
3331////////////////////////////////////////////////////////////////////////////////
3332/// Set the given integrator configuration as default numeric integration
3333/// configuration for this object
3334
3336{
3337 _specIntegratorConfig = std::make_unique<RooNumIntConfig>(config);
3338}
3339
3340
3341
3342////////////////////////////////////////////////////////////////////////////////
3343/// Remove the specialized numeric integration configuration associated
3344/// with this object
3345
3347{
3348 _specIntegratorConfig.reset();
3349}
3350
3351
3352
3353
3354////////////////////////////////////////////////////////////////////////////////
3355/// Interface function to force use of a given set of observables
3356/// to interpret function value. Needed for functions or p.d.f.s
3357/// whose shape depends on the choice of normalization such as
3358/// RooAddPdf
3359
3361{
3362}
3363
3364
3365
3366
3367////////////////////////////////////////////////////////////////////////////////
3368/// Interface function to force use of a given normalization range
3369/// to interpret function value. Needed for functions or p.d.f.s
3370/// whose shape depends on the choice of normalization such as
3371/// RooAddPdf
3372
3374{
3375}
3376
3377
3378
3379////////////////////////////////////////////////////////////////////////////////
3380/// Advertise capability to determine maximum value of function for given set of
3381/// observables. If no direct generator method is provided, this information
3382/// will assist the accept/reject generator to operate more efficiently as
3383/// it can skip the initial trial sampling phase to empirically find the function
3384/// maximum
3385
3387{
3388 return 0 ;
3389}
3390
3391
3392
3393////////////////////////////////////////////////////////////////////////////////
3394/// Return maximum value for set of observables identified by code assigned
3395/// in getMaxVal
3396
3397double RooAbsReal::maxVal(Int_t /*code*/) const
3398{
3399 assert(1) ;
3400 return 0 ;
3401}
3402
3403
3404
3405////////////////////////////////////////////////////////////////////////////////
3406/// Interface to insert remote error logging messages received by RooRealMPFE into current error logging stream.
3407
3408void RooAbsReal::logEvalError(const RooAbsReal* originator, const char* origName, const char* message, const char* serverValueString)
3409{
3410 if (evalErrorData().mode == Ignore) {
3411 return ;
3412 }
3413
3414 if (evalErrorData().mode == CountErrors) {
3415 evalErrorData().count++ ;
3416 return ;
3417 }
3418
3419 static bool inLogEvalError = false ;
3420
3421 if (inLogEvalError) {
3422 return ;
3423 }
3424 inLogEvalError = true ;
3425
3426 EvalError ee ;
3427 ee.setMessage(message) ;
3428
3429 if (serverValueString) {
3430 ee.setServerValues(serverValueString) ;
3431 }
3432
3433 if (evalErrorData().mode == PrintErrors) {
3434 oocoutE(nullptr,Eval) << "RooAbsReal::logEvalError(" << "<STATIC>" << ") evaluation error, " << std::endl
3435 << " origin : " << origName << std::endl
3436 << " message : " << ee._msg << std::endl
3437 << " server values: " << ee._srvval << std::endl ;
3438 } else if (evalErrorData().mode == CollectErrors) {
3439 auto &evalErrorList = evalErrorData().errorList[originator];
3440 evalErrorList.first = origName ;
3441 evalErrorList.second.push_back(ee) ;
3442 }
3443
3444
3445 inLogEvalError = false ;
3446}
3447
3448
3449
3450////////////////////////////////////////////////////////////////////////////////
3451/// Log evaluation error message. Evaluation errors may be routed through a different
3452/// protocol than generic RooFit warning message (which go straight through RooMsgService)
3453/// because evaluation errors can occur in very large numbers in the use of likelihood
3454/// evaluations. In logEvalError mode, controlled by global method enableEvalErrorLogging()
3455/// messages reported through this function are not printed but all stored in a list,
3456/// along with server values at the time of reporting. Error messages logged in this
3457/// way can be printed in a structured way, eliminating duplicates and with the ability
3458/// to truncate the list by printEvalErrors. This is the standard mode of error logging
3459/// during MINUIT operations. If enableEvalErrorLogging() is false, all errors
3460/// reported through this method are passed for immediate printing through RooMsgService.
3461/// A string with server names and values is constructed automatically for error logging
3462/// purposes, unless a custom string with similar information is passed as argument.
3463
3464void RooAbsReal::logEvalError(const char* message, const char* serverValueString) const
3465{
3466 if (evalErrorData().mode == Ignore) {
3467 return ;
3468 }
3469
3470 if (evalErrorData().mode == CountErrors) {
3471 evalErrorData().count++ ;
3472 return ;
3473 }
3474
3475 static bool inLogEvalError = false ;
3476
3477 if (inLogEvalError) {
3478 return ;
3479 }
3480 inLogEvalError = true ;
3481
3482 EvalError ee ;
3483 ee.setMessage(message) ;
3484
3485 if (serverValueString) {
3486 ee.setServerValues(serverValueString) ;
3487 } else {
3488 std::string srvval ;
3489 std::ostringstream oss ;
3490 bool first(true) ;
3491 for (Int_t i=0 ; i<numProxies() ; i++) {
3492 RooAbsProxy* p = getProxy(i) ;
3493 if (!p) continue ;
3494 //if (p->name()[0]=='!') continue ;
3495 if (first) {
3496 first=false ;
3497 } else {
3498 oss << ", " ;
3499 }
3500 p->print(oss,true) ;
3501 }
3502 ee.setServerValues(oss.str().c_str()) ;
3503 }
3504
3505 std::ostringstream oss2 ;
3507
3508 if (evalErrorData().mode == PrintErrors) {
3509 coutE(Eval) << "RooAbsReal::logEvalError(" << GetName() << ") evaluation error, " << std::endl
3510 << " origin : " << oss2.str() << std::endl
3511 << " message : " << ee._msg << std::endl
3512 << " server values: " << ee._srvval << std::endl ;
3513 } else if (evalErrorData().mode == CollectErrors) {
3514 auto &evalErrorList = evalErrorData().errorList[this];
3515 if (evalErrorList.second.size() >= 2048) {
3516 // avoid overflowing the error list, so if there are very many, print
3517 // the oldest one first, and pop it off the list
3518 const EvalError& oee = evalErrorList.second.front();
3519 // print to debug stream, since these would normally be suppressed, and
3520 // we do not want to increase the error count in the message service...
3521 ccoutD(Eval) << "RooAbsReal::logEvalError(" << GetName()
3522 << ") delayed evaluation error, " << std::endl
3523 << " origin : " << oss2.str() << std::endl
3524 << " message : " << oee._msg << std::endl
3525 << " server values: " << oee._srvval << std::endl ;
3526 evalErrorList.second.pop_front();
3527 }
3528 evalErrorList.first = oss2.str() ;
3529 evalErrorList.second.push_back(ee) ;
3530 }
3531
3532 inLogEvalError = false ;
3533 //coutE(Tracing) << "RooAbsReal::logEvalError(" << GetName() << ") message = " << message << std::endl ;
3534}
3535
3536
3537
3538
3539////////////////////////////////////////////////////////////////////////////////
3540/// Clear the stack of evaluation error messages
3541
3543{
3544 if (evalErrorData().mode == PrintErrors) {
3545 return ;
3546 } else if (evalErrorData().mode == CollectErrors) {
3547 evalErrorData().errorList.clear() ;
3548 } else {
3549 evalErrorData().count = 0 ;
3550 }
3551}
3552
3553
3554////////////////////////////////////////////////////////////////////////////////
3555/// Retrieve bin boundaries if this distribution is binned in `obs`.
3556/// \param[in] obs Observable to retrieve boundaries for.
3557/// \param[in] xlo Beginning of range.
3558/// \param[in] xhi End of range.
3559/// \return The caller owns the returned std::list.
3560std::list<double>* RooAbsReal::binBoundaries(RooAbsRealLValue& /*obs*/, double /*xlo*/, double /*xhi*/) const {
3561 return nullptr;
3562}
3563
3564
3565////////////////////////////////////////////////////////////////////////////////
3566/// Interface for returning an optional hint for initial sampling points when constructing a curve projected on observable `obs`.
3567/// \param[in] obs Observable to retrieve sampling hint for.
3568/// \param[in] xlo Beginning of range.
3569/// \param[in] xhi End of range.
3570/// \return The caller owns the returned std::list.
3571std::list<double>* RooAbsReal::plotSamplingHint(RooAbsRealLValue& /*obs*/, double /*xlo*/, double /*xhi*/) const {
3572 return nullptr;
3573}
3574
3575////////////////////////////////////////////////////////////////////////////////
3576/// Print all outstanding logged evaluation error on the given ostream. If maxPerNode
3577/// is zero, only the number of errors for each source (object with unique name) is listed.
3578/// If maxPerNode is greater than zero, up to maxPerNode detailed error messages are shown
3579/// per source of errors. A truncation message is shown if there were more errors logged
3580/// than shown.
3581
3582void RooAbsReal::printEvalErrors(std::ostream &os, Int_t maxPerNode)
3583{
3584 if (evalErrorData().mode == CountErrors) {
3585 os << evalErrorData().count << " errors counted" << std::endl;
3586 }
3587
3588 if (maxPerNode < 0)
3589 return;
3590
3591 for (auto const &item : evalErrorData().errorList) {
3592 if (maxPerNode == 0) {
3593
3594 // Only print node name with total number of errors
3595 os << item.second.first;
3596 // item.first->printStream(os,kName|kClassName|kArgs,kInline) ;
3597 os << " has " << item.second.second.size() << " errors" << std::endl;
3598
3599 } else {
3600
3601 // Print node name and details of 'maxPerNode' errors
3602 os << item.second.first << std::endl;
3603 // item.first->printStream(os,kName|kClassName|kArgs,kSingleLine) ;
3604
3605 Int_t i(0);
3606 for (auto const &item2 : item.second.second) {
3607 os << " " << item2._msg << " @ " << item2._srvval << std::endl;
3608 if (i > maxPerNode) {
3609 os << " ... (remaining " << item.second.second.size() - maxPerNode << " messages suppressed)"
3610 << std::endl;
3611 break;
3612 }
3613 i++;
3614 }
3615 }
3616 }
3617}
3618
3619
3620
3621////////////////////////////////////////////////////////////////////////////////
3622/// Return the number of logged evaluation errors since the last clearing.
3623
3625{
3626 auto &evalErrors = evalErrorData();
3627 if (evalErrors.mode == CountErrors) {
3628 return evalErrors.count;
3629 }
3630
3631 Int_t ntot(0);
3632 for (auto const &elem : evalErrors.errorList) {
3633 ntot += elem.second.second.size();
3634 }
3635 return ntot;
3636}
3637
3638
3639
3640////////////////////////////////////////////////////////////////////////////////
3641/// Fix the interpretation of the coefficient of any RooAddPdf component in
3642/// the expression tree headed by this object to the given set of observables.
3643///
3644/// If the force flag is false, the normalization choice is only fixed for those
3645/// RooAddPdf components that have the default 'automatic' interpretation of
3646/// coefficients (i.e. the interpretation is defined by the observables passed
3647/// to getVal()). If force is true, also RooAddPdf that already have a fixed
3648/// interpretation are changed to a new fixed interpretation.
3649
3650void RooAbsReal::fixAddCoefNormalization(const RooArgSet& addNormSet, bool force)
3651{
3652 std::unique_ptr<RooArgSet> compSet{getComponents()};
3653 for(auto * pdf : dynamic_range_cast<RooAbsPdf*>(*compSet)) {
3654 if (pdf) {
3655 if (!addNormSet.empty()) {
3656 pdf->selectNormalization(&addNormSet,force) ;
3657 } else {
3658 pdf->selectNormalization(nullptr,force) ;
3659 }
3660 }
3661 }
3662}
3663
3664
3665
3666////////////////////////////////////////////////////////////////////////////////
3667/// Fix the interpretation of the coefficient of any RooAddPdf component in
3668/// the expression tree headed by this object to the given set of observables.
3669///
3670/// If the force flag is false, the normalization range choice is only fixed for those
3671/// RooAddPdf components that currently use the default full domain to interpret their
3672/// coefficients. If force is true, also RooAddPdf that already have a fixed
3673/// interpretation range are changed to a new fixed interpretation range.
3674
3675void RooAbsReal::fixAddCoefRange(const char* rangeName, bool force)
3676{
3677 std::unique_ptr<RooArgSet> compSet{getComponents()};
3678 for(auto * pdf : dynamic_range_cast<RooAbsPdf*>(*compSet)) {
3679 if (pdf) {
3680 pdf->selectNormalizationRange(rangeName,force) ;
3681 }
3682 }
3683}
3684
3685
3686
3687////////////////////////////////////////////////////////////////////////////////
3688/// Interface method for function objects to indicate their preferred order of observables
3689/// for scanning their values into a (multi-dimensional) histogram or RooDataSet. The observables
3690/// to be ordered are offered in argument 'obs' and should be copied in their preferred
3691/// order into argument 'orderedObs', This default implementation indicates no preference
3692/// and copies the original order of 'obs' into 'orderedObs'
3693
3695{
3696 // Dummy implementation, do nothing
3697 orderedObs.removeAll() ;
3698 orderedObs.add(obs) ;
3699}
3700
3701
3702
3703////////////////////////////////////////////////////////////////////////////////
3704/// Calls createRunningIntegral(const RooArgSet&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&)
3705
3707{
3708 return createRunningIntegral(iset,RooFit::SupNormSet(nset)) ;
3709}
3710
3711
3712
3713////////////////////////////////////////////////////////////////////////////////
3714/// Create an object that represents the running integral of the function over one or more observables listed in iset, i.e.
3715/// \f[
3716/// \int_{x_\mathrm{lo}}^x f(x') \, \mathrm{d}x'
3717/// \f]
3718///
3719/// The actual integration calculation is only performed when the return object is evaluated. The name
3720/// of the integral object is automatically constructed from the name of the input function, the variables
3721/// it integrates and the range integrates over. The default strategy to calculate the running integrals is
3722///
3723/// - If the integrand (this object) supports analytical integration, construct an integral object
3724/// that calculate the running integrals value by calculating the analytical integral each
3725/// time the running integral object is evaluated
3726///
3727/// - If the integrand (this object) requires numeric integration to construct the running integral
3728/// create an object of class RooNumRunningInt which first samples the entire function and integrates
3729/// the sampled function numerically. This method has superior performance as there is no need to
3730/// perform a full (numeric) integration for each evaluation of the running integral object, but
3731/// only when one of its parameters has changed.
3732///
3733/// The choice of strategy can be changed with the ScanAll() argument, which forces the use of the
3734/// scanning technique implemented in RooNumRunningInt for all use cases, and with the ScanNone()
3735/// argument which forces the 'integrate each evaluation' technique for all use cases. The sampling
3736/// granularity for the scanning technique can be controlled with the ScanParameters technique
3737/// which allows to specify the number of samples to be taken, and to which order the resulting
3738/// running integral should be interpolated. The default values are 1000 samples and 2nd order
3739/// interpolation.
3740///
3741/// The following named arguments are accepted
3742/// | | Effect on integral creation
3743/// |-|-------------------------------
3744/// | `SupNormSet(const RooArgSet&)` | Observables over which should be normalized _in addition_ to the integration observables
3745/// | `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
3746/// | `ScanNum()` | Apply scanning technique if cdf integral involves numeric integration
3747/// | `ScanAll()` | Always apply scanning technique
3748/// | `ScanNone()` | Never apply scanning technique
3749
3751 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
3752 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
3753{
3754 // Define configuration for this method
3755 RooCmdConfig pc("RooAbsReal::createRunningIntegral(" + std::string(GetName()) + ")");
3756 pc.defineSet("supNormSet","SupNormSet",0,nullptr) ;
3757 pc.defineInt("numScanBins","ScanParameters",0,1000) ;
3758 pc.defineInt("intOrder","ScanParameters",1,2) ;
3759 pc.defineInt("doScanNum","ScanNum",0,1) ;
3760 pc.defineInt("doScanAll","ScanAll",0,0) ;
3761 pc.defineInt("doScanNon","ScanNone",0,0) ;
3762 pc.defineMutex("ScanNum","ScanAll","ScanNone") ;
3763
3764 // Process & check varargs
3765 pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
3766 if (!pc.ok(true)) {
3767 return nullptr ;
3768 }
3769
3770 // Extract values from named arguments
3771 RooArgSet nset ;
3772 if (const RooArgSet* snset = pc.getSet("supNormSet",nullptr)) {
3773 nset.add(*snset) ;
3774 }
3775 Int_t numScanBins = pc.getInt("numScanBins") ;
3776 Int_t intOrder = pc.getInt("intOrder") ;
3777 Int_t doScanNum = pc.getInt("doScanNum") ;
3778 Int_t doScanAll = pc.getInt("doScanAll") ;
3779 Int_t doScanNon = pc.getInt("doScanNon") ;
3780
3781 // If scanning technique is not requested make integral-based cdf and return
3782 if (doScanNon) {
3783 return createIntRI(iset,nset) ;
3784 }
3785 if (doScanAll) {
3786 return createScanRI(iset,nset,numScanBins,intOrder) ;
3787 }
3788 if (doScanNum) {
3789 std::unique_ptr<RooAbsReal> tmp{createIntegral(iset)} ;
3790 Int_t isNum= !static_cast<RooRealIntegral&>(*tmp).numIntRealVars().empty();
3791
3792 if (isNum) {
3793 coutI(NumIntegration) << "RooAbsPdf::createRunningIntegral(" << GetName() << ") integration over observable(s) " << iset << " involves numeric integration," << std::endl
3794 << " constructing cdf though numeric integration of sampled pdf in " << numScanBins << " bins and applying order "
3795 << intOrder << " interpolation on integrated histogram." << std::endl
3796 << " To override this choice of technique use argument ScanNone(), to change scan parameters use ScanParameters(nbins,order) argument" << std::endl ;
3797 }
3798
3799 return isNum ? createScanRI(iset,nset,numScanBins,intOrder) : createIntRI(iset,nset) ;
3800 }
3801 return nullptr;
3802}
3803
3804
3805
3806////////////////////////////////////////////////////////////////////////////////
3807/// Utility function for createRunningIntegral that construct an object
3808/// implementing the numeric scanning technique for calculating the running integral
3809
3811{
3812 std::string name = std::string(GetName()) + "_NUMRUNINT_" + integralNameSuffix(iset,&nset).Data() ;
3813 RooRealVar* ivar = static_cast<RooRealVar*>(iset.first()) ;
3814 ivar->setBins(numScanBins,"numcdf") ;
3815 auto ret = std::make_unique<RooNumRunningInt>(name.c_str(),name.c_str(),*this,*ivar,"numrunint") ;
3816 ret->setInterpolationOrder(intOrder) ;
3817 return RooFit::makeOwningPtr<RooAbsReal>(std::move(ret));
3818}
3819
3820
3821
3822////////////////////////////////////////////////////////////////////////////////
3823/// Utility function for createRunningIntegral. It creates an
3824/// object implementing the standard (analytical) integration
3825/// technique for calculating the running integral.
3826
3828{
3829 // Make list of input arguments keeping only RooRealVars
3830 RooArgList ilist ;
3831 for(RooAbsArg * arg : iset) {
3832 if (dynamic_cast<RooRealVar*>(arg)) {
3833 ilist.add(*arg) ;
3834 } else {
3835 coutW(InputArguments) << "RooAbsPdf::createRunningIntegral(" << GetName() << ") WARNING ignoring non-RooRealVar input argument " << arg->GetName() << std::endl ;
3836 }
3837 }
3838
3839 RooArgList cloneList ;
3840 RooArgList loList ;
3841 RooArgSet clonedBranchNodes ;
3842
3843 // Setup customizer that stores all cloned branches in our non-owning list
3844 RooCustomizer cust(*this,"cdf") ;
3845 cust.setCloneBranchSet(clonedBranchNodes) ;
3846 cust.setOwning(false) ;
3847
3848 // Make integration observable x_prime for each observable x as well as an x_lowbound
3849 for(auto * rrv : static_range_cast<RooRealVar*>(ilist)) {
3850
3851 // Make clone x_prime of each c.d.f observable x represening running integral
3852 RooRealVar* cloneArg = static_cast<RooRealVar*>(rrv->clone(Form("%s_prime",rrv->GetName()))) ;
3853 cloneList.add(*cloneArg) ;
3854 cust.replaceArg(*rrv,*cloneArg) ;
3855
3856 // Make clone x_lowbound of each c.d.f observable representing low bound of x
3857 RooRealVar* cloneLo = static_cast<RooRealVar*>(rrv->clone(Form("%s_lowbound",rrv->GetName()))) ;
3858 cloneLo->setVal(rrv->getMin()) ;
3859 loList.add(*cloneLo) ;
3860
3861 // Make parameterized binning from [x_lowbound,x] for each x_prime
3862 RooParamBinning pb(*cloneLo,*rrv,100) ;
3863 cloneArg->setBinning(pb,"CDF") ;
3864
3865 }
3866
3867 RooAbsReal* tmp = static_cast<RooAbsReal*>(cust.build()) ;
3868
3869 // Construct final normalization set for c.d.f = integrated observables + any extra specified by user
3870 RooArgSet finalNset(nset) ;
3871 finalNset.add(cloneList,true) ;
3872 std::unique_ptr<RooAbsReal> cdf{tmp->createIntegral(cloneList,finalNset,"CDF")};
3873
3874 // Transfer ownership of cloned items to top-level c.d.f object
3875 cdf->addOwnedComponents(*tmp) ;
3876 cdf->addOwnedComponents(cloneList) ;
3877 cdf->addOwnedComponents(loList) ;
3878
3879 return RooFit::makeOwningPtr(std::move(cdf));
3880}
3881
3882
3883////////////////////////////////////////////////////////////////////////////////
3884/// Return a RooFunctor object bound to this RooAbsReal with given definition of observables
3885/// and parameters
3886
3887RooFunctor* RooAbsReal::functor(const RooArgList& obs, const RooArgList& pars, const RooArgSet& nset) const
3888{
3889 RooArgSet realObs;
3890 getObservables(&obs, realObs);
3891 if (realObs.size() != obs.size()) {
3892 coutE(InputArguments) << "RooAbsReal::functor(" << GetName() << ") ERROR: one or more specified observables are not variables of this p.d.f" << std::endl ;
3893 return nullptr;
3894 }
3895 RooArgSet realPars;
3896 getObservables(&pars, realPars);
3897 if (realPars.size() != pars.size()) {
3898 coutE(InputArguments) << "RooAbsReal::functor(" << GetName() << ") ERROR: one or more specified parameters are not variables of this p.d.f" << std::endl ;
3899 return nullptr;
3900 }
3901
3902 return new RooFunctor(*this,obs,pars,nset) ;
3903}
3904
3905
3906
3907////////////////////////////////////////////////////////////////////////////////
3908/// Return a ROOT TF1,2,3 object bound to this RooAbsReal with given definition of observables
3909/// and parameters
3910
3911TF1* RooAbsReal::asTF(const RooArgList& obs, const RooArgList& pars, const RooArgSet& nset) const
3912{
3913 // Check that specified input are indeed variables of this function
3914 RooArgSet realObs;
3915 getObservables(&obs, realObs) ;
3916 if (realObs.size() != obs.size()) {
3917 coutE(InputArguments) << "RooAbsReal::functor(" << GetName() << ") ERROR: one or more specified observables are not variables of this p.d.f" << std::endl ;
3918 return nullptr ;
3919 }
3920 RooArgSet realPars;
3921 getObservables(&pars, realPars) ;
3922 if (realPars.size() != pars.size()) {
3923 coutE(InputArguments) << "RooAbsReal::functor(" << GetName() << ") ERROR: one or more specified parameters are not variables of this p.d.f" << std::endl ;
3924 return nullptr ;
3925 }
3926
3927 // Check that all obs and par are of type RooRealVar
3928 for (std::size_t i=0 ; i<obs.size() ; i++) {
3929 if (dynamic_cast<RooRealVar*>(obs.at(i))==nullptr) {
3930 coutE(ObjectHandling) << "RooAbsReal::asTF(" << GetName() << ") ERROR: proposed observable " << obs.at(0)->GetName() << " is not of type RooRealVar" << std::endl ;
3931 return nullptr ;
3932 }
3933 }
3934 for (std::size_t i=0 ; i<pars.size() ; i++) {
3935 if (dynamic_cast<RooRealVar*>(pars.at(i))==nullptr) {
3936 coutE(ObjectHandling) << "RooAbsReal::asTF(" << GetName() << ") ERROR: proposed parameter " << pars.at(0)->GetName() << " is not of type RooRealVar" << std::endl ;
3937 return nullptr ;
3938 }
3939 }
3940
3941 // Create functor and TFx of matching dimension
3942 TF1* tf=nullptr ;
3943 RooFunctor* f ;
3944 switch(obs.size()) {
3945 case 1: {
3946 RooRealVar* x = static_cast<RooRealVar*>(obs.at(0)) ;
3947 f = functor(obs,pars,nset) ;
3948 tf = new TF1(GetName(),f,x->getMin(),x->getMax(),pars.size()) ;
3949 break ;
3950 }
3951 case 2: {
3952 RooRealVar* x = static_cast<RooRealVar*>(obs.at(0)) ;
3953 RooRealVar* y = static_cast<RooRealVar*>(obs.at(1)) ;
3954 f = functor(obs,pars,nset) ;
3955 tf = new TF2(GetName(),f,x->getMin(),x->getMax(),y->getMin(),y->getMax(),pars.size()) ;
3956 break ;
3957 }
3958 case 3: {
3959 RooRealVar* x = static_cast<RooRealVar*>(obs.at(0)) ;
3960 RooRealVar* y = static_cast<RooRealVar*>(obs.at(1)) ;
3961 RooRealVar* z = static_cast<RooRealVar*>(obs.at(2)) ;
3962 f = functor(obs,pars,nset) ;
3963 tf = new TF3(GetName(),f,x->getMin(),x->getMax(),y->getMin(),y->getMax(),z->getMin(),z->getMax(),pars.size()) ;
3964 break ;
3965 }
3966 default:
3967 coutE(InputArguments) << "RooAbsReal::asTF(" << GetName() << ") ERROR: " << obs.size()
3968 << " observables specified, but a ROOT TFx can only have 1,2 or 3 observables" << std::endl ;
3969 return nullptr ;
3970 }
3971
3972 // Set initial parameter values of TFx to those of RooRealVars
3973 for (std::size_t i=0 ; i<pars.size() ; i++) {
3974 RooRealVar* p = static_cast<RooRealVar*>(pars.at(i)) ;
3975 tf->SetParameter(i,p->getVal()) ;
3976 tf->SetParName(i,p->GetName()) ;
3977 //tf->SetParLimits(i,p->getMin(),p->getMax()) ;
3978 }
3979
3980 return tf ;
3981}
3982
3983
3984////////////////////////////////////////////////////////////////////////////////
3985/// Return function representing first, second or third order derivative of this function
3986
3988{
3989 std::string name=Form("%s_DERIV_%s",GetName(),obs.GetName()) ;
3990 std::string title=Form("Derivative of %s w.r.t %s ",GetName(),obs.GetName()) ;
3991 return new RooDerivative(name.c_str(),title.c_str(),*this,obs,order,eps) ;
3992}
3993
3994
3995
3996////////////////////////////////////////////////////////////////////////////////
3997/// Return function representing first, second or third order derivative of this function
3998
3999RooDerivative* RooAbsReal::derivative(RooRealVar& obs, const RooArgSet& normSet, Int_t order, double eps)
4000{
4001 std::string name=Form("%s_DERIV_%s",GetName(),obs.GetName()) ;
4002 std::string title=Form("Derivative of %s w.r.t %s ",GetName(),obs.GetName()) ;
4003 return new RooDerivative(name.c_str(),title.c_str(),*this,obs,normSet,order,eps) ;
4004}
4005
4006
4007
4008////////////////////////////////////////////////////////////////////////////////
4009/// Return function representing moment of function of given order.
4010/// \param[in] obs Observable to calculate the moments for
4011/// \param[in] order Order of the moment
4012/// \param[in] central If true, the central moment is given by \f$ \langle (x- \langle x \rangle )^2 \rangle \f$
4013/// \param[in] takeRoot Calculate the square root
4014
4015RooAbsMoment* RooAbsReal::moment(RooRealVar& obs, Int_t order, bool central, bool takeRoot)
4016{
4017 std::string name=Form("%s_MOMENT_%d%s_%s",GetName(),order,(central?"C":""),obs.GetName()) ;
4018 std::string title=Form("%sMoment of order %d of %s w.r.t %s ",(central?"Central ":""),order,GetName(),obs.GetName()) ;
4019 if (order==1) return new RooFirstMoment(name.c_str(),title.c_str(),*this,obs) ;
4020 if (order==2) return new RooSecondMoment(name.c_str(),title.c_str(),*this,obs,central,takeRoot) ;
4021 return new RooMoment(name.c_str(),title.c_str(),*this,obs,order,central,takeRoot) ;
4022}
4023
4024
4025////////////////////////////////////////////////////////////////////////////////
4026/// Return function representing moment of p.d.f (normalized w.r.t given observables) of given order.
4027/// \param[in] obs Observable to calculate the moments for
4028/// \param[in] normObs Normalise w.r.t. these observables
4029/// \param[in] order Order of the moment
4030/// \param[in] central If true, the central moment is given by \f$ \langle (x- \langle x \rangle )^2 \rangle \f$
4031/// \param[in] takeRoot Calculate the square root
4032/// \param[in] intNormObs If true, the moment of the function integrated over all normalization observables is returned.
4033
4034RooAbsMoment* RooAbsReal::moment(RooRealVar& obs, const RooArgSet& normObs, Int_t order, bool central, bool takeRoot, bool intNormObs)
4035{
4036 std::string name=Form("%s_MOMENT_%d%s_%s",GetName(),order,(central?"C":""),obs.GetName()) ;
4037 std::string title=Form("%sMoment of order %d of %s w.r.t %s ",(central?"Central ":""),order,GetName(),obs.GetName()) ;
4038
4039 if (order==1) return new RooFirstMoment(name.c_str(),title.c_str(),*this,obs,normObs,intNormObs) ;
4040 if (order==2) return new RooSecondMoment(name.c_str(),title.c_str(),*this,obs,normObs,central,takeRoot,intNormObs) ;
4041 return new RooMoment(name.c_str(),title.c_str(),*this,obs,normObs,order,central,takeRoot,intNormObs) ;
4042}
4043
4044
4045
4046////////////////////////////////////////////////////////////////////////////////
4047///
4048/// Return value of x (in range xmin,xmax) at which function equals yval.
4049/// (Calculation is performed with Brent root finding algorithm)
4050
4051double RooAbsReal::findRoot(RooRealVar& x, double xmin, double xmax, double yval)
4052{
4053 double result(0) ;
4055 return result ;
4056}
4057
4058
4059
4060////////////////////////////////////////////////////////////////////////////////
4061/// Perform a \f$ \chi^2 \f$ fit to given histogram. By default the fit is executed through the MINUIT
4062/// commands MIGRAD, HESSE in succession
4063///
4064/// The following named arguments are supported
4065///
4066/// <table>
4067/// <tr><th> <th> Options to control construction of chi2
4068/// <tr><td> `Extended(bool flag)` <td> **Only applicable when fitting a RooAbsPdf**. Scale the normalized pdf by the number of events predicted by the model instead of scaling by the total data weight.
4069/// This imposes a constraint on the predicted number of events analogous to the extended term in a likelihood fit.
4070/// - If you don't pass this command, an extended fit will be done by default if the pdf makes a prediction on the number of events
4071/// (in RooFit jargon, "if the pdf can be extended").
4072/// - Passing `Extended(true)` when the the pdf makes no prediction on the expected number of events will result in error messages,
4073/// and the chi2 will fall back to the total data weight to scale the normalized pdf.
4074/// - There are cases where the fit **must** be done in extended mode. This happens for example when you have a RooAddPdf
4075/// where the coefficients represent component yields. If the fit is not extended, these coefficients will not be
4076/// well-defined, as the RooAddPdf always normalizes itself. If you pass `Extended(false)` in such a case, an error will be
4077/// printed and you'll most likely get garbage results.
4078/// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name
4079/// <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.
4080/// Multiple comma separated range names can be specified.
4081/// <tr><td> `NumCPU(int num)` <td> Parallelize NLL calculation on num CPUs
4082/// <tr><td> `Optimize(bool flag)` <td> Activate constant term optimization (on by default)
4083/// <tr><td> `IntegrateBins()` <td> Integrate PDF within each bin. This sets the desired precision.
4084///
4085/// <tr><th> <th> Options to control flow of fit procedure
4086/// <tr><td> `InitialHesse(bool flag)` <td> Flag controls if HESSE before MIGRAD as well, off by default
4087/// <tr><td> `Hesse(bool flag)` <td> Flag controls if HESSE is run after MIGRAD, on by default
4088/// <tr><td> `Minos(bool flag)` <td> Flag controls if MINOS is run after HESSE, on by default
4089/// <tr><td> `Minos(const RooArgSet& set)` <td> Only run MINOS on given subset of arguments
4090/// <tr><td> `Save(bool flag)` <td> Flag controls if RooFitResult object is produced and returned, off by default
4091/// <tr><td> `Strategy(Int_t flag)` <td> Set Minuit strategy (0 through 2, default is 1)
4092///
4093/// <tr><th> <th> Options to control informational output
4094/// <tr><td> `Verbose(bool flag)` <td> Flag controls if verbose output is printed (NLL, parameter changes during fit
4095/// <tr><td> `Timer(bool flag)` <td> Time CPU and wall clock consumption of fit steps, off by default
4096/// <tr><td> `PrintLevel(Int_t level)` <td> Set Minuit print level (-1 through 3, default is 1). At -1 all RooFit informational
4097/// messages are suppressed as well
4098/// <tr><td> `Warnings(bool flag)` <td> Enable or disable MINUIT warnings (enabled by default)
4099/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per likelihood evaluation. A negative
4100/// value suppress output completely, a zero value will only print the error count per p.d.f component,
4101/// a positive value is will print details of each error up to numErr messages per p.d.f component.
4102/// </table>
4103///
4104
4106 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
4107 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
4108{
4110 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
4111 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
4112 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
4113 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
4114 return chi2FitTo(data,l) ;
4115}
4116
4117
4118
4119////////////////////////////////////////////////////////////////////////////////
4120/// Calls RooAbsReal::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
4121///
4122/// List of possible commands in the `cmdList`:
4123///
4124/// <table>
4125/// <tr><th> Type of CmdArg <th> Effect on \f$ \chi^2 \f$
4126/// <tr><td>
4127/// <tr><td> `DataError()` <td> Choose between:
4128/// - RooAbsData::Expected: Expected Poisson error (\f$ \sqrt{n_\text{expected}} \f$ from the PDF).
4129/// - RooAbsData::SumW2: The observed error from the square root of the sum of weights,
4130/// i.e., symmetric errors calculated with the standard deviation of a Poisson distribution.
4131/// - RooAbsData::Poisson: Asymmetric errors from the central 68 % interval around a Poisson distribution with mean \f$ n_\text{observed} \f$.
4132/// If for a given bin \f$ n_\text{expected} \f$ is lower than the \f$ n_\text{observed} \f$, the lower uncertainty is taken
4133/// (e.g., the difference between the mean and the 16 % quantile).
4134/// If \f$ n_\text{expected} \f$ is higher than \f$ n_\text{observed} \f$, the higher uncertainty is taken
4135/// (e.g., the difference between the 84 % quantile and the mean).
4136/// - RooAbsData::Auto (default): RooAbsData::Expected for unweighted data, RooAbsData::SumW2 for weighted data.
4137/// <tr><td>
4138/// `Extended()` <td> Use expected number of events of an extended p.d.f as normalization
4139/// <tr><td>
4140/// NumCPU() <td> Activate parallel processing feature
4141/// <tr><td>
4142/// Range() <td> Calculate \f$ \chi^2 \f$ only in selected region
4143/// <tr><td>
4144/// Verbose() <td> Verbose output of GOF framework
4145/// <tr><td>
4146/// IntegrateBins() <td> Integrate PDF within each bin. This sets the desired precision. Only useful for binned fits.
4147/// <tr><td> `SumCoefRange()` <td> Set the range in which to interpret the coefficients of RooAddPdf components
4148/// <tr><td> `SplitRange()` <td> Fit ranges used in different categories get named after the category.
4149/// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
4150/// ```
4151/// myVariable.setRange("range_pi0", 135, 210);
4152/// myVariable.setRange("range_gamma", 50, 210);
4153/// ```
4154/// <tr><td> `ConditionalObservables(Args_t &&... argsOrArgSet)` <td> Define projected observables.
4155/// Arguments can either be multiple RooRealVar or a single RooArgSet containing them.
4156///
4157/// </table>
4158
4160{
4161 return RooFit::makeOwningPtr(RooFit::FitHelpers::fitTo(*this, data, cmdList, true));
4162}
4163
4164
4165
4166
4167////////////////////////////////////////////////////////////////////////////////
4168/// Create a \f$ \chi^2 \f$ variable from a histogram and this function.
4169///
4170/// \param arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8 ordered arguments
4171///
4172/// The list of supported command arguments is given in the documentation for
4173/// 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&).
4174///
4175/// \param data Histogram with data
4176/// \return \f$ \chi^2 \f$ variable
4177
4179 const RooCmdArg &arg3, const RooCmdArg &arg4,
4180 const RooCmdArg &arg5, const RooCmdArg &arg6,
4181 const RooCmdArg &arg7, const RooCmdArg &arg8)
4182{
4184 l.Add((TObject *)&arg1);
4185 l.Add((TObject *)&arg2);
4186 l.Add((TObject *)&arg3);
4187 l.Add((TObject *)&arg4);
4188 l.Add((TObject *)&arg5);
4189 l.Add((TObject *)&arg6);
4190 l.Add((TObject *)&arg7);
4191 l.Add((TObject *)&arg8);
4192 return createChi2(data, l);
4193}
4194
4195////////////////////////////////////////////////////////////////////////////////
4196/// \see RooAbsReal::createChi2(RooDataHist&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
4197/// \param data hist data
4198/// \param cmdList List with RooCmdArg() from the table
4199
4201{
4202 return RooFit::makeOwningPtr(RooFit::FitHelpers::createChi2(*this, data, cmdList));
4203}
4204
4205////////////////////////////////////////////////////////////////////////////////
4206/// Perform a 2-D \f$ \chi^2 \f$ fit using a series of x and y values stored in the dataset `xydata`.
4207/// The y values can either be the event weights, or can be another column designated
4208/// by the YVar() argument. The y value must have errors defined for the \f$ \chi^2 \f$ to
4209/// be well defined.
4210///
4211/// <table>
4212/// <tr><th><th> Options to control construction of the chi-square
4213/// <tr><td> `YVar(RooRealVar& yvar)` <td> Designate given column in dataset as Y value
4214/// <tr><td> `Integrate(bool flag)` <td> Integrate function over range specified by X errors
4215/// rather than take value at bin center.
4216///
4217/// <tr><th><th> Options to control flow of fit procedure
4218/// <tr><td> `InitialHesse(bool flag)` <td> Flag controls if HESSE before MIGRAD as well, off by default
4219/// <tr><td> `Hesse(bool flag)` <td> Flag controls if HESSE is run after MIGRAD, on by default
4220/// <tr><td> `Minos(bool flag)` <td> Flag controls if MINOS is run after HESSE, on by default
4221/// <tr><td> `Minos(const RooArgSet& set)` <td> Only run MINOS on given subset of arguments
4222/// <tr><td> `Save(bool flag)` <td> Flag controls if RooFitResult object is produced and returned, off by default
4223/// <tr><td> `Strategy(Int_t flag)` <td> Set Minuit strategy (0 through 2, default is 1)
4224///
4225/// <tr><th><th> Options to control informational output
4226/// <tr><td> `Verbose(bool flag)` <td> Flag controls if verbose output is printed (NLL, parameter changes during fit
4227/// <tr><td> `Timer(bool flag)` <td> Time CPU and wall clock consumption of fit steps, off by default
4228/// <tr><td> `PrintLevel(Int_t level)` <td> Set Minuit print level (-1 through 3, default is 1). At -1 all RooFit informational
4229/// messages are suppressed as well
4230/// <tr><td> `Warnings(bool flag)` <td> Enable or disable MINUIT warnings (enabled by default)
4231/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per likelihood evaluation. A negative
4232/// value suppress output completely, a zero value will only print the error count per p.d.f component,
4233/// a positive value is will print details of each error up to numErr messages per p.d.f component.
4234/// </table>
4235
4237 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
4238 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
4239{
4241 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
4242 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
4243 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
4244 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
4245 return chi2FitTo(xydata,l) ;
4246}
4247
4248
4249
4250
4251////////////////////////////////////////////////////////////////////////////////
4252/// \copydoc RooAbsReal::chi2FitTo(RooDataSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
4253
4255{
4256 return RooFit::makeOwningPtr(RooFit::FitHelpers::fitTo(*this, xydata, cmdList, true));
4257}
4258
4259
4260
4261
4262////////////////////////////////////////////////////////////////////////////////
4263/// Create a \f$ \chi^2 \f$ from a series of x and y values stored in a dataset.
4264/// The y values can either be the event weights (default), or can be another column designated
4265/// by the YVar() argument. The y value must have errors defined for the \f$ \chi^2 \f$ to
4266/// be well defined.
4267///
4268/// The following named arguments are supported
4269///
4270/// | | Options to control construction of the \f$ \chi^2 \f$
4271/// |-|-----------------------------------------
4272/// | `YVar(RooRealVar& yvar)` | Designate given column in dataset as Y value
4273/// | `Integrate(bool flag)` | Integrate function over range specified by X errors rather than take value at bin center.
4274///
4275
4277 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
4278 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
4279{
4281 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
4282 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
4283 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
4284 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
4285 return createChi2(data,l) ;
4286}
4287
4288
4289////////////////////////////////////////////////////////////////////////////////
4290/// See RooAbsReal::createChi2(RooDataSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
4291
4293{
4294 return RooFit::makeOwningPtr(RooFit::FitHelpers::createChi2(*this, data, cmdList));
4295}
4296
4297
4298
4299////////////////////////////////////////////////////////////////////////////////
4300/// Return current evaluation error logging mode.
4301
4303{
4304 return evalErrorData().mode ;
4305}
4306
4307////////////////////////////////////////////////////////////////////////////////
4308/// Set evaluation error logging mode. Options are
4309///
4310/// PrintErrors - Print each error through RooMsgService() as it occurs
4311/// CollectErrors - Accumulate errors, but do not print them. A subsequent call
4312/// to printEvalErrors() will print a summary
4313/// CountErrors - Accumulate error count, but do not print them.
4314///
4315
4317{
4318 evalErrorData().mode = m;
4319}
4320
4321
4322////////////////////////////////////////////////////////////////////////////////
4323
4325{
4326 std::string plist ;
4327 for (auto const* arg : paramVars) {
4328 if (!dependsOnValue(*arg)) {
4329 coutW(InputArguments) << "RooAbsReal::setParameterizeIntegral(" << GetName()
4330 << ") function does not depend on listed parameter " << arg->GetName() << ", ignoring" << std::endl ;
4331 continue ;
4332 }
4333 if (!plist.empty()) plist += ":" ;
4334 plist += arg->GetName() ;
4335 }
4336 setStringAttribute("CACHEPARAMINT",plist.c_str()) ;
4337}
4338
4339
4340/** Base function for computing multiple values of a RooAbsReal.
4341\param ctx An evaluation context object
4342**/
4344{
4345 std::span<double> output = ctx.output();
4346
4347 // Find all servers that are serving real numbers to us, retrieve their batch data,
4348 // and switch them into "always clean" operating mode, so they return always the last-set value.
4349 struct ServerData {
4350 RooAbsArg* server;
4351 std::span<const double> batch;
4352 double oldValue;
4353 RooAbsArg::OperMode oldOperMode;
4354 bool oldValueDirty;
4355 bool oldShapeDirty;
4356 };
4357 std::vector<ServerData> ourServers;
4358 ourServers.reserve(servers().size());
4359
4360 for (auto server : servers()) {
4361 auto serverValues = ctx.at(server);
4362 if(serverValues.empty()) continue;
4363
4364 // maybe we are still missing inhibit dirty here
4365 auto oldOperMode = server->operMode();
4366 // See note at the bottom of this function to learn why we can only set
4367 // the operation mode to "always clean" if there are no other value
4368 // clients.
4369 server->setOperMode(RooAbsArg::AClean);
4370 ourServers.push_back({server,
4371 serverValues,
4372 server->isCategory() ? static_cast<RooAbsCategory const*>(server)->getCurrentIndex() : static_cast<RooAbsReal const*>(server)->_value,
4373 oldOperMode,
4374 server->_valueDirty,
4375 server->_shapeDirty});
4376 // Prevent the server from evaluating; just return cached result, which we will side load:
4377 }
4378
4379
4380 // Make sure that we restore all state when we finish:
4381 struct RestoreStateRAII {
4382 RestoreStateRAII(std::vector<ServerData>& servers) :
4383 _servers{servers} { }
4384
4385 ~RestoreStateRAII() {
4386 for (auto& serverData : _servers) {
4387 serverData.server->setCachedValue(serverData.oldValue, true);
4388 serverData.server->setOperMode(serverData.oldOperMode);
4389 serverData.server->_valueDirty = serverData.oldValueDirty;
4390 serverData.server->_shapeDirty = serverData.oldShapeDirty;
4391 }
4392 }
4393
4394 std::vector<ServerData>& _servers;
4395 } restoreState{ourServers};
4396
4397
4398 // Advising to implement the batch interface makes only sense if the batch was not a scalar.
4399 // Otherwise, there would be no speedup benefit.
4401 coutI(FastEvaluations) << "The class " << ClassName() << " does not implement the faster batch evaluation interface."
4402 << " Consider requesting or implementing it to benefit from a speed up." << std::endl;
4403 }
4404
4405
4406 // For each event, write temporary values into our servers' caches, and run a single-value computation.
4407
4408 for (std::size_t i=0; i < output.size(); ++i) {
4409 for (auto& serv : ourServers) {
4410 serv.server->setCachedValue(serv.batch[std::min(i, serv.batch.size()-1)], false);
4411 }
4412
4413 output[i] = evaluate();
4414 }
4415}
4416
4417////////////////////////////////////////////////////////////////////////////////
4418/// This function defines the analytical integral translation for the class.
4419///
4420/// \param[in] code The code that decides the integrands.
4421/// \param[in] rangeName Name of the normalization range.
4422/// \param[in] ctx An object to manage auxiliary information for code-squashing.
4423///
4424/// \returns The representative code string of the integral for the given object.
4425std::string RooAbsReal::buildCallToAnalyticIntegral(Int_t /* code */, const char * /* rangeName */,
4426 RooFit::Detail::CodeSquashContext & /*ctx*/) const
4427{
4428 std::stringstream errorMsg;
4429 errorMsg << "An analytical integral function for class \"" << ClassName() << "\" has not yet been implemented.";
4430 coutE(Minimization) << errorMsg.str() << std::endl;
4431 throw std::runtime_error(errorMsg.str().c_str());
4432}
4433
4434double RooAbsReal::_DEBUG_getVal(const RooArgSet* normalisationSet) const {
4435
4436 const bool tmpFast = _fast;
4437 const double tmp = _value;
4438
4439 double fullEval = 0.;
4440 try {
4441 fullEval = getValV(normalisationSet);
4442 }
4443 catch (CachingError& error) {
4444 throw CachingError(std::move(error),
4445 FormatPdfTree() << *this);
4446 }
4447
4448 const double ret = (_fast && !_inhibitDirty) ? _value : fullEval;
4449
4450 if (std::isfinite(ret) && ( ret != 0. ? (ret - fullEval)/ret : ret - fullEval) > 1.E-9) {
4451#ifndef NDEBUG
4453#endif
4454 FormatPdfTree formatter;
4455 formatter << "--> (Scalar computation wrong here:)\n"
4456 << GetName() << " " << this << " _fast=" << tmpFast
4457 << "\n\tcached _value=" << std::setprecision(16) << tmp
4458 << "\n\treturning =" << ret
4459 << "\n\trecomputed =" << fullEval
4460 << "\n\tnew _value =" << _value << "] ";
4461 formatter << "\nServers:";
4462 for (const auto server : _serverList) {
4463 formatter << "\n ";
4464 server->printStream(formatter.stream(), kName | kClassName | kArgs | kExtras | kAddress | kValue, kInline);
4465 }
4466
4467 throw CachingError(formatter);
4468 }
4469
4470 return ret;
4471}
4472
4473
4474bool RooAbsReal::redirectServersHook(const RooAbsCollection & newServerList, bool mustReplaceAll,
4475 bool nameChange, bool isRecursiveStep)
4476{
4478 return RooAbsArg::redirectServersHook(newServerList, mustReplaceAll, nameChange, isRecursiveStep);
4479}
4480
4481
4482////////////////////////////////////////////////////////////////////////////////
4483
4485{
4486 for (RooAbsArg* arg : servers()) {
4487 if(auto realArg = dynamic_cast<RooAbsReal*>(arg)) {
4488 realArg->enableOffsetting(flag) ;
4489 }
4490 }
4491}
4492
4493
4494RooAbsReal::Ref::Ref(double val) : _ref{RooFit::RooConst(val)} {}
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define coutI(a)
#define cxcoutD(a)
#define coutW(a)
#define ccoutP(a)
#define dologD(a)
#define coutF(a)
#define oocoutE(o, a)
#define coutE(a)
#define ccoutW(a)
#define ccoutD(a)
int Int_t
Definition RtypesCore.h:45
float Size_t
Definition RtypesCore.h:89
char Text_t
Definition RtypesCore.h:62
#define ClassImp(name)
Definition Rtypes.h:382
static void indent(ostringstream &buf, int indent_level)
winID h TVirtualViewer3D TVirtualGLPainter p
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 char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t format
char name[80]
Definition TGX11.cxx:110
float xmin
float ymin
float xmax
float ymax
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
R__EXTERN TSystem * gSystem
Definition TSystem.h:561
std::ostream & stream()
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:79
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.
bool recursiveRedirectServers(const RooAbsCollection &newServerList, bool mustReplaceAll=false, bool nameChange=false, bool recurseInNewSet=true)
Recursively replace all servers with the new servers in newSet.
const TNamed * namePtr() const
De-duplicated pointer to this object's name.
Definition RooAbsArg.h:535
R__DEPRECATED(6, 36, "Use getObservables().") RooFit R__DEPRECATED(6, 36, "Use getObservables().") RooFit R__DEPRECATED(6, 36, "Use getObservables().") RooFit const RooAbsArg &testArg const
Definition RooAbsArg.h:145
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition RooAbsArg.h:467
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
bool isValueDirtyAndClear() const
Definition RooAbsArg.h:408
bool _fast
Definition RooAbsArg.h:689
RooFit::OwningPtr< 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...
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
RooFit::OwningPtr< RooArgSet > getComponents() const
Create a RooArgSet with all components (branch nodes) of the expression tree headed by this object.
const RefCountList_t & servers() const
List of all servers of this object.
Definition RooAbsArg.h:180
bool dependsOnValue(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr) const
Check whether this object depends on values from an element in the serverList.
Definition RooAbsArg.h:108
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition RooAbsArg.h:462
RooFit::OwningPtr< RooArgSet > getVariables(bool stripDisconnected=true) const
Return RooArgSet with all variables (tree leaf nodes of expression tree)
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Implement multi-line detailed printing.
virtual RooAbsArg * cloneTree(const char *newname=nullptr) const
Clone tree expression of objects.
TString cleanBranchName() const
Construct a mangled name from the actual name that is free of any math symbols that might be interpre...
Int_t numProxies() const
Return the number of registered proxies.
static bool _inhibitDirty
Definition RooAbsArg.h:668
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
void setProxyNormSet(const RooArgSet *nset)
Forward a change in the cached normalization argset to all the registered proxies.
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.
RooAbsProxy * getProxy(Int_t index) const
Return the nth proxy from the proxy list.
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Definition RooAbsArg.h:91
RefCountList_t _serverList
Definition RooAbsArg.h:606
void leafNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=nullptr, bool recurseNonDerived=false) const
Fill supplied list with all leaf nodes of the arg tree, starting with ourself as top node.
virtual bool isFundamental() const
Is this object a fundamental type that can be added to a dataset? Fundamental-type subclasses overrid...
Definition RooAbsArg.h:223
virtual bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep)
Function that is called at the end of redirectServers().
virtual bool checkObservables(const RooArgSet *nset) const
Overloadable function in which derived classes can implement consistency checks of the variables.
void treeNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=nullptr, bool doBranch=true, bool doLeaf=true, bool valueOnly=false, bool recurseNonDerived=false) const
Fill supplied list with nodes of the arg tree, following all server links, starting with ourself as t...
Abstract base class for RooRealVar binning definitions.
virtual bool isParameterized() const
Interface function.
virtual RooAbsReal * highBoundFunc() const
Return pointer to RooAbsReal parameterized upper bound, if any.
virtual RooAbsReal * lowBoundFunc() const
Return pointer to RooAbsReal parameterized lower bound, if any.
Abstract base class for objects that represent a discrete value that can be set from the outside,...
virtual bool setIndex(value_type index, bool printError=true)=0
Change category state by specifying the index code of the desired state.
A space to attach TBranches.
virtual value_type getCurrentIndex() const
Return index number of current state.
bool isSignType(bool mustHaveZero=false) const
Determine if category has 2 or 3 states with index values -1,0,1.
Abstract container object that can hold multiple RooAbsArg objects.
RooFit::UniqueId< RooAbsCollection > const & uniqueId() const
Returns a unique ID that is different for every instantiated RooAbsCollection.
virtual void removeAll()
Remove all arguments from our set, deleting them if we own them.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
const char * GetName() const override
Returns name of object.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
bool overlaps(Iterator_t otherCollBegin, Iterator_t otherCollEnd) const
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...
Storage_t::size_type size() const
RooAbsArg * first() const
virtual bool replace(const RooAbsArg &var1, const RooAbsArg &var2)
Replace var1 with var2 and return true for success.
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
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.
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:57
virtual const RooArgSet * get() const
Definition RooAbsData.h:101
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Abstract interface for evaluating a real-valued function of one real variable and performing numerica...
Definition RooAbsFunc.h:27
virtual double getMaxLimit(UInt_t dimension) const =0
virtual double operator()(const double xvector[]) const =0
virtual double getMinLimit(UInt_t dimension) const =0
Abstract base class for objects that are lvalues, i.e.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
virtual double expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
static TClass * Class()
@ CanNotBeExtended
Definition RooAbsPdf.h:212
const char * normRange() const
Definition RooAbsPdf.h:250
RooFit::OwningPtr< RooDataSet > generate(const RooArgSet &whatVars, Int_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={})
See RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,...
Definition RooAbsPdf.h:57
virtual ExtendMode extendMode() const
Returns ability of PDF to provide extended likelihood terms.
Definition RooAbsPdf.h:216
Abstract interface for proxy classes.
Definition RooAbsProxy.h:37
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
TH1 * createHistogram(const char *name, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
void setServerValues(const char *tmp)
Definition RooAbsReal.h:312
void setMessage(const char *tmp)
Definition RooAbsReal.h:311
Ref(RooAbsReal &ref)
Definition RooAbsReal.h:70
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
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.
virtual void selectNormalizationRange(const char *rangeName=nullptr, bool force=false)
Interface function to force use of a given normalization range to interpret function value.
void plotOnCompSelect(RooArgSet *selNodes) const
Helper function for plotting of composite p.d.fs.
bool isSelectedComp() const
If true, the current pdf is a selected component (for use in plotting)
virtual std::list< double > * binBoundaries(RooAbsRealLValue &obs, double xlo, double xhi) const
Retrieve bin boundaries if this distribution is binned in obs.
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create an object that represents the integral of the function over one or more observables listed in ...
void selectComp(bool flag)
Definition RooAbsReal.h:377
TString _label
Plot label for objects value.
Definition RooAbsReal.h:538
bool _selectComp
A buffer for reading values from trees.
Definition RooAbsReal.h:542
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
double findRoot(RooRealVar &x, double xmin, double xmax, double yval)
Return value of x (in range xmin,xmax) at which function equals yval.
TreeReadBuffer * _treeReadBuffer
Definition RooAbsReal.h:541
virtual double getValV(const RooArgSet *normalisationSet=nullptr) const
Return value of object.
static Int_t numEvalErrorItems()
RooAbsReal()
coverity[UNINIT_CTOR] Default constructor
friend class RooRealBinding
Definition RooAbsReal.h:401
virtual void fixAddCoefNormalization(const RooArgSet &addNormSet=RooArgSet(), bool force=true)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=nullptr) const
Variant of getAnalyticalIntegral that is also passed the normalization set that should be applied to ...
bool _forceNumInt
Force numerical integration if flag set.
Definition RooAbsReal.h:539
~RooAbsReal() override
Destructor.
void setParameterizeIntegral(const RooArgSet &paramVars)
bool matchArgsByName(const RooArgSet &allArgs, RooArgSet &matchedArgs, const TList &nameList) const
Check if allArgs contains matching elements for each name in nameList.
static bool hideOffset()
void setTreeBranchStatus(TTree &t, bool active) override
(De)Activate associated tree branch
TH1 * fillHistogram(TH1 *hist, const RooArgList &plotVars, double scaleFactor=1, const RooArgSet *projectedVars=nullptr, bool scaling=true, const RooArgSet *condObs=nullptr, bool setError=true) const
Fill the ROOT histogram 'hist' with values sampled from this function at the bin centers.
RooFit::OwningPtr< RooAbsReal > createScanRI(const RooArgSet &iset, const RooArgSet &nset, Int_t numScanBins, Int_t intOrder)
Utility function for createRunningIntegral that construct an object implementing the numeric scanning...
double _DEBUG_getVal(const RooArgSet *normalisationSet) const
Debug version of getVal(), which is slow and does error checking.
RooFit::OwningPtr< RooAbsArg > createFundamental(const char *newname=nullptr) const override
Create a RooRealVar fundamental object with our properties.
bool plotSanityChecks(RooPlot *frame) const
Utility function for plotOn(), perform general sanity check on frame to ensure safe plotting operatio...
RooFit::OwningPtr< RooAbsFunc > bindVars(const RooArgSet &vars, const RooArgSet *nset=nullptr, bool clipInvalid=false) const
Create an interface adaptor f(vars) that binds us to the specified variables (in arbitrary order).
virtual void selectNormalization(const RooArgSet *depSet=nullptr, bool force=false)
Interface function to force use of a given set of observables to interpret function value.
RooDerivative * derivative(RooRealVar &obs, Int_t order=1, double eps=0.001)
Return function representing first, second or third order derivative of this function.
virtual RooFit::OwningPtr< RooFitResult > chi2FitTo(RooDataHist &data, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={})
Perform a fit to given histogram.
TF1 * asTF(const RooArgList &obs, const RooArgList &pars=RooArgList(), const RooArgSet &nset=RooArgSet()) const
Return a ROOT TF1,2,3 object bound to this RooAbsReal with given definition of observables and parame...
TString _unit
Unit for objects value.
Definition RooAbsReal.h:537
static RooNumIntConfig * defaultIntegratorConfig()
Returns the default numeric integration configuration for all RooAbsReals.
bool readFromStream(std::istream &is, bool compact, bool verbose=false) override
Read object contents from stream (dummy for now)
bool matchArgs(const RooArgSet &allDeps, RooArgSet &numDeps, const RooArgProxy &a) const
Utility function for use in getAnalyticalIntegral().
void fillTreeBranch(TTree &t) override
Fill the tree branch that associated with this object with its current value.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Structure printing.
virtual RooPlot * plotAsymOn(RooPlot *frame, const RooAbsCategoryLValue &asymCat, PlotOpt o) const
bool operator==(double value) const
Equality operator comparing to a double.
static ErrorLoggingMode evalErrorLoggingMode()
Return current evaluation error logging mode.
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
Function that is called at the end of redirectServers().
virtual bool isValidReal(double, bool printError=false) const
Interface function to check if given value is a valid value for this object. Returns true unless over...
Definition RooAbsReal.h:447
void setIntegratorConfig()
Remove the specialized numeric integration configuration associated with this object.
void printValue(std::ostream &os) const override
Print object value.
bool isIdentical(const RooAbsArg &other, bool assumeSameType=false) const override
virtual RooFit::OwningPtr< RooAbsReal > createProfile(const RooArgSet &paramsOfInterest)
Create a RooProfileLL object that eliminates all nuisance parameters in the present function.
static bool _hideOffset
Offset hiding flag.
Definition RooAbsReal.h:546
void attachToVStore(RooVectorDataStore &vstore) override
void copyCache(const RooAbsArg *source, bool valueOnly=false, bool setValDirty=true) override
Copy the cached value of another RooAbsArg to our cache.
TH1 * createHistogram(RooStringView varNameList, Int_t xbins=0, Int_t ybins=0, Int_t zbins=0) const
Create and fill a ROOT histogram TH1, TH2 or TH3 with the values of this function for the variables w...
virtual void fixAddCoefRange(const char *rangeName=nullptr, bool force=true)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
double _value
Cache for current value of object.
Definition RooAbsReal.h:536
virtual double analyticalIntegral(Int_t code, const char *rangeName=nullptr) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
void attachToTree(TTree &t, Int_t bufSize=32000) override
Attach object to a branch of given TTree.
RooNumIntConfig * specialIntegratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
void writeToStream(std::ostream &os, bool compact) const override
Write object contents to stream (dummy for now)
double traceEval(const RooArgSet *set) const
Calculate current value of object, with error tracing wrapper.
double getPropagatedError(const RooFitResult &fr, const RooArgSet &nset={}) const
Propagates parameter uncertainties to an uncertainty estimate for this RooAbsReal.
static void setHideOffset(bool flag)
static void globalSelectComp(bool flag)
Global switch controlling the activation of the selectComp() functionality.
RooAbsMoment * moment(RooRealVar &obs, Int_t order, bool central, bool takeRoot)
Return function representing moment of function of given order.
virtual std::string buildCallToAnalyticIntegral(Int_t code, const char *rangeName, RooFit::Detail::CodeSquashContext &ctx) const
This function defines the analytical integral translation for the class.
RooPlot * plotOnWithErrorBand(RooPlot *frame, const RooFitResult &fr, double Z, const RooArgSet *params, const RooLinkedList &argList, bool method1) const
Plot function or PDF on frame with support for visualization of the uncertainty encoded in the given ...
RooFit::UniqueId< RooArgSet >::Value_t _lastNormSetId
Component selection flag for RooAbsPdf::plotCompOn.
Definition RooAbsReal.h:543
const char * getPlotLabel() const
Get the label associated with the variable.
RooFit::OwningPtr< RooAbsReal > createRunningIntegral(const RooArgSet &iset, const RooArgSet &nset={})
Calls createRunningIntegral(const RooArgSet&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&,...
std::unique_ptr< RooNumIntConfig > _specIntegratorConfig
Definition RooAbsReal.h:540
virtual Int_t getAnalyticalIntegral(RooArgSet &allVars, RooArgSet &analVars, const char *rangeName=nullptr) const
Interface function getAnalyticalIntergral advertises the analytical integrals that are supported.
static std::map< constRooAbsArg *, std::pair< std::string, std::list< RooAbsReal::EvalError > > >::iterator evalErrorIter()
static Int_t numEvalErrors()
Return the number of logged evaluation errors since the last clearing.
static void setEvalErrorLoggingMode(ErrorLoggingMode m)
Set evaluation error logging mode.
virtual void preferredObservableScanOrder(const RooArgSet &obs, RooArgSet &orderedObs) const
Interface method for function objects to indicate their preferred order of observables for scanning t...
virtual double maxVal(Int_t code) const
Return maximum value for set of observables identified by code assigned in getMaxVal.
void findInnerMostIntegration(const RooArgSet &allObs, RooArgSet &innerObs, const char *rangeName) const
Utility function for createIntObj() that aids in the construct of recursive integrals over functions ...
TString integralNameSuffix(const RooArgSet &iset, const RooArgSet *nset=nullptr, const char *rangeName=nullptr, bool omitEmpty=false) const
Construct string with unique suffix name to give to integral object that encodes integrated observabl...
virtual double evaluate() const =0
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
TString getTitle(bool appendUnit=false) const
Return this variable's title string.
void logEvalError(const char *message, const char *serverValueString=nullptr) const
Log evaluation error message.
virtual double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
const Text_t * getUnit() const
Definition RooAbsReal.h:143
const RooNumIntConfig * getIntegratorConfig() const
Return the numeric integration configuration used for this object.
static void printEvalErrors(std::ostream &os=std::cout, Int_t maxPerNode=10000000)
Print all outstanding logged evaluation error on the given ostream.
RooFit::OwningPtr< RooAbsReal > createIntRI(const RooArgSet &iset, const RooArgSet &nset={})
Utility function for createRunningIntegral.
virtual void enableOffsetting(bool)
static void clearEvalErrorLog()
Clear the stack of evaluation error messages.
RooFit::OwningPtr< RooAbsReal > createIntObj(const RooArgSet &iset, const RooArgSet *nset, const RooNumIntConfig *cfg, const char *rangeName) const
Internal utility function for createIntegral() that creates the actual integral object.
RooFunctor * functor(const RooArgList &obs, const RooArgList &pars=RooArgList(), const RooArgSet &nset=RooArgSet()) const
Return a RooFunctor object bound to this RooAbsReal with given definition of observables and paramete...
const RooAbsReal * createPlotProjection(const RooArgSet &depVars, const RooArgSet &projVars, RooArgSet *&cloneSet) const
Utility function for plotOn() that creates a projection of a function or p.d.f to be plotted on a Roo...
virtual std::list< double > * plotSamplingHint(RooAbsRealLValue &obs, double xlo, double xhi) const
Interface for returning an optional hint for initial sampling points when constructing a curve projec...
void setPlotLabel(const char *label)
Set the label associated with this variable.
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={}, const RooCmdArg &arg10={}) const
Plot (project) PDF on specified frame.
virtual void doEval(RooFit::EvalContext &) const
Base function for computing multiple values of a RooAbsReal.
void makeProjectionSet(const RooAbsArg *plotVar, const RooArgSet *allVars, RooArgSet &projectedVars, bool silent) const
Utility function for plotOn() that constructs the set of observables to project when plotting ourselv...
virtual Int_t getMaxVal(const RooArgSet &vars) const
Advertise capability to determine maximum value of function for given set of observables.
virtual RooFit::OwningPtr< RooAbsReal > createChi2(RooDataHist &data, const RooLinkedList &cmdList)
virtual double offset() const
Definition RooAbsReal.h:371
static bool _globalSelectComp
Definition RooAbsReal.h:545
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
Abstract interface for RooAbsArg proxy classes.
Definition RooArgProxy.h:24
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:154
RooArgSet * selectByName(const char *nameList, bool verbose=false) const
Use RooAbsCollection::selectByName(), but return as RooArgSet.
Definition RooArgSet.h:144
RooArgSet * selectCommon(const RooAbsCollection &refColl) const
Use RooAbsCollection::selecCommon(), but return as RooArgSet.
Definition RooArgSet.h:149
Implement the abstract 1-dimensional root finding interface using the Brent-Decker method.
bool findRoot(double &result, double xlo, double xhi, double value=0) const
Do the root finding using the Brent-Decker method.
Object to represent discrete states.
Definition RooCategory.h:28
Named container for two doubles, two integers two object points and three string pointers that can be...
Definition RooCmdArg.h:26
static const RooCmdArg & none()
Return reference to null argument.
Definition RooCmdArg.cxx:52
const char * getString(Int_t idx) const
Return string stored in slot idx.
Definition RooCmdArg.h:96
void setString(Int_t idx, const char *value)
Definition RooCmdArg.h:79
Configurable parser for RooCmdArg named arguments.
void defineMutex(const char *head, Args_t &&... tail)
Define arguments where any pair is mutually exclusive.
bool process(const RooCmdArg &arg)
Process given RooCmdArg.
bool hasProcessed(const char *cmdName) const
Return true if RooCmdArg with name 'cmdName' has been processed.
double getDouble(const char *name, double defaultValue=0.0) const
Return double property registered with name 'name'.
bool defineDouble(const char *name, const char *argName, int doubleNum, double defValue=0.0)
Define double property name 'name' mapped to double in slot 'doubleNum' in RooCmdArg with name argNam...
static void stripCmdList(RooLinkedList &cmdList, const char *cmdsToPurge)
Utility function that strips command names listed (comma separated) in cmdsToPurge from cmdList.
RooArgSet * getSet(const char *name, RooArgSet *set=nullptr) const
Return RooArgSet property registered with name 'name'.
bool defineSet(const char *name, const char *argName, int setNum, const RooArgSet *set=nullptr)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
bool ok(bool verbose) const
Return true of parsing was successful.
bool defineObject(const char *name, const char *argName, int setNum, const TObject *obj=nullptr, bool isArray=false)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
const char * getString(const char *name, const char *defaultValue="", bool convEmptyToNull=false) const
Return string property registered with name 'name'.
bool defineString(const char *name, const char *argName, int stringNum, const char *defValue="", bool appendMode=false)
Define double property name 'name' mapped to double in slot 'stringNum' in RooCmdArg with name argNam...
const RooLinkedList & getObjectList(const char *name) const
Return list of objects registered with name 'name'.
bool defineInt(const char *name, const char *argName, int intNum, int 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.
int getInt(const char *name, int defaultValue=0) const
Return integer property registered with name 'name'.
TObject * getObject(const char *name, TObject *obj=nullptr) const
Return TObject property registered with name 'name'.
One-dimensional graphical representation of a real-valued function.
Definition RooCurve.h:36
@ Extended
Definition RooCurve.h:39
@ NoWings
Definition RooCurve.h:39
@ Straight
Definition RooCurve.h:39
RooCurve * makeErrorBand(const std::vector< RooCurve * > &variations, double Z=1) const
Construct filled RooCurve represented error band that captures alpha% of the variations of the curves...
Definition RooCurve.cxx:701
static TClass * Class()
RooCustomizer is a factory class to produce clones of a prototype composite PDF object with the same ...
void setCloneBranchSet(RooArgSet &cloneBranchSet)
Releases ownership of list of cloned branch nodes.
void replaceArg(const RooAbsArg &orig, const RooAbsArg &subst)
Replace any occurrence of arg 'orig' with arg 'subst'.
RooAbsArg * build(const char *masterCatState, bool verbose=false)
Build a clone of the prototype executing all registered 'replace' rules and 'split' rules for the mas...
void setOwning(bool flag)
If flag is true, make customizer own all created components.
Container class to hold N-dimensional binned data.
Definition RooDataHist.h:40
void set(std::size_t binNumber, double weight, double wgtErr)
Set bin content of bin that was last loaded with get(std::size_t).
double binVolume(std::size_t i) const
Return bin volume of i-th bin.
const RooArgSet * get() const override
Get bin centre of current bin.
Definition RooDataHist.h:82
Container class to hold unbinned data.
Definition RooDataSet.h:33
Represents the first, second, or third order derivative of any RooAbsReal as calculated (numerically)...
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
const TMatrixDSym & covarianceMatrix() const
Return covariance matrix.
TMatrixDSym reducedCovarianceMatrix(const RooArgList &params) const
Return a reduced covariance matrix (Note that Vred is a simple sub-matrix of V, row/columns are order...
const RooArgList & floatParsFinal() const
Return list of floating parameters after fit.
RooAbsPdf * createHessePdf(const RooArgSet &params) const
Return a p.d.f that represents the fit result as a multi-variate probability densisty function on the...
A class to maintain the context for squashing of RooFit models into code.
std::span< const double > at(RooAbsArg const *arg, RooAbsArg const *caller=nullptr)
std::span< double > output()
A RooFormulaVar is a generic implementation of a real-valued object, which takes a RooArgList of serv...
Lightweight interface adaptor that exports a RooAbsPdf as a functor.
Definition RooFunctor.h:25
Graphical representation of binned data based on the TGraphAsymmErrors class.
Definition RooHist.h:29
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
void Delete(Option_t *o=nullptr) override
Remove all elements in collection and delete all elements NB: Collection does not own elements,...
virtual void Add(TObject *arg)
RooLinkedListIterImpl begin() const
TObject * FindObject(const char *name) const override
Return pointer to object with given name.
static RooMsgService & instance()
Return reference to singleton instance.
bool isActive(T self, RooFit::MsgTopic topic, RooFit::MsgLevel level)
Check if logging is active for given object/topic/RooFit::MsgLevel combination.
Holds the configuration parameters of the various numeric integrators used by RooRealIntegral.
static RooNumIntConfig & defaultConfig()
Return reference to instance of default numeric integrator configuration object.
Implementation of RooAbsBinning that constructs a binning with a range definition that depends on ext...
Plot frame and a container for graphics objects within that frame.
Definition RooPlot.h:45
void remove(const char *name=nullptr, bool deleteToo=true)
Remove object with given name, or last object added if no name is given.
Definition RooPlot.cxx:868
bool drawBefore(const char *before, const char *target)
Change the order in which our contained objects are drawn so that the target object is drawn just bef...
Definition RooPlot.cxx:906
TObject * findObject(const char *name, const TClass *tClass=nullptr) const
Find the named object in our list of items and return a pointer to it.
Definition RooPlot.cxx:942
const RooArgSet * getNormVars() const
Definition RooPlot.h:152
double GetMaximum(double maxval=FLT_MAX) const
Definition RooPlot.cxx:1272
TAttLine * getAttLine(const char *name=nullptr) const
Return a pointer to the line attributes of the named object in this plot, or zero if the named object...
Definition RooPlot.cxx:807
Stat_t numItems() const
Definition RooPlot.h:119
TAttFill * getAttFill(const char *name=nullptr) const
Return a pointer to the fill attributes of the named object in this plot, or zero if the named object...
Definition RooPlot.cxx:817
TObject * getObject(Int_t idx) const
Return the name of the object at slot 'idx' in this RooPlot.
Definition RooPlot.cxx:791
RooAbsRealLValue * getPlotVar() const
Definition RooPlot.h:143
TAttMarker * getAttMarker(const char *name=nullptr) const
Return a pointer to the marker attributes of the named object in this plot, or zero if the named obje...
Definition RooPlot.cxx:827
TAxis * GetXaxis() const
Definition RooPlot.cxx:1262
RooCurve * getCurve(const char *name=nullptr) const
Return a RooCurve pointer of the named object in this plot, or zero if the named object does not exis...
Definition RooPlot.cxx:848
SetMaximum(ymax)
Int_t GetNbinsX() const
Definition RooPlot.cxx:1266
SetMinimum(ymin)
void addPlotable(RooPlotable *plotable, Option_t *drawOptions="", bool invisible=false, bool refreshNorm=false)
Add the specified plotable object to our plot.
Definition RooPlot.cxx:516
double GetMinimum(double minval=-FLT_MAX) const
Definition RooPlot.cxx:1270
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,...
Performs hybrid numerical/analytical integrals of RooAbsReal objects.
const RooArgSet & numIntRealVars() const
void setAllowComponentSelection(bool allow)
Set component selection to be allowed/forbidden.
static TClass * Class()
Variable that can be changed from the outside.
Definition RooRealVar.h:37
void setVal(double value) override
Set value of variable to 'value'.
void setBinning(const RooAbsBinning &binning, const char *name=nullptr)
Add given binning under name 'name' with this variable.
void setBins(Int_t nBins, const char *name=nullptr)
Create a uniform binning under name 'name' for this variable.
The RooStringView is a wrapper around a C-style string that can also be constructed from a std::strin...
void setBuffer(RooAbsReal *real, double *newBuf)
Uses std::vector to store data columns.
RealVector * addReal(RooAbsReal *real)
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
Definition TAttFill.h:37
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition TAttFill.h:39
Line Attributes class.
Definition TAttLine.h:18
virtual void SetLineStyle(Style_t lstyle)
Set the line style.
Definition TAttLine.h:42
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
Definition TAttLine.h:43
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition TAttLine.h:40
virtual void SetMarkerColor(Color_t mcolor=1)
Set the marker color.
Definition TAttMarker.h:38
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:40
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition TAttMarker.h:45
Class to manage histogram axis.
Definition TAxis.h:31
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
Double_t GetXmax() const
Definition TAxis.h:140
Double_t GetXmin() const
Definition TAxis.h:139
A TTree is a list of TBranches.
Definition TBranch.h:93
TObjArray * GetListOfLeaves()
Definition TBranch.h:247
Int_t Fill()
Definition TBranch.h:205
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
1-Dim function class
Definition TF1.h:233
virtual void SetParName(Int_t ipar, const char *name)
Set name of parameter number ipar.
Definition TF1.cxx:3450
virtual void SetParameter(Int_t param, Double_t value)
Definition TF1.h:667
A 2-Dim function with parameters.
Definition TF2.h:29
A 3-Dim function with parameters.
Definition TF3.h:28
void SetName(const char *name="") override
Set graph name.
Definition TGraph.cxx:2381
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
TAxis * GetZaxis()
Definition TH1.h:326
virtual Int_t GetNbinsY() const
Definition TH1.h:298
virtual Int_t GetNbinsZ() const
Definition TH1.h:299
virtual Int_t GetDimension() const
Definition TH1.h:283
TAxis * GetXaxis()
Definition TH1.h:324
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition TH1.cxx:4982
virtual Int_t GetNbinsX() const
Definition TH1.h:297
virtual void SetBinError(Int_t bin, Double_t error)
Set the bin Error Note that this resets the bin eror option to be of Normal Type and for the non-empt...
Definition TH1.cxx:9227
TAxis * GetYaxis()
Definition TH1.h:325
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition TH1.cxx:9243
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
virtual const char * GetTypeName() const
Definition TLeaf.h:139
virtual TLeaf * GetLeafCounter(Int_t &countval) const
Return a pointer to the counter of this leaf (if any) or store the number of elements that the leaf c...
Definition TLeaf.cxx:249
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
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
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:444
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:213
Basic string class.
Definition TString.h:139
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:457
const char * Data() const
Definition TString.h:376
TString & Prepend(const char *cs)
Definition TString.h:673
Bool_t IsNull() const
Definition TString.h:414
TString & Append(const char *cs)
Definition TString.h:572
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:734
A TTree represents a columnar dataset.
Definition TTree.h:79
virtual void SetBranchStatus(const char *bname, bool status=true, UInt_t *found=nullptr)
Set branch status to Process or DoNotProcess.
Definition TTree.cxx:8534
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5294
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=nullptr)
Change branch address, dealing with clone trees properly.
Definition TTree.cxx:8385
TBranch * Branch(const char *name, T *obj, Int_t bufsize=32000, Int_t splitlevel=99)
Add a new branch, and infer the data type from the type of obj being passed.
Definition TTree.h:353
RooCmdArg YVar(const RooAbsRealLValue &var, const RooCmdArg &arg={})
RooCmdArg ZVar(const RooAbsRealLValue &var, const RooCmdArg &arg={})
RooCmdArg SupNormSet(const RooArgSet &nset)
RooCmdArg Binning(const RooAbsBinning &binning)
RooCmdArg NormRange(const char *rangeNameList)
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
#define F(x, y, z)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
std::unique_ptr< T > compileForNormSet(T const &arg, RooArgSet const &normSet)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition JSONIO.h:26
@ FastEvaluations
OwningPtr< T > makeOwningPtr(std::unique_ptr< T > &&ptr)
Internal helper to turn a std::unique_ptr<T> into an OwningPtr.
Definition Config.h:40
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
Definition Config.h:35
RooArgSet selectFromArgSet(RooArgSet const &, std::string const &names)
bool checkIfRangesOverlap(RooArgSet const &observables, std::vector< std::string > const &rangeNames)
std::string getColonSeparatedNameString(RooArgSet const &argSet, char delim=':')
Bool_t IsNaN(Double_t x)
Definition TMath.h:892
Double_t Erfc(Double_t x)
Computes the complementary error function erfc(x).
Definition TMath.cxx:199
Definition graph.py:1
RooCurve::WingMode wmode
Definition RooAbsReal.h:477
const char * normRangeName
Definition RooAbsReal.h:473
RooFit::MPSplit interleave
Definition RooAbsReal.h:485
const char * projectionRangeName
Definition RooAbsReal.h:478
const RooArgSet * projDataSet
Definition RooAbsReal.h:472
const char * curveNameSuffix
Definition RooAbsReal.h:486
const char * addToCurveName
Definition RooAbsReal.h:481
const RooFitResult * errorFR
Definition RooAbsReal.h:491
const RooArgSet * projSet
Definition RooAbsReal.h:469
const char * curveName
Definition RooAbsReal.h:480
const RooAbsData * projData
Definition RooAbsReal.h:467
Option_t * drawOptions
Definition RooAbsReal.h:464
A UniqueId can be added as a class member to enhance any class with a unique identifier for each inst...
Definition UniqueId.h:39
constexpr Value_t value() const
Return numerical value of ID.
Definition UniqueId.h:59
TMarker m
Definition textangle.C:8
TLine l
Definition textangle.C:4
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345
static void output()