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