Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
RooAbsReal.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17//////////////////////////////////////////////////////////////////////////////
18
19/** \class RooAbsReal
20
21 Abstract base class for objects that represent a
22 real value and implements functionality common to all real-valued objects
23 such as the ability to plot them, to construct integrals of them, the
24 ability to advertise (partial) analytical integrals etc.
25
26 Implementation of RooAbsReal may be derived, thus no interface
27 is provided to modify the contents.
28
29 \ingroup Roofitcore
30*/
31
32#include "RooAbsReal.h"
33
34#include "FitHelpers.h"
36#include "RooAbsData.h"
37#include "RooAddPdf.h"
38#include "RooAddition.h"
39#include "RooArgList.h"
40#include "RooArgProxy.h"
41#include "RooArgSet.h"
42#include "RooBinning.h"
43#include "RooBrentRootFinder.h"
44#include "RooCachedReal.h"
45#include "RooCategory.h"
46#include "RooCmdConfig.h"
47#include "RooConstVar.h"
48#include "RooCurve.h"
49#include "RooCustomizer.h"
50#include "RooDataHist.h"
51#include "RooDataSet.h"
52#include "RooDerivative.h"
53#include "RooFirstMoment.h"
55#include "RooFit/Evaluator.h"
56#include "RooFitResult.h"
57#include "RooFormulaVar.h"
58#include "RooFunctor.h"
59#include "RooGlobalFunc.h"
60#include "RooFitImplHelpers.h"
61#include "RooHist.h"
62#include "RooMoment.h"
63#include "RooMsgService.h"
64#include "RooNumIntConfig.h"
65#include "RooNumRunningInt.h"
66#include "RooParamBinning.h"
67#include "RooPlot.h"
68#include "RooProduct.h"
69#include "RooProfileLL.h"
70#include "RooRealBinding.h"
71#include "RooRealIntegral.h"
72#include "RooRealVar.h"
73#include "RooSecondMoment.h"
74#include "RooVectorDataStore.h"
75#include "TreeReadBuffer.h"
76#include "ValueChecking.h"
77
78#include "ROOT/StringUtils.hxx"
79#include "Compression.h"
80#include "Math/IFunction.h"
81#include "TMath.h"
82#include "TObjString.h"
83#include "TTree.h"
84#include "TH1.h"
85#include "TH2.h"
86#include "TH3.h"
87#include "TBranch.h"
88#include "TLeaf.h"
89#include "TAttLine.h"
90#include "TF1.h"
91#include "TF2.h"
92#include "TF3.h"
93#include "TMatrixD.h"
94#include "TVector.h"
95#include "strlcpy.h"
96#ifndef NDEBUG
97#include <TSystem.h> // To print stack traces when caching errors are detected
98#endif
99
100#include <iomanip>
101#include <iostream>
102#include <limits>
103#include <sstream>
104#include <sys/types.h>
105
106namespace {
107
108// Internal helper RooAbsFunc that evaluates the scaled data-weighted average of
109// given RooAbsReal as a function of a single variable using the RooFit::Evaluator.
110class ScaledDataWeightedAverage : public RooAbsFunc {
111public:
112 ScaledDataWeightedAverage(RooAbsReal const &arg, RooAbsData const &data, double scaleFactor, RooAbsRealLValue &var)
113 : RooAbsFunc{1}, _var{var}, _dataWeights{data.getWeightBatch(0, data.numEntries())}, _scaleFactor{scaleFactor}
114 {
115 _arg = RooFit::Detail::compileForNormSet(arg, *data.get());
116 _arg->recursiveRedirectServers(RooArgList{var});
117 _evaluator = std::make_unique<RooFit::Evaluator>(*_arg);
118 std::stack<std::vector<double>>{}.swap(_vectorBuffers);
119 auto dataSpans = RooFit::BatchModeDataHelpers::getDataSpans(data, "", nullptr, /*skipZeroWeights=*/false,
120 /*takeGlobalObservablesFromData=*/true,
121 _vectorBuffers);
122 for (auto const& item : dataSpans) {
123 _evaluator->setInput(item.first->GetName(), item.second, false);
124 }
125 }
126
127 double operator()(const double xvector[]) const override
128 {
129 double oldVal = _var.getVal();
130 _var.setVal(xvector[0]);
131
132 double out = 0.0;
133 std::span<const double> pdfValues = _evaluator->run();
134 if (_dataWeights.empty()) {
135 pdfValues.size();
136 } else {
137 double weightsSum = 0.0;
138 for (std::size_t i = 0; i < pdfValues.size(); ++i) {
139 pdfValues[i] * _dataWeights[i];
140 weightsSum += _dataWeights[i];
141 }
142 weightsSum;
143 }
144 out *= _scaleFactor;
145
146 _var.setVal(oldVal);
147 return out;
148 }
149 double getMinLimit(UInt_t /*dimension*/) const override { return _var.getMin(); }
150 double getMaxLimit(UInt_t /*dimension*/) const override { return _var.getMax(); }
151
152private:
153 RooAbsRealLValue &_var;
154 std::unique_ptr<RooAbsReal> _arg;
155 std::span<const double> _dataWeights;
156 double _scaleFactor;
157 std::unique_ptr<RooFit::Evaluator> _evaluator;
158 std::stack<std::vector<double>> _vectorBuffers;
159};
160
161struct EvalErrorData {
162 using ErrorList = std::map<const RooAbsArg *, std::pair<std::string, std::list<RooAbsReal::EvalError>>>;
164 int count = 0;
165 ErrorList errorList;
166};
167
168EvalErrorData &evalErrorData()
169{
170 static EvalErrorData data;
171 return data;
172}
173
174} // namespace
175
177{
178 return evalErrorData().errorList.size();
179}
180
181EvalErrorData::ErrorList::iterator RooAbsReal::evalErrorIter()
182{
183 return evalErrorData().errorList.begin();
184}
185
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
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
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
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();
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 // fall through to next case...
1020 case 2:
1021 ybins= hist->GetNbinsY();
1022 yvar= dynamic_cast<RooRealVar*>(plotClones.find(plotVars.at(1)->GetName()));
1023 yaxis= hist->GetYaxis();
1024 assert(nullptr != yvar && nullptr != yaxis);
1025 // fall through to next case...
1026 case 1:
1027 xbins= hist->GetNbinsX();
1028 xvar= dynamic_cast<RooRealVar*>(plotClones.find(plotVars.at(0)->GetName()));
1029 xaxis= hist->GetXaxis();
1030 assert(nullptr != xvar && nullptr != xaxis);
1031 break;
1032 default:
1033 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillHistogram: cannot fill histogram with "
1034 << hdim << " dimensions" << std::endl;
1035 break;
1036 }
1037
1038 // Loop over the input histogram's bins and fill each one with our projection's
1039 // value, calculated at the center.
1041 Int_t xbin(0);
1042 Int_t ybin(0);
1043 Int_t zbin(0);
1044 Int_t bins= xbins*ybins*zbins;
1045 for(Int_t bin= 0; bin < bins; bin++) {
1046 switch(hdim) {
1047 case 3:
1048 if(bin % (xbins*ybins) == 0) {
1049 zbin++;
1050 zvar->setVal(zaxis->GetBinCenter(zbin));
1051 }
1052 // fall through to next case...
1053 case 2:
1054 if(bin % xbins == 0) {
1055 ybin= (ybin%ybins) + 1;
1056 yvar->setVal(yaxis->GetBinCenter(ybin));
1057 }
1058 // fall through to next case...
1059 case 1:
1060 xbin= (xbin%xbins) + 1;
1061 xvar->setVal(xaxis->GetBinCenter(xbin));
1062 break;
1063 default:
1064 coutE(InputArguments) << "RooAbsReal::fillHistogram: Internal Error!" << std::endl;
1065 break;
1066 }
1067
1068 // Bin volume scaling
1069 double scaleFactorBin = scaleFactor;
1070 scaleFactorBin *= scaleForDensity && hdim > 2 ? hist->GetZaxis()->GetBinWidth(zbin) : 1.0;
1071 scaleFactorBin *= scaleForDensity && hdim > 1 ? hist->GetYaxis()->GetBinWidth(ybin) : 1.0;
1072 scaleFactorBin *= scaleForDensity && hdim > 0 ? hist->GetXaxis()->GetBinWidth(xbin) : 1.0;
1073
1074 double result= scaleFactorBin * projected->getVal();
1075 if (RooAbsReal::numEvalErrors()>0) {
1076 coutW(Plotting) << "WARNING: Function evaluation error(s) at coordinates [x]=" << xvar->getVal() ;
1077 if (hdim==2) ccoutW(Plotting) << " [y]=" << yvar->getVal() ;
1078 if (hdim==3) ccoutW(Plotting) << " [z]=" << zvar->getVal() ;
1079 ccoutW(Plotting) << std::endl ;
1080 // RooAbsReal::printEvalErrors(ccoutW(Plotting),10) ;
1081 result = 0 ;
1082 }
1084
1085 hist->SetBinContent(hist->GetBin(xbin,ybin,zbin),result);
1086 if (setError) {
1087 hist->SetBinError(hist->GetBin(xbin,ybin,zbin),sqrt(result)) ;
1088 }
1089
1090 //cout << "bin " << bin << " -> (" << xbin << "," << ybin << "," << zbin << ") = " << result << std::endl;
1091 }
1093
1094 // cleanup
1095 delete cloneSet;
1096
1097 return hist;
1098}
1099
1100
1101
1102////////////////////////////////////////////////////////////////////////////////
1103/// Fill a RooDataHist with values sampled from this function at the
1104/// bin centers. If extendedMode is true, the p.d.f. values is multiplied
1105/// by the number of expected events in each bin
1106///
1107/// An optional scaling by a given scaleFactor can be performed.
1108/// Returns a pointer to the input RooDataHist, or zero
1109/// in case of an error.
1110///
1111/// If correctForBinSize is true the RooDataHist
1112/// is filled with the functions density (function value times the
1113/// bin volume) rather than function value.
1114///
1115/// If showProgress is true
1116/// a process indicator is printed on stdout in steps of one percent,
1117/// which is mostly useful for the sampling of expensive functions
1118/// such as likelihoods
1119
1121 bool correctForBinSize, bool showProgress) const
1122{
1123 // Do we have a valid histogram to use?
1124 if(nullptr == hist) {
1125 coutE(InputArguments) << ClassName() << "::" << GetName() << ":fillDataHist: no valid RooDataHist to fill" << std::endl;
1126 return nullptr;
1127 }
1128
1129 // Call checkObservables
1130 RooArgSet allDeps(*hist->get()) ;
1131 if (checkObservables(&allDeps)) {
1132 coutE(InputArguments) << "RooAbsReal::fillDataHist(" << GetName() << ") error in checkObservables, abort" << std::endl ;
1133 return hist ;
1134 }
1135
1136 // Make deep clone of self and attach to dataset observables
1137 //RooArgSet* origObs = getObservables(hist) ;
1139 RooArgSet(*this).snapshot(cloneSet, true);
1140 RooAbsReal* theClone = static_cast<RooAbsReal*>(cloneSet.find(GetName()));
1141 theClone->recursiveRedirectServers(*hist->get()) ;
1142 //const_cast<RooAbsReal*>(this)->recursiveRedirectServers(*hist->get()) ;
1143
1144 // Iterator over all bins of RooDataHist and fill weights
1145 Int_t onePct = hist->numEntries()/100 ;
1146 if (onePct==0) {
1147 onePct++ ;
1148 }
1149 for (Int_t i=0 ; i<hist->numEntries() ; i++) {
1150 if (showProgress && (i%onePct==0)) {
1151 ccoutP(Eval) << "." << std::flush ;
1152 }
1153 const RooArgSet* obs = hist->get(i) ;
1154 double binVal = theClone->getVal(normSet?normSet:obs)*scaleFactor ;
1155 if (correctForBinSize) {
1156 binVal*= hist->binVolume() ;
1157 }
1158 hist->set(i, binVal, 0.);
1159 }
1160
1161 return hist;
1162}
1163
1164
1165
1166
1167////////////////////////////////////////////////////////////////////////////////
1168/// Create and fill a ROOT histogram TH1, TH2 or TH3 with the values of this function for the variables with given names.
1169/// \param[in] varNameList List of variables to use for x, y, z axis, separated by ':'
1170/// \param[in] xbins Number of bins for first variable
1171/// \param[in] ybins Number of bins for second variable
1172/// \param[in] zbins Number of bins for third variable
1173/// \return TH1*, which is one of TH[1-3]. The histogram is owned by the caller.
1174///
1175/// For a greater degree of control use
1176/// RooAbsReal::createHistogram(const char *, const RooAbsRealLValue&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&) const
1177///
1178
1180{
1181 std::unique_ptr<RooArgSet> vars{getVariables()};
1182
1183 auto varNames = ROOT::Split(varNameList, ",:");
1184 std::vector<RooRealVar*> histVars(3, nullptr);
1185
1186 for(std::size_t iVar = 0; iVar < varNames.size(); ++iVar) {
1187 if(varNames[iVar].empty()) continue;
1188 if(iVar >= 3) {
1189 std::stringstream errMsg;
1190 errMsg << "RooAbsPdf::createHistogram(" << GetName() << ") ERROR more than three variable names passed, but maximum number of supported variables is three";
1191 coutE(Plotting) << errMsg.str() << std::endl;
1192 throw std::invalid_argument(errMsg.str());
1193 }
1194 auto var = static_cast<RooRealVar*>(vars->find(varNames[iVar].c_str()));
1195 if(!var) {
1196 std::stringstream errMsg;
1197 errMsg << "RooAbsPdf::createHistogram(" << GetName() << ") ERROR variable " << varNames[iVar] << " does not exist in argset: " << *vars;
1198 coutE(Plotting) << errMsg.str() << std::endl;
1199 throw std::runtime_error(errMsg.str());
1200 }
1201 histVars[iVar] = var;
1202 }
1203
1204 // Construct list of named arguments to pass to the implementation version of createHistogram()
1205
1206 RooLinkedList argList ;
1207 if (xbins>0) {
1208 argList.Add(RooFit::Binning(xbins).Clone()) ;
1209 }
1210
1211 if (histVars[1]) {
1213 }
1214
1215 if (histVars[2]) {
1217 }
1218
1219 // Call implementation function
1220 TH1* result = createHistogram(GetName(), *histVars[0], argList) ;
1221
1222 // Delete temporary list of RooCmdArgs
1223 argList.Delete() ;
1224
1225 return result ;
1226}
1227
1228
1229
1230////////////////////////////////////////////////////////////////////////////////
1231/// Create and fill a ROOT histogram TH1, TH2 or TH3 with the values of this function.
1232///
1233/// \param[in] name Name of the ROOT histogram
1234/// \param[in] xvar Observable to be std::mapped on x axis of ROOT histogram
1235/// \param[in] arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8 Arguments according to list below
1236/// \return TH1 *, one of TH{1,2,3}. The caller takes ownership.
1237///
1238/// <table>
1239/// <tr><th><th> Effect on histogram creation
1240/// <tr><td> `IntrinsicBinning()` <td> Apply binning defined by function or pdf (as advertised via binBoundaries() method)
1241/// <tr><td> `Binning(const char* name)` <td> Apply binning with given name to x axis of histogram
1242/// <tr><td> `Binning(RooAbsBinning& binning)` <td> Apply specified binning to x axis of histogram
1243/// <tr><td> `Binning(int nbins, [double lo, double hi])` <td> Apply specified binning to x axis of histogram
1244/// <tr><td> `ConditionalObservables(Args_t &&... argsOrArgSet)` <td> Do not normalise PDF over following observables when projecting PDF into histogram.
1245// Arguments can either be multiple RooRealVar or a single RooArgSet containing them.
1246/// <tr><td> `Scaling(bool)` <td> Apply density-correction scaling (multiply by bin volume), default is true
1247/// <tr><td> `Extended(bool)` <td> Plot event yield instead of probability density (for extended pdfs only)
1248///
1249/// <tr><td> `YVar(const RooAbsRealLValue& var,...)` <td> Observable to be std::mapped on y axis of ROOT histogram.
1250/// The YVar() and ZVar() arguments can be supplied with optional Binning() arguments to control the binning of the Y and Z axes, e.g.
1251/// ```
1252/// createHistogram("histo",x,Binning(-1,1,20), YVar(y,Binning(-1,1,30)), ZVar(z,Binning("zbinning")))
1253/// ```
1254/// <tr><td> `ZVar(const RooAbsRealLValue& var,...)` <td> Observable to be std::mapped on z axis of ROOT histogram
1255/// </table>
1256///
1257///
1258
1260 const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
1261 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
1262{
1263
1265 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
1266 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
1267 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
1268 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
1269
1270 return createHistogram(name,xvar,l) ;
1271}
1272
1273
1274////////////////////////////////////////////////////////////////////////////////
1275/// Internal method implementing createHistogram
1276
1278{
1279
1280 // Define configuration for this method
1281 RooCmdConfig pc("RooAbsReal::createHistogram(" + std::string(GetName()) + ")");
1282 pc.defineInt("scaling","Scaling",0,1) ;
1283 pc.defineInt("intBinning","IntrinsicBinning",0,2) ;
1284 pc.defineInt("extended","Extended",0,2) ;
1285
1286 pc.defineSet("compSet","SelectCompSet",0);
1287 pc.defineString("compSpec","SelectCompSpec",0) ;
1288 pc.defineSet("projObs","ProjectedObservables",0,nullptr) ;
1289 pc.defineObject("yvar","YVar",0,nullptr) ;
1290 pc.defineObject("zvar","ZVar",0,nullptr) ;
1291 pc.defineMutex("SelectCompSet","SelectCompSpec") ;
1292 pc.defineMutex("IntrinsicBinning","Binning") ;
1293 pc.defineMutex("IntrinsicBinning","BinningName") ;
1294 pc.defineMutex("IntrinsicBinning","BinningSpec") ;
1295 pc.allowUndefined() ;
1296
1297 // Process & check varargs
1298 pc.process(argList) ;
1299 if (!pc.ok(true)) {
1300 return nullptr ;
1301 }
1302
1303 RooArgList vars(xvar) ;
1304 RooAbsArg* yvar = static_cast<RooAbsArg*>(pc.getObject("yvar")) ;
1305 if (yvar) {
1306 vars.add(*yvar) ;
1307 }
1308 RooAbsArg* zvar = static_cast<RooAbsArg*>(pc.getObject("zvar")) ;
1309 if (zvar) {
1310 vars.add(*zvar) ;
1311 }
1312
1313 auto projObs = pc.getSet("projObs");
1314 RooArgSet* intObs = nullptr ;
1315
1316 bool doScaling = pc.getInt("scaling") ;
1317 Int_t doIntBinning = pc.getInt("intBinning") ;
1318 Int_t doExtended = pc.getInt("extended") ;
1319
1320 // If doExtended is two, selection is automatic, set to 1 of pdf is extended, to zero otherwise
1321 const RooAbsPdf* pdfSelf = dynamic_cast<const RooAbsPdf*>(this) ;
1322 if (!pdfSelf && doExtended == 1) {
1323 coutW(InputArguments) << "RooAbsReal::createHistogram(" << GetName() << ") WARNING extended mode requested for a non-pdf object, ignored" << std::endl ;
1324 doExtended=0 ;
1325 }
1326 if (pdfSelf && doExtended==1 && pdfSelf->extendMode()==RooAbsPdf::CanNotBeExtended) {
1327 coutW(InputArguments) << "RooAbsReal::createHistogram(" << GetName() << ") WARNING extended mode requested for a non-extendable pdf, ignored" << std::endl ;
1328 doExtended=0 ;
1329 }
1330 if (pdfSelf && doExtended==2) {
1331 doExtended = pdfSelf->extendMode()==RooAbsPdf::CanNotBeExtended ? 0 : 1 ;
1332 } else if(!pdfSelf) {
1333 doExtended = 0;
1334 }
1335
1336 const char* compSpec = pc.getString("compSpec") ;
1337 const RooArgSet* compSet = pc.getSet("compSet");
1338 bool haveCompSel = ( (compSpec && strlen(compSpec)>0) || compSet) ;
1339
1340 std::unique_ptr<RooBinning> intBinning;
1341 if (doIntBinning>0) {
1342 // Given RooAbsPdf* pdf and RooRealVar* obs
1343 std::unique_ptr<std::list<double>> bl{binBoundaries(const_cast<RooAbsRealLValue&>(xvar),xvar.getMin(),xvar.getMax())};
1344 if (!bl) {
1345 // Only emit warning when intrinsic binning is explicitly requested
1346 if (doIntBinning==1) {
1347 coutW(InputArguments) << "RooAbsReal::createHistogram(" << GetName()
1348 << ") WARNING, intrinsic model binning requested for histogram, but model does not define bin boundaries, reverting to default binning"<< std::endl ;
1349 }
1350 } else {
1351 if (doIntBinning==2) {
1352 coutI(InputArguments) << "RooAbsReal::createHistogram(" << GetName()
1353 << ") INFO: Model has intrinsic binning definition, selecting that binning for the histogram"<< std::endl ;
1354 }
1355 std::vector<double> edges(bl->size());
1356 int i=0 ;
1357 for (auto const& elem : *bl) { edges[i++] = elem ; }
1358 intBinning = std::make_unique<RooBinning>(bl->size()-1,edges.data()) ;
1359 }
1360 }
1361
1362 RooLinkedList argListCreate(argList) ;
1363 RooCmdConfig::stripCmdList(argListCreate,"Scaling,ProjectedObservables,IntrinsicBinning,SelectCompSet,SelectCompSpec,Extended") ;
1364
1365 TH1* histo(nullptr) ;
1366 if (intBinning) {
1368 argListCreate.Add(&tmp) ;
1369 histo = xvar.createHistogram(name,argListCreate) ;
1370 } else {
1371 histo = xvar.createHistogram(name,argListCreate) ;
1372 }
1373
1374 // Do component selection here
1375 if (haveCompSel) {
1376
1377 // Get complete set of tree branch nodes
1380
1381 // Discard any non-RooAbsReal nodes
1382 for(RooAbsArg * arg : branchNodeSet) {
1383 if (!dynamic_cast<RooAbsReal*>(arg)) {
1384 branchNodeSet.remove(*arg) ;
1385 }
1386 }
1387
1388 std::unique_ptr<RooArgSet> dirSelNodes;
1389 if (compSet) {
1390 dirSelNodes = std::unique_ptr<RooArgSet>{branchNodeSet.selectCommon(*compSet)};
1391 } else {
1392 dirSelNodes = std::unique_ptr<RooArgSet>{branchNodeSet.selectByName(compSpec)};
1393 }
1394 if (!dirSelNodes->empty()) {
1395 coutI(Plotting) << "RooAbsPdf::createHistogram(" << GetName() << ") directly selected PDF components: " << *dirSelNodes << std::endl ;
1396
1397 // Do indirect selection and activate both
1399 } else {
1400 if (compSet) {
1401 coutE(Plotting) << "RooAbsPdf::createHistogram(" << GetName() << ") ERROR: component selection set " << *compSet << " does not match any components of p.d.f." << std::endl ;
1402 } else {
1403 coutE(Plotting) << "RooAbsPdf::createHistogram(" << GetName() << ") ERROR: component selection expression '" << compSpec << "' does not select any components of p.d.f." << std::endl ;
1404 }
1405 return nullptr ;
1406 }
1407 }
1408
1409 double scaleFactor(1.0) ;
1410 if (doExtended) {
1411 scaleFactor = pdfSelf->expectedEvents(vars);
1412 }
1413
1414 fillHistogram(histo,vars,scaleFactor,intObs,doScaling,projObs,false) ;
1415
1416 // Deactivate component selection
1417 if (haveCompSel) {
1418 plotOnCompSelect(nullptr) ;
1419 }
1420
1421
1422 return histo ;
1423}
1424
1425
1426////////////////////////////////////////////////////////////////////////////////
1427/// Helper function for plotting of composite p.d.fs. Given
1428/// a set of selected components that should be plotted,
1429/// find all nodes that (in)directly depend on these selected
1430/// nodes. Mark all directly and indirectly selected nodes
1431/// as 'selected' using the selectComp() method
1432
1434{
1435 // Get complete set of tree branch nodes
1438
1439 // Discard any non-PDF nodes
1440 // Iterate by number because collection is being modified! Iterators may invalidate ...
1441 for (unsigned int i = 0; i < branchNodeSet.size(); ++i) {
1442 const auto arg = branchNodeSet[i];
1443 if (!dynamic_cast<RooAbsReal*>(arg)) {
1444 branchNodeSet.remove(*arg) ;
1445 }
1446 }
1447
1448 // If no set is specified, restored all selection bits to true
1449 if (!selNodes) {
1450 // Reset PDF selection bits to true
1451 for (const auto arg : branchNodeSet) {
1452 static_cast<RooAbsReal*>(arg)->selectComp(true);
1453 }
1454 return ;
1455 }
1456
1457
1458 // Add all nodes below selected nodes that are value servers
1459 RooArgSet tmp;
1460 for (const auto arg : branchNodeSet) {
1461 for (const auto selNode : *selNodes) {
1462 if (selNode->dependsOn(*arg, nullptr, /*valueOnly=*/true)) {
1463 tmp.add(*arg,true);
1464 }
1465 }
1466 }
1467
1468 // Add all nodes that depend on selected nodes by value
1469 for (const auto arg : branchNodeSet) {
1470 if (arg->dependsOn(*selNodes, nullptr, /*valueOnly=*/true)) {
1471 tmp.add(*arg,true);
1472 }
1473 }
1474
1475 tmp.remove(*selNodes, true);
1476 tmp.remove(*this);
1477 selNodes->add(tmp);
1478 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") indirectly selected PDF components: " << tmp << std::endl ;
1479
1480 // Set PDF selection bits according to selNodes
1481 for (const auto arg : branchNodeSet) {
1482 bool select = selNodes->find(arg->GetName()) != nullptr;
1483 static_cast<RooAbsReal*>(arg)->selectComp(select);
1484 }
1485}
1486
1487
1488
1489////////////////////////////////////////////////////////////////////////////////
1490/// Plot (project) PDF on specified frame. If a PDF is plotted in an empty frame, it
1491/// will show a unit normalized curve in the frame variable, taken at the present value
1492/// of other observables defined for this PDF.
1493///
1494/// \param[in] frame pointer to RooPlot
1495/// \param[in] arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10 Ordered arguments
1496///
1497/// If a PDF is plotted in a frame in which a dataset has already been plotted, it will
1498/// show a projected curve integrated over all variables that were present in the shown
1499/// dataset except for the one on the x-axis. The normalization of the curve will also
1500/// be adjusted to the event count of the plotted dataset. An informational message
1501/// will be printed for each projection step that is performed.
1502///
1503/// This function takes the following named arguments
1504/// <table>
1505/// <tr><th><th> Projection control
1506/// <tr><td> `Slice(const RooArgSet& set)` <td> Override default projection behaviour by omitting observables listed
1507/// in set from the projection, i.e. by not integrating over these.
1508/// Slicing is usually only sensible in discrete observables, by e.g. creating a slice
1509/// of the PDF at the current value of the category observable.
1510///
1511/// <tr><td> `Slice(RooCategory& cat, const char* label)` <td> Override default projection behaviour by omitting the specified category
1512/// observable from the projection, i.e., by not integrating over all states of this category.
1513/// The slice is positioned at the given label value. To pass multiple Slice() commands, please use the
1514/// Slice(std::map<RooCategory*, std::string> const&) argument explained below.
1515///
1516/// <tr><td> `Slice(std::map<RooCategory*, std::string> const&)` <td> Omits multiple categories from the projection, as explianed above.
1517/// Can be used with initializer lists for convenience, e.g.
1518/// ```{.cpp}
1519/// pdf.plotOn(frame, Slice({{&tagCategory, "2tag"}, {&jetCategory, "3jet"}});
1520/// ```
1521///
1522/// <tr><td> `Project(const RooArgSet& set)` <td> Override default projection behaviour by projecting over observables
1523/// given in the set, ignoring the default projection behavior. Advanced use only.
1524///
1525/// <tr><td> `ProjWData(const RooAbsData& d)` <td> Override default projection _technique_ (integration). For observables present in given dataset
1526/// projection of PDF is achieved by constructing an average over all observable values in given set.
1527/// Consult RooFit plotting tutorial for further explanation of meaning & use of this technique
1528///
1529/// <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
1530///
1531/// <tr><td> `ProjectionRange(const char* rn)` <td> Override default range of projection integrals to a different range specified by given range name.
1532/// This technique allows you to project a finite width slice in a real-valued observable
1533///
1534/// <tr><td> `NumCPU(Int_t ncpu)` <td> Number of CPUs to use simultaneously to calculate data-weighted projections (only in combination with ProjWData)
1535///
1536///
1537/// <tr><th><th> Misc content control
1538/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per curve. A negative
1539/// value suppress output completely, a zero value will only print the error count per p.d.f component,
1540/// a positive value is will print details of each error up to numErr messages per p.d.f component.
1541///
1542/// <tr><td> `EvalErrorValue(double value)` <td> Set curve points at which (pdf) evaluation errors occur to specified value. By default the
1543/// function value is plotted.
1544///
1545/// <tr><td> `Normalization(double scale, ScaleType code)` <td> Adjust normalization by given scale factor. Interpretation of number depends on code:
1546/// - Relative: relative adjustment factor for a normalized function,
1547/// - NumEvent: scale to match given number of events.
1548/// - Raw: relative adjustment factor for an un-normalized function.
1549///
1550/// <tr><td> `Name(const chat* name)` <td> Give curve specified name in frame. Useful if curve is to be referenced later
1551///
1552/// <tr><td> `Asymmetry(const RooCategory& c)` <td> Show the asymmetry of the PDF in given two-state category [F(+)-F(-)] / [F(+)+F(-)] rather than
1553/// the PDF projection. Category must have two states with indices -1 and +1 or three states with
1554/// indices -1,0 and +1.
1555///
1556/// <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
1557///
1558/// <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
1559/// <tr><td> `Components(const char* names)` <td> When plotting sums of PDFs, plot only the named components (*e.g.* only
1560/// the signal of a signal+background model).
1561/// <tr><td> `Components(const RooArgSet& compSet)` <td> As above, but pass a RooArgSet of the components themselves.
1562///
1563/// <tr><th><th> Plotting control
1564/// <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).
1565/// \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.
1566///
1567/// <tr><td> `LineStyle(Int_t style)` <td> Select line style by ROOT line style code, default is solid
1568///
1569/// <tr><td> `LineColor(Int_t color)` <td> Select line color by ROOT color code, default is blue
1570///
1571/// <tr><td> `LineWidth(Int_t width)` <td> Select line with in pixels, default is 3
1572///
1573/// <tr><td> `MarkerStyle(Int_t style)` <td> Select the ROOT marker style, default is 21
1574///
1575/// <tr><td> `MarkerColor(Int_t color)` <td> Select the ROOT marker color, default is black
1576///
1577/// <tr><td> `MarkerSize(double size)` <td> Select the ROOT marker size
1578///
1579/// <tr><td> `FillStyle(Int_t style)` <td> Select fill style, default is not filled. If a filled style is selected, also use VLines()
1580/// to add vertical downward lines at end of curve to ensure proper closure. Add `DrawOption("F")` for filled drawing.
1581/// <tr><td> `FillColor(Int_t color)` <td> Select fill color by ROOT color code
1582///
1583/// <tr><td> `Range(const char* name)` <td> Only draw curve in range defined by given name
1584///
1585/// <tr><td> `Range(double lo, double hi)` <td> Only draw curve in specified range
1586///
1587/// <tr><td> `VLines()` <td> Add vertical lines to y=0 at end points of curve
1588///
1589/// <tr><td> `Precision(double eps)` <td> Control precision of drawn curve w.r.t to scale of plot, default is 1e-3. Higher precision
1590/// will result in more and more densely spaced curve points
1591///
1592/// <tr><td> `Invisible(bool flag)` <td> Add curve to frame, but do not display. Useful in combination AddTo()
1593///
1594/// <tr><td> `VisualizeError(const RooFitResult& fitres, double Z=1, bool linearMethod=true)`
1595/// <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
1596///
1597/// <tr><td> `VisualizeError(const RooFitResult& fitres, const RooArgSet& param, double Z=1, bool linearMethod=true)`
1598/// <td> Visualize the uncertainty on the subset of parameters 'param', as given in fitres, at 'Z' sigma'
1599/// </table>
1600///
1601/// Details on error band visualization
1602/// -----------------------------------
1603/// *VisualizeError() uses plotOnWithErrorBand(). Documentation of the latter:*
1604/// \see plotOnWithErrorBand()
1605
1607 const RooCmdArg& arg3, const RooCmdArg& arg4,
1608 const RooCmdArg& arg5, const RooCmdArg& arg6,
1609 const RooCmdArg& arg7, const RooCmdArg& arg8,
1610 const RooCmdArg& arg9, const RooCmdArg& arg10) const
1611{
1613 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
1614 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
1615 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
1616 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
1617 l.Add((TObject*)&arg9) ; l.Add((TObject*)&arg10) ;
1618 return plotOn(frame,l) ;
1619}
1620
1621
1622
1623////////////////////////////////////////////////////////////////////////////////
1624/// Internal back-end function of plotOn() with named arguments
1625
1627{
1628 // Special handling here if argList contains RangeWithName argument with multiple
1629 // range names -- Need to translate this call into multiple calls
1630
1631 RooCmdArg* rcmd = static_cast<RooCmdArg*>(argList.FindObject("RangeWithName")) ;
1632 if (rcmd && TString(rcmd->getString(0)).Contains(",")) {
1633
1634 // List joint ranges as choice of normalization for all later processing
1635 RooCmdArg rnorm = RooFit::NormRange(rcmd->getString(0)) ;
1636 argList.Add(&rnorm) ;
1637
1638 for (const auto& rangeString : ROOT::Split(rcmd->getString(0), ",")) {
1639 // Process each range with a separate command with a single range to be plotted
1640 rcmd->setString(0, rangeString.c_str());
1641 RooAbsReal::plotOn(frame,argList);
1642 }
1643 return frame ;
1644
1645 }
1646
1647 // Define configuration for this method
1648 RooCmdConfig pc("RooAbsReal::plotOn(" + std::string(GetName()) + ")");
1649 pc.defineString("drawOption","DrawOption",0,"L") ;
1650 pc.defineString("projectionRangeName","ProjectionRange",0,"",true) ;
1651 pc.defineString("curveNameSuffix","CurveNameSuffix",0,"") ;
1652 pc.defineString("sliceCatState","SliceCat",0,"",true) ;
1653 pc.defineDouble("scaleFactor","Normalization",0,1.0) ;
1654 pc.defineInt("scaleType","Normalization",0,Relative) ;
1655 pc.defineSet("sliceSet","SliceVars",0) ;
1656 pc.defineObject("sliceCatList","SliceCat",0,nullptr,true) ;
1657 // This dummy is needed for plotOn to recognize the "SliceCatMany" command.
1658 // It is not used directly, but the "SliceCat" commands are nested in it.
1659 // Removing this dummy definition results in "ERROR: unrecognized command: SliceCatMany".
1660 pc.defineObject("dummy1","SliceCatMany",0) ;
1661 pc.defineSet("projSet","Project",0) ;
1662 pc.defineObject("asymCat","Asymmetry",0) ;
1663 pc.defineDouble("precision","Precision",0,1e-3) ;
1664 pc.defineDouble("evalErrorVal","EvalErrorValue",0,0) ;
1665 pc.defineInt("doEvalError","EvalErrorValue",0,0) ;
1666 pc.defineInt("shiftToZero","ShiftToZero",0,0) ;
1667 pc.defineSet("projDataSet","ProjData",0) ;
1668 pc.defineObject("projData","ProjData",1) ;
1669 pc.defineObject("errorFR","VisualizeError",0) ;
1670 pc.defineDouble("errorZ","VisualizeError",0,1.) ;
1671 pc.defineSet("errorPars","VisualizeError",0) ;
1672 pc.defineInt("linearMethod","VisualizeError",0,0) ;
1673 pc.defineInt("binProjData","ProjData",0,0) ;
1674 pc.defineDouble("rangeLo","Range",0,-999.) ;
1675 pc.defineDouble("rangeHi","Range",1,-999.) ;
1676 pc.defineInt("numee","PrintEvalErrors",0,10) ;
1677 pc.defineInt("rangeAdjustNorm","Range",0,0) ;
1678 pc.defineInt("rangeWNAdjustNorm","RangeWithName",0,0) ;
1679 pc.defineInt("VLines","VLines",0,2) ; // 2==ExtendedWings
1680 pc.defineString("rangeName","RangeWithName",0,"") ;
1681 pc.defineString("normRangeName","NormRange",0,"") ;
1682 pc.defineInt("markerColor","MarkerColor",0,-999) ;
1683 pc.defineInt("markerStyle","MarkerStyle",0,-999) ;
1684 pc.defineDouble("markerSize","MarkerSize",0,-999) ;
1685 pc.defineInt("lineColor","LineColor",0,-999) ;
1686 pc.defineInt("lineStyle","LineStyle",0,-999) ;
1687 pc.defineInt("lineWidth","LineWidth",0,-999) ;
1688 pc.defineInt("fillColor","FillColor",0,-999) ;
1689 pc.defineInt("fillStyle","FillStyle",0,-999) ;
1690 pc.defineString("curveName","Name",0,"") ;
1691 pc.defineInt("curveInvisible","Invisible",0,0) ;
1692 pc.defineInt("showProg","ShowProgress",0,0) ;
1693 pc.defineInt("numCPU","NumCPU",0,1) ;
1694 pc.defineInt("interleave","NumCPU",1,0) ;
1695 pc.defineString("addToCurveName","AddTo",0,"") ;
1696 pc.defineDouble("addToWgtSelf","AddTo",0,1.) ;
1697 pc.defineDouble("addToWgtOther","AddTo",1,1.) ;
1698 pc.defineInt("moveToBack","MoveToBack",0,0) ;
1699 pc.defineMutex("SliceVars","Project") ;
1700 pc.defineMutex("AddTo","Asymmetry") ;
1701 pc.defineMutex("Range","RangeWithName") ;
1702 pc.defineMutex("VisualizeError","VisualizeErrorData") ;
1703
1704 // Process & check varargs
1705 pc.process(argList) ;
1706 if (!pc.ok(true)) {
1707 return frame ;
1708 }
1709
1710 TString drawOpt(pc.getString("drawOption"));
1711
1712 RooFitResult* errFR = static_cast<RooFitResult*>(pc.getObject("errorFR")) ;
1713 if (!drawOpt.Contains("P") && errFR) {
1714 return plotOnWithErrorBand(frame, *errFR, pc.getDouble("errorZ"), pc.getSet("errorPars"), argList,
1715 pc.getInt("linearMethod"));
1716 }
1717
1718 // Extract values from named arguments
1719 PlotOpt o ;
1720 o.numee = pc.getInt("numee") ;
1721 o.drawOptions = drawOpt.Data();
1722 o.curveNameSuffix = pc.getString("curveNameSuffix") ;
1723 o.scaleFactor = pc.getDouble("scaleFactor") ;
1724 o.stype = (ScaleType) pc.getInt("scaleType") ;
1725 o.projData = static_cast<const RooAbsData*>(pc.getObject("projData")) ;
1726 o.binProjData = pc.getInt("binProjData") ;
1727 o.projDataSet = pc.getSet("projDataSet");
1728 o.numCPU = pc.getInt("numCPU") ;
1729 o.interleave = (RooFit::MPSplit) pc.getInt("interleave") ;
1730 o.eeval = pc.getDouble("evalErrorVal") ;
1731 o.doeeval = pc.getInt("doEvalError") ;
1732 o.errorFR = errFR;
1733
1734 const RooArgSet* sliceSetTmp = pc.getSet("sliceSet");
1735 std::unique_ptr<RooArgSet> sliceSet{sliceSetTmp ? static_cast<RooArgSet*>(sliceSetTmp->Clone()) : nullptr};
1736 const RooArgSet* projSet = pc.getSet("projSet") ;
1737 const RooAbsCategoryLValue* asymCat = static_cast<const RooAbsCategoryLValue*>(pc.getObject("asymCat")) ;
1738
1739
1740 // Look for category slice arguments and add them to the master slice list if found
1741 if (const char* sliceCatState = pc.getString("sliceCatState",nullptr,true)) {
1742 const RooLinkedList& sliceCatList = pc.getObjectList("sliceCatList") ;
1743
1744 // Make the master slice set if it doesnt exist
1745 if (!sliceSet) {
1746 sliceSet = std::make_unique<RooArgSet>();
1747 }
1748
1749 // Loop over all categories provided by (multiple) Slice() arguments
1750 auto iter = sliceCatList.begin();
1751 for (auto const& catToken : ROOT::Split(sliceCatState, ",")) {
1752 if (auto scat = static_cast<RooCategory*>(*iter)) {
1753 // Set the slice position to the value indicate by slabel
1754 scat->setLabel(catToken);
1755 // Add the slice category to the master slice set
1756 sliceSet->add(*scat,false) ;
1757 }
1758 ++iter;
1759 }
1760 }
1761
1762 o.precision = pc.getDouble("precision") ;
1763 o.shiftToZero = (pc.getInt("shiftToZero")!=0) ;
1764 Int_t vlines = pc.getInt("VLines");
1765 if (pc.hasProcessed("Range")) {
1766 o.rangeLo = pc.getDouble("rangeLo") ;
1767 o.rangeHi = pc.getDouble("rangeHi") ;
1768 o.postRangeFracScale = pc.getInt("rangeAdjustNorm") ;
1769 if (vlines==2) vlines=0 ; // Default is NoWings if range was specified
1770 } else if (pc.hasProcessed("RangeWithName")) {
1771 o.normRangeName = pc.getString("rangeName",nullptr,true) ;
1772 o.rangeLo = frame->getPlotVar()->getMin(pc.getString("rangeName",nullptr,true)) ;
1773 o.rangeHi = frame->getPlotVar()->getMax(pc.getString("rangeName",nullptr,true)) ;
1774 o.postRangeFracScale = pc.getInt("rangeWNAdjustNorm") ;
1775 if (vlines==2) vlines=0 ; // Default is NoWings if range was specified
1776 }
1777
1778
1779 // If separate normalization range was specified this overrides previous settings
1780 if (pc.hasProcessed("NormRange")) {
1781 o.normRangeName = pc.getString("normRangeName") ;
1783 }
1784
1786 o.projectionRangeName = pc.getString("projectionRangeName",nullptr,true) ;
1787 o.curveName = pc.getString("curveName",nullptr,true) ;
1788 o.curveInvisible = pc.getInt("curveInvisible") ;
1789 o.progress = pc.getInt("showProg") ;
1790 o.addToCurveName = pc.getString("addToCurveName",nullptr,true) ;
1791 o.addToWgtSelf = pc.getDouble("addToWgtSelf") ;
1792 o.addToWgtOther = pc.getDouble("addToWgtOther") ;
1793
1795 coutE(InputArguments) << "RooAbsReal::plotOn(" << GetName() << ") cannot find existing curve " << o.addToCurveName << " to add to in RooPlot" << std::endl ;
1796 return frame ;
1797 }
1798
1800 if (sliceSet) {
1801 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") Preprocessing: have slice " << *sliceSet << std::endl ;
1802
1803 makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,true) ;
1804
1805 // Take out the sliced variables
1806 for (const auto sliceArg : *sliceSet) {
1807 if (RooAbsArg* arg = projectedVars.find(sliceArg->GetName())) {
1808 projectedVars.remove(*arg) ;
1809 } else {
1810 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") slice variable "
1811 << sliceArg->GetName() << " was not projected anyway" << std::endl ;
1812 }
1813 }
1814 } else if (projSet) {
1815 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") Preprocessing: have projSet " << *projSet << std::endl ;
1816 makeProjectionSet(frame->getPlotVar(),projSet,projectedVars,false) ;
1817 } else {
1818 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") Preprocessing: have neither sliceSet nor projSet " << std::endl ;
1819 makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,true) ;
1820 }
1821 o.projSet = &projectedVars ;
1822
1823 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") Preprocessing: projectedVars = " << projectedVars << std::endl ;
1824
1825
1826 // Forward to actual calculation
1828
1829 // Optionally adjust line/fill attributes
1830 Int_t lineColor = pc.getInt("lineColor") ;
1831 Int_t lineStyle = pc.getInt("lineStyle") ;
1832 Int_t lineWidth = pc.getInt("lineWidth") ;
1833 Int_t markerColor = pc.getInt("markerColor") ;
1834 Int_t markerStyle = pc.getInt("markerStyle") ;
1835 Size_t markerSize = pc.getDouble("markerSize") ;
1836 Int_t fillColor = pc.getInt("fillColor") ;
1837 Int_t fillStyle = pc.getInt("fillStyle") ;
1838 if (lineColor!=-999) ret->getAttLine()->SetLineColor(lineColor) ;
1839 if (lineStyle!=-999) ret->getAttLine()->SetLineStyle(lineStyle) ;
1840 if (lineWidth!=-999) ret->getAttLine()->SetLineWidth(lineWidth) ;
1841 if (fillColor!=-999) ret->getAttFill()->SetFillColor(fillColor) ;
1842 if (fillStyle!=-999) ret->getAttFill()->SetFillStyle(fillStyle) ;
1843 if (markerColor!=-999) ret->getAttMarker()->SetMarkerColor(markerColor) ;
1844 if (markerStyle!=-999) ret->getAttMarker()->SetMarkerStyle(markerStyle) ;
1845 if (markerSize!=-999) ret->getAttMarker()->SetMarkerSize(markerSize) ;
1846
1847 if ((fillColor != -999 || fillStyle != -999) && !drawOpt.Contains("F")) {
1848 coutW(Plotting) << "Fill color or style was set for plotting \"" << GetName()
1849 << "\", but these only have an effect when 'DrawOption(\"F\")' for fill is used at the same time." << std::endl;
1850 }
1851
1852 // Move last inserted object to back to drawing stack if requested
1853 if (pc.getInt("moveToBack") && frame->numItems()>1) {
1854 frame->drawBefore(frame->getObject(0)->GetName(), frame->getCurve()->GetName());
1855 }
1856
1857 return ret ;
1858}
1859
1860
1861
1862/// Plotting engine function for internal use
1863///
1864/// Plot ourselves on given frame. If frame contains a histogram, all dimensions of the plotted
1865/// function that occur in the previously plotted dataset are projected via partial integration,
1866/// otherwise no projections are performed. Optionally, certain projections can be performed
1867/// by summing over the values present in a provided dataset ('projData'), to correctly
1868/// project out data dependents that are not properly described by the PDF (e.g. per-event errors).
1869///
1870/// The functions value can be multiplied with an optional scale factor. The interpretation
1871/// of the scale factor is unique for generic real functions, for PDFs there are various interpretations
1872/// possible, which can be selection with 'stype' (see RooAbsPdf::plotOn() for details).
1873///
1874/// The default projection behaviour can be overridden by supplying an optional set of dependents
1875/// to project via RooFit command arguments.
1876//_____________________________________________________________________________
1877// coverity[PASS_BY_VALUE]
1879{
1880 // Sanity checks
1881 if (plotSanityChecks(frame)) return frame ;
1882
1883 // ProjDataVars is either all projData observables, or the user indicated subset of it
1885 if (o.projData) {
1886 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") have ProjData with observables = " << *o.projData->get() << std::endl ;
1887 if (o.projDataSet) {
1888 projDataVars.add(*std::unique_ptr<RooArgSet>{o.projData->get()->selectCommon(*o.projDataSet)}) ;
1889 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") have ProjDataSet = " << *o.projDataSet << " will only use this subset of projData" << std::endl ;
1890 } else {
1891 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") using full ProjData" << std::endl ;
1892 projDataVars.add(*o.projData->get()) ;
1893 }
1894 }
1895
1896 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") ProjDataVars = " << projDataVars << std::endl ;
1897
1898 // Make list of variables to be projected
1901 if (o.projSet) {
1902 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") have input projSet = " << *o.projSet << std::endl ;
1904 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") calculated projectedVars = " << *o.projSet << std::endl ;
1905
1906 // Print list of non-projected variables
1907 if (frame->getNormVars()) {
1910
1911 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") frame->getNormVars() that are also observables = " << sliceSetTmp << std::endl ;
1912
1913 sliceSetTmp.remove(projectedVars,true,true) ;
1914 sliceSetTmp.remove(*frame->getPlotVar(),true,true) ;
1915
1916 if (o.projData) {
1917 std::unique_ptr<RooArgSet> tmp{projDataVars.selectCommon(*o.projSet)};
1918 sliceSetTmp.remove(*tmp,true,true) ;
1919 }
1920
1921 if (!sliceSetTmp.empty()) {
1922 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on "
1923 << frame->getPlotVar()->GetName() << " represents a slice in " << sliceSetTmp << std::endl ;
1924 }
1925 sliceSet.add(sliceSetTmp) ;
1926 }
1927 } else {
1928 makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,true) ;
1929 }
1930
1931 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") projectedVars = " << projectedVars << " sliceSet = " << sliceSet << std::endl ;
1932
1933
1934 RooArgSet* projDataNeededVars = nullptr ;
1935 // Take out data-projected dependents from projectedVars
1936 if (o.projData) {
1938 projectedVars.remove(projDataVars,true,true) ;
1939 }
1940
1941 // Get the plot variable and remember its original value
1942 auto* plotVar = static_cast<RooRealVar*>(frame->getPlotVar());
1943 double oldPlotVarVal = plotVar->getVal();
1944
1945 // Inform user about projections
1946 if (!projectedVars.empty()) {
1947 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
1948 << " integrates over variables " << projectedVars
1949 << (o.projectionRangeName?Form(" in range %s",o.projectionRangeName):"") << std::endl;
1950 }
1951 if (projDataNeededVars && !projDataNeededVars->empty()) {
1952 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
1953 << " averages using data variables " << *projDataNeededVars << std::endl ;
1954 }
1955
1956 // Create projection integral
1957 RooArgSet* projectionCompList = nullptr ;
1958
1959 RooArgSet deps;
1960 getObservables(frame->getNormVars(), deps) ;
1961 deps.remove(projectedVars,true,true) ;
1962 if (projDataNeededVars) {
1963 deps.remove(*projDataNeededVars,true,true) ;
1964 }
1965 deps.remove(*plotVar,true,true) ;
1966 deps.add(*plotVar) ;
1967
1968 // Now that we have the final set of dependents, call checkObservables()
1969
1970 // WVE take out conditional observables
1971 if (checkObservables(&deps)) {
1972 coutE(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") error in checkObservables, abort" << std::endl ;
1974 return frame ;
1975 }
1976
1978 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot projection object is " << projection->GetName() << std::endl ;
1979 if (dologD(Plotting)) {
1980 projection->printStream(ccoutD(Plotting),0,kVerbose) ;
1981 }
1982
1983 // Always fix RooAddPdf normalizations
1984 RooArgSet fullNormSet(deps) ;
1986 if (projDataNeededVars && !projDataNeededVars->empty()) {
1988 }
1989
1990 std::unique_ptr<RooArgSet> projectionComponents(projection->getComponents());
1992 if (pdf) {
1993 pdf->selectNormalization(&fullNormSet) ;
1994 }
1995 }
1996
1997 // Apply data projection, if requested
1998 if (o.projData && projDataNeededVars && !projDataNeededVars->empty()) {
1999
2000 // If data set contains more rows than needed, make reduced copy first
2001 RooAbsData* projDataSel = const_cast<RooAbsData*>(o.projData);
2002 std::unique_ptr<RooAbsData> projDataSelOwned;
2003
2004 if (projDataNeededVars->size() < o.projData->get()->size()) {
2005
2006 // Determine if there are any slice variables in the projection set
2008 sliceSet.selectCommon(*o.projData->get(), sliceDataSet);
2010
2011 if (!cutString.empty()) {
2012 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") reducing given projection dataset to entries with " << cutString << std::endl ;
2013 }
2014 projDataSelOwned = std::unique_ptr<RooAbsData>{projDataSel->reduce(RooFit::SelectVars(*projDataNeededVars), RooFit::Cut(cutString.c_str()))};
2016 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName()
2017 << ") only the following components of the projection data will be used: " << *projDataNeededVars << std::endl ;
2018 }
2019
2020 // Request binning of unbinned projection dataset that consists exclusively of category observables
2021 if (!o.binProjData && dynamic_cast<RooDataSet*>(projDataSel)!=nullptr) {
2022
2023 // Determine if dataset contains only categories
2024 bool allCat(true) ;
2025 for(RooAbsArg * arg2 : *projDataSel->get()) {
2026 if (!dynamic_cast<RooCategory*>(arg2)) allCat = false ;
2027 }
2028 if (allCat) {
2029 o.binProjData = true ;
2030 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") unbinned projection dataset consist only of discrete variables,"
2031 << " performing projection with binned copy for optimization." << std::endl ;
2032
2033 }
2034 }
2035
2036 // Bin projection dataset if requested
2037 if (o.binProjData) {
2038 projDataSelOwned = std::make_unique<RooDataHist>(std::string(projDataSel->GetName()) + "_binned","Binned projection data",*projDataSel->get(),*projDataSel);
2040 }
2041
2042 // Construct scaled data weighted average
2043 ScaledDataWeightedAverage scaleBind{*projection, *projDataSel, o.scaleFactor, *plotVar};
2044
2045 // Set default range, if not specified
2046 if (o.rangeLo==0 && o.rangeHi==0) {
2047 o.rangeLo = frame->GetXaxis()->GetXmin() ;
2048 o.rangeHi = frame->GetXaxis()->GetXmax() ;
2049 }
2050
2051 // Construct name of curve for data weighed average
2052 std::string curveName(projection->GetName()) ;
2053 curveName.append("_DataAvg[" + projDataSel->get()->contentsString() + "]");
2054 // Append slice set specification if any
2055 if (!sliceSet.empty()) {
2056 curveName.append("_Slice[" + sliceSet.contentsString() + "]");
2057 }
2058 // Append any suffixes imported from RooAbsPdf::plotOn
2059 if (o.curveNameSuffix) {
2060 curveName.append(o.curveNameSuffix) ;
2061 }
2062
2063 // Curve constructor for data weighted average
2065 RooCurve *curve = new RooCurve(projection->GetName(),projection->GetTitle(),scaleBind,
2068
2069 curve->SetName(curveName.c_str()) ;
2070
2071 // Add self to other curve if requested
2072 if (o.addToCurveName) {
2074
2075 // Curve constructor for sum of curves
2077 sumCurve->SetName(Form("%s_PLUS_%s",curve->GetName(),otherCurve->GetName())) ;
2078 delete curve ;
2079 curve = sumCurve ;
2080
2081 }
2082
2083 if (o.curveName) {
2084 curve->SetName(o.curveName) ;
2085 }
2086
2087 // add this new curve to the specified plot frame
2089
2090 } else {
2091
2092 // Set default range, if not specified
2093 if (o.rangeLo==0 && o.rangeHi==0) {
2094 o.rangeLo = frame->GetXaxis()->GetXmin() ;
2095 o.rangeHi = frame->GetXaxis()->GetXmax() ;
2096 }
2097
2098 // Calculate a posteriori range fraction scaling if requested (2nd part of normalization correction for
2099 // result fit on subrange of data)
2100 if (o.postRangeFracScale) {
2101 if (!o.normRangeName) {
2102 o.normRangeName = "plotRange" ;
2103 plotVar->setRange("plotRange",o.rangeLo,o.rangeHi) ;
2104 }
2105
2106 // Evaluate fractional correction integral always on full p.d.f, not component.
2108 std::unique_ptr<RooAbsReal> intFrac{projection->createIntegral(*plotVar,*plotVar,o.normRangeName)};
2109 if(o.stype != RooAbsReal::Raw || this->InheritsFrom(RooAbsPdf::Class())){
2110 // this scaling should only be !=1 when plotting partial ranges
2111 // still, raw means raw
2112 o.scaleFactor /= intFrac->getVal() ;
2113 }
2114 }
2115
2116 // create a new curve of our function using the clone to do the evaluations
2117 // Curve constructor for regular projections
2118
2119 // Set default name of curve
2120 std::string curveName(projection->GetName()) ;
2121 if (!sliceSet.empty()) {
2122 curveName.append("_Slice[" + sliceSet.contentsString() + "]");
2123 }
2124 if (o.curveNameSuffix) {
2125 // Append any suffixes imported from RooAbsPdf::plotOn
2126 curveName.append(o.curveNameSuffix) ;
2127 }
2128
2129 TString opt(o.drawOptions);
2130 if(opt.Contains("P")){
2132 RooHist *graph= new RooHist(*projection,*plotVar,1.,o.scaleFactor,frame->getNormVars(),o.errorFR);
2134
2135 // Override name of curve by user name, if specified
2136 if (o.curveName) {
2137 graph->SetName(o.curveName) ;
2138 }
2139
2140 // add this new curve to the specified plot frame
2141 frame->addPlotable(graph, o.drawOptions, o.curveInvisible);
2142 } else {
2147 curve->SetName(curveName.c_str()) ;
2148
2149 // Add self to other curve if requested
2150 if (o.addToCurveName) {
2153 sumCurve->SetName(Form("%s_PLUS_%s",curve->GetName(),otherCurve->GetName())) ;
2154 delete curve ;
2155 curve = sumCurve ;
2156 }
2157
2158 // Override name of curve by user name, if specified
2159 if (o.curveName) {
2160 curve->SetName(o.curveName) ;
2161 }
2162
2163 // add this new curve to the specified plot frame
2165 }
2166 }
2167
2169 delete projectionCompList ;
2170 plotVar->setVal(oldPlotVarVal); // reset the plot variable value to not disturb the original state
2171 return frame;
2172}
2173
2174
2175//_____________________________________________________________________________
2176// coverity[PASS_BY_VALUE]
2178
2179{
2180 // Plotting engine for asymmetries. Implements the functionality if plotOn(frame,Asymmetry(...)))
2181 //
2182 // Plot asymmetry of ourselves, defined as
2183 //
2184 // asym = f(asymCat=-1) - f(asymCat=+1) / ( f(asymCat=-1) + f(asymCat=+1) )
2185 //
2186 // on frame. If frame contains a histogram, all dimensions of the plotted
2187 // asymmetry function that occur in the previously plotted dataset are projected via partial integration.
2188 // Otherwise no projections are performed,
2189 //
2190 // The asymmetry function can be multiplied with an optional scale factor. The default projection
2191 // behaviour can be overridden by supplying an optional set of dependents to project.
2192
2193 // Sanity checks
2194 if (plotSanityChecks(frame)) return frame ;
2195
2196 // ProjDataVars is either all projData observables, or the user indicated subset of it
2198 if (o.projData) {
2199 if (o.projDataSet) {
2200 std::unique_ptr<RooArgSet> tmp{o.projData->get()->selectCommon(*o.projDataSet)};
2201 projDataVars.add(*tmp) ;
2202 } else {
2203 projDataVars.add(*o.projData->get()) ;
2204 }
2205 }
2206
2207 // Must depend on asymCat
2208 if (!dependsOn(asymCat)) {
2209 coutE(Plotting) << "RooAbsReal::plotAsymOn(" << GetName()
2210 << ") function doesn't depend on asymmetry category " << asymCat.GetName() << std::endl ;
2211 return frame ;
2212 }
2213
2214 // asymCat must be a signCat
2215 if (!asymCat.isSignType()) {
2216 coutE(Plotting) << "RooAbsReal::plotAsymOn(" << GetName()
2217 << ") asymmetry category must have 2 or 3 states with index values -1,0,1" << std::endl ;
2218 return frame ;
2219 }
2220
2221 // Make list of variables to be projected
2224 if (o.projSet) {
2226
2227 // Print list of non-projected variables
2228 if (frame->getNormVars()) {
2231 sliceSetTmp.remove(projectedVars,true,true) ;
2232 sliceSetTmp.remove(*frame->getPlotVar(),true,true) ;
2233
2234 if (o.projData) {
2235 std::unique_ptr<RooArgSet> tmp{projDataVars.selectCommon(*o.projSet)};
2236 sliceSetTmp.remove(*tmp,true,true) ;
2237 }
2238
2239 if (!sliceSetTmp.empty()) {
2240 coutI(Plotting) << "RooAbsReal::plotAsymOn(" << GetName() << ") plot on "
2241 << frame->getPlotVar()->GetName() << " represents a slice in " << sliceSetTmp << std::endl ;
2242 }
2243 sliceSet.add(sliceSetTmp) ;
2244 }
2245 } else {
2246 makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,true) ;
2247 }
2248
2249
2250 // Take out data-projected dependents from projectedVars
2251 RooArgSet* projDataNeededVars = nullptr ;
2252 if (o.projData) {
2254 projectedVars.remove(projDataVars,true,true) ;
2255 }
2256
2257 // Take out plotted asymmetry from projection
2258 if (projectedVars.find(asymCat.GetName())) {
2259 projectedVars.remove(*projectedVars.find(asymCat.GetName())) ;
2260 }
2261
2262 // Clone the plot variable
2263 RooAbsReal* realVar = static_cast<RooRealVar*>(frame->getPlotVar()) ;
2264 RooRealVar* plotVar = static_cast<RooRealVar*>(realVar->Clone()) ;
2265
2266 // Inform user about projections
2267 if (!projectedVars.empty()) {
2268 coutI(Plotting) << "RooAbsReal::plotAsymOn(" << GetName() << ") plot on " << plotVar->GetName()
2269 << " projects variables " << projectedVars << std::endl ;
2270 }
2271 if (projDataNeededVars && !projDataNeededVars->empty()) {
2272 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") plot on " << plotVar->GetName()
2273 << " averages using data variables "<< *projDataNeededVars << std::endl ;
2274 }
2275
2276
2277 // Customize two copies of projection with fixed negative and positive asymmetry
2278 std::unique_ptr<RooAbsCategoryLValue> asymPos{static_cast<RooAbsCategoryLValue*>(asymCat.Clone("asym_pos"))};
2279 std::unique_ptr<RooAbsCategoryLValue> asymNeg{static_cast<RooAbsCategoryLValue*>(asymCat.Clone("asym_neg"))};
2280 asymPos->setIndex(1) ;
2281 asymNeg->setIndex(-1) ;
2282 RooCustomizer custPos{*this,"pos"};
2283 RooCustomizer custNeg{*this,"neg"};
2284 //custPos->setOwning(true) ;
2285 //custNeg->setOwning(true) ;
2286 custPos.replaceArg(asymCat,*asymPos) ;
2287 custNeg.replaceArg(asymCat,*asymNeg) ;
2288 std::unique_ptr<RooAbsReal> funcPos{static_cast<RooAbsReal*>(custPos.build())};
2289 std::unique_ptr<RooAbsReal> funcNeg{static_cast<RooAbsReal*>(custNeg.build())};
2290
2291 // Create projection integral
2294
2295 // Add projDataVars to normalized dependents of projection
2296 // This is needed only for asymmetries (why?)
2299 depPos.add(projDataVars) ;
2300 depNeg.add(projDataVars) ;
2301
2302 const RooAbsReal *posProj = funcPos->createPlotProjection(depPos, &projectedVars, posProjCompList, o.projectionRangeName) ;
2303 const RooAbsReal *negProj = funcNeg->createPlotProjection(depNeg, &projectedVars, negProjCompList, o.projectionRangeName) ;
2304 if (!posProj || !negProj) {
2305 coutE(Plotting) << "RooAbsReal::plotAsymOn(" << GetName() << ") Unable to create projections, abort" << std::endl ;
2306 return frame ;
2307 }
2308
2309 // Create a RooFormulaVar representing the asymmetry
2311 asymName.Append("_Asym[") ;
2312 asymName.Append(asymCat.GetName()) ;
2313 asymName.Append("]") ;
2314 TString asymTitle(asymCat.GetName()) ;
2315 asymTitle.Append(" Asymmetry of ") ;
2316 asymTitle.Append(GetTitle()) ;
2318
2319 if (o.projData) {
2320
2321 // If data set contains more rows than needed, make reduced copy first
2322 RooAbsData* projDataSel = const_cast<RooAbsData*>(o.projData);
2323 std::unique_ptr<RooAbsData> projDataSelOwned;
2324 if (projDataNeededVars && projDataNeededVars->size() < o.projData->get()->size()) {
2325
2326 // Determine if there are any slice variables in the projection set
2328 sliceSet.selectCommon(*o.projData->get(), sliceDataSet);
2330
2331 if (!cutString.empty()) {
2332 coutI(Plotting) << "RooAbsReal::plotAsymOn(" << GetName()
2333 << ") reducing given projection dataset to entries with " << cutString << std::endl ;
2334 }
2335 projDataSelOwned = std::unique_ptr<RooAbsData>{projDataSel->reduce(RooFit::SelectVars(*projDataNeededVars),RooFit::Cut(cutString.c_str()))};
2337 coutI(Plotting) << "RooAbsReal::plotAsymOn(" << GetName()
2338 << ") only the following components of the projection data will be used: " << *projDataNeededVars << std::endl ;
2339 }
2340
2341
2342 // Construct scaled data weighted average
2343 ScaledDataWeightedAverage scaleBind{funcAsym, *projDataSel, o.scaleFactor, *plotVar};
2344
2345 // Set default range, if not specified
2346 if (o.rangeLo==0 && o.rangeHi==0) {
2347 o.rangeLo = frame->GetXaxis()->GetXmin() ;
2348 o.rangeHi = frame->GetXaxis()->GetXmax() ;
2349 }
2350
2351 // Construct name of curve for data weighed average
2352 TString curveName(funcAsym.GetName()) ;
2353 curveName.Append(Form("_DataAvg[%s]",projDataSel->get()->contentsString().c_str())) ;
2354 // Append slice set specification if any
2355 if (!sliceSet.empty()) {
2356 curveName.Append(Form("_Slice[%s]",sliceSet.contentsString().c_str())) ;
2357 }
2358 // Append any suffixes imported from RooAbsPdf::plotOn
2359 if (o.curveNameSuffix) {
2360 curveName.Append(o.curveNameSuffix) ;
2361 }
2362
2363
2365 RooCurve *curve = new RooCurve(funcAsym.GetName(),funcAsym.GetTitle(),scaleBind,
2366 o.rangeLo,o.rangeHi,frame->GetNbinsX(),o.precision,o.precision,false,o.wmode,o.numee,o.doeeval,o.eeval) ;
2368
2369 dynamic_cast<TAttLine*>(curve)->SetLineColor(2) ;
2370 // add this new curve to the specified plot frame
2371 frame->addPlotable(curve, o.drawOptions);
2372
2373 ccoutW(Eval) << std::endl ;
2374 } else {
2375
2376 // Set default range, if not specified
2377 if (o.rangeLo==0 && o.rangeHi==0) {
2378 o.rangeLo = frame->GetXaxis()->GetXmin() ;
2379 o.rangeHi = frame->GetXaxis()->GetXmax() ;
2380 }
2381
2384 o.scaleFactor,nullptr,o.precision,o.precision,false,o.wmode,o.numee,o.doeeval,o.eeval);
2386
2387 dynamic_cast<TAttLine*>(curve)->SetLineColor(2) ;
2388
2389
2390 // Set default name of curve
2391 TString curveName(funcAsym.GetName()) ;
2392 if (!sliceSet.empty()) {
2393 curveName.Append(Form("_Slice[%s]",sliceSet.contentsString().c_str())) ;
2394 }
2395 if (o.curveNameSuffix) {
2396 // Append any suffixes imported from RooAbsPdf::plotOn
2397 curveName.Append(o.curveNameSuffix) ;
2398 }
2399 curve->SetName(curveName.Data()) ;
2400
2401 // add this new curve to the specified plot frame
2402 frame->addPlotable(curve, o.drawOptions);
2403
2404 }
2405
2406 // Cleanup
2407 delete posProjCompList ;
2408 delete negProjCompList ;
2409
2410 delete plotVar ;
2411
2412 return frame;
2413}
2414
2415
2416
2417////////////////////////////////////////////////////////////////////////////////
2418/// \brief Propagates parameter uncertainties to an uncertainty estimate for this RooAbsReal.
2419///
2420/// Estimates the uncertainty \f$\sigma_f(x;\theta)\f$ on a function \f$f(x;\theta)\f$ represented by this RooAbsReal.
2421/// Here, \f$\theta\f$ is a vector of parameters with uncertainties \f$\sigma_\theta\f$, and \f$x\f$ are usually observables.
2422/// The uncertainty is estimated by *linearly* propagating the parameter uncertainties using the correlation matrix from a fit result.
2423///
2424/// The square of the uncertainty on \f$f(x;\theta)\f$ is calculated as follows:
2425/// \f[
2426/// \sigma_f(x)^2 = \Delta f_i(x) \cdot \mathrm{Corr}_{i, j} \cdot \Delta f_j(x),
2427/// \f]
2428/// 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$
2429/// is the vector of function variations when changing the parameters one at a time, and
2430/// \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.
2431
2432double RooAbsReal::getPropagatedError(const RooFitResult &fr, const RooArgSet &nset) const
2433{
2434 // Calling getParameters() might be costly, but necessary to get the right
2435 // parameters in the RooAbsReal. The RooFitResult only stores snapshots.
2438
2439 RooArgList paramList;
2441
2442 auto rrvInAbsReal = static_cast<RooRealVar const*>(allParamsInAbsReal.find(*rrvFitRes));
2443
2444 // If this RooAbsReal is a RooRealVar in the fit result, we don't need to
2445 // propagate anything and can just return the error in the fit result
2446 if(rrvFitRes->namePtr() == namePtr()) return rrvFitRes->getError();
2447
2448 // Strip out parameters with zero error
2449 if (rrvFitRes->getError() <= std::abs(rrvFitRes->getVal()) * std::numeric_limits<double>::epsilon()) continue;
2450
2451 // Ignore parameters in the fit result that this RooAbsReal doesn't depend on
2452 if(!rrvInAbsReal) continue;
2453
2454 // Checking for float equality is a bad. We check if the values are
2455 // negligibly far away from each other, relative to the uncertainty.
2456 if(std::abs(rrvInAbsReal->getVal() - rrvFitRes->getVal()) > 0.01 * rrvFitRes->getError()) {
2457 std::stringstream errMsg;
2458 errMsg << "RooAbsReal::getPropagatedError(): the parameters of the RooAbsReal don't have"
2459 << " the same values as in the fit result! The logic of getPropagatedError is broken in this case.";
2460
2461 throw std::runtime_error(errMsg.str());
2462 }
2463
2464 paramList.add(*rrvInAbsReal);
2465 }
2466
2467 std::vector<double> plusVar;
2468 std::vector<double> minusVar;
2469 plusVar.reserve(paramList.size());
2470 minusVar.reserve(paramList.size());
2471
2472 // Create std::vector of plus,minus variations for each parameter
2473 TMatrixDSym V(paramList.size() == fr.floatParsFinal().size() ?
2474 fr.covarianceMatrix() :
2475 fr.reducedCovarianceMatrix(paramList)) ;
2476
2477 for (std::size_t ivar=0 ; ivar<paramList.size() ; ivar++) {
2478
2479 auto& rrv = static_cast<RooRealVar&>(paramList[ivar]);
2480
2481 double cenVal = rrv.getVal() ;
2482 double errVal = sqrt(V(ivar,ivar)) ;
2483
2484 // Make Plus variation
2485 rrv.setVal(cenVal+errVal) ;
2486 plusVar.push_back(getVal(nset)) ;
2487
2488 // Make Minus variation
2489 rrv.setVal(cenVal-errVal) ;
2490 minusVar.push_back(getVal(nset)) ;
2491
2492 rrv.setVal(cenVal) ;
2493 }
2494
2495 // Re-evaluate this RooAbsReal with the central parameters just to be
2496 // extra-safe that a call to `getPropagatedError()` doesn't change any state.
2497 // It should not be necessary because thanks to the dirty flag propagation
2498 // the RooAbsReal is re-evaluated anyway the next time getVal() is called.
2499 // Still there are imaginable corner cases where it would not be triggered,
2500 // for example if the user changes the RooFit operation more after the error
2501 // propagation.
2502 getVal(nset);
2503
2504 TMatrixDSym C(paramList.size()) ;
2505 std::vector<double> errVec(paramList.size()) ;
2506 for (std::size_t i=0 ; i<paramList.size() ; i++) {
2507 errVec[i] = std::sqrt(V(i,i)) ;
2508 for (std::size_t j=i ; j<paramList.size() ; j++) {
2509 C(i,j) = V(i,j) / std::sqrt(V(i,i)*V(j,j));
2510 C(j,i) = C(i,j) ;
2511 }
2512 }
2513
2514 // Make std::vector of variations
2515 TVectorD F(plusVar.size()) ;
2516 for (std::size_t j=0 ; j<plusVar.size() ; j++) {
2517 F[j] = (plusVar[j]-minusVar[j]) * 0.5;
2518 }
2519
2520 // Calculate error in linear approximation from variations and correlation coefficient
2521 double sum = F*(C*F) ;
2522
2523 return sqrt(sum) ;
2524}
2525
2526
2527
2528////////////////////////////////////////////////////////////////////////////////
2529/// Plot function or PDF on frame with support for visualization of the uncertainty encoded in the given fit result fr.
2530/// \param[in] frame RooPlot to plot on
2531/// \param[in] fr The RooFitResult, where errors can be extracted
2532/// \param[in] Z The desired significance (width) of the error band
2533/// \param[in] params If non-zero, consider only the subset of the parameters in fr for the error evaluation
2534/// \param[in] argList Optional `RooCmdArg` that can be applied to a regular plotOn() operation
2535/// \param[in] linMethod By default (linMethod=true), a linearized error is shown.
2536/// \return The RooPlot the band was plotted on (for chaining of plotting commands).
2537///
2538/// The linearized error is calculated as follows:
2539/// \f[
2540/// \mathrm{error}(x) = Z * F_a(x) * \mathrm{Corr}(a,a') * F_{a'}^\mathrm{T}(x),
2541/// \f]
2542///
2543/// where
2544/// \f[
2545/// F_a(x) = \frac{ f(x,a+\mathrm{d}a) - f(x,a-\mathrm{d}a) }{2},
2546/// \f]
2547/// with \f$ f(x) \f$ the plotted curve and \f$ \mathrm{d}a \f$ taken from the fit result, and
2548/// \f$ \mathrm{Corr}(a,a') \f$ = the correlation matrix from the fit result, and \f$ Z \f$ = requested signifance (\f$ Z \sigma \f$ band)
2549///
2550/// The linear method is fast (required 2*N evaluations of the curve, where N is the number of parameters), but may
2551/// not be accurate in the presence of strong correlations (~>0.9) and at Z>2 due to linear and Gaussian approximations made
2552///
2553/// Alternatively, a more robust error is calculated using a sampling method. In this method a number of curves
2554/// is calculated with variations of the parameter values, as drawn from a multi-variate Gaussian p.d.f. that is constructed
2555/// from the fit results covariance matrix. The error(x) is determined by calculating a central interval that capture N% of the variations
2556/// 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
2557/// 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)
2558/// Intervals from the sampling method can be asymmetric, and may perform better in the presence of strong correlations, but may take (much)
2559/// longer to calculate.
2560
2561RooPlot* RooAbsReal::plotOnWithErrorBand(RooPlot* frame,const RooFitResult& fr, double Z,const RooArgSet* params, const RooLinkedList& argList, bool linMethod) const
2562{
2563 RooLinkedList plotArgListTmp(argList) ;
2564 RooCmdConfig::stripCmdList(plotArgListTmp,"VisualizeError,MoveToBack") ;
2565
2566 // Strip any 'internal normalization' arguments from list
2569 if (std::string("Normalization")==cmd->GetName()) {
2570 if (((RooCmdArg*)cmd)->getInt(1)!=0) {
2571 } else {
2572 plotArgList.Add(cmd) ;
2573 }
2574 } else {
2575 plotArgList.Add(cmd) ;
2576 }
2577 }
2578
2579 // Function to plot a single curve, creating a copy of the plotArgList to
2580 // pass as plot command arguments. The "FillColor" command is removed because
2581 // it has no effect on plotting single curves and would cause a warning.
2582 auto plotFunc = [&](RooAbsReal const& absReal) {
2584 RooCmdConfig::stripCmdList(tmp, "FillColor");
2585 absReal.plotOn(frame, tmp);
2586 };
2587
2588 // Generate central value curve
2589 plotFunc(*this);
2590 RooCurve* cenCurve = frame->getCurve() ;
2591 if(!cenCurve){
2592 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOnWithErrorBand: no curve for central value available" << std::endl;
2593 return frame;
2594 }
2595 frame->remove(nullptr,false) ;
2596
2597 RooCurve* band(nullptr) ;
2598 if (!linMethod) {
2599
2600 // *** Interval method ***
2601 //
2602 // Make N variations of parameters samples from V and visualize N% central interval where N% is defined from Z
2603
2604 // Clone self for internal use
2605 RooAbsReal* cloneFunc = static_cast<RooAbsReal*>(cloneTree()) ;
2607 cloneFunc->getObservables(&fr.floatParsFinal(), cloneParams) ;
2609 if(params) {
2610 // clear and fill errorParams only with parameters that both in params and cloneParams
2611 cloneParams.selectCommon(*params, errorParams);
2612 }
2613
2614 // Generate 100 random parameter points distributed according to fit result covariance matrix
2616 Int_t n = Int_t(100./TMath::Erfc(Z/sqrt(2.))) ;
2617 if (n<100) n=100 ;
2618
2619 coutI(Plotting) << "RooAbsReal::plotOn(" << GetName() << ") INFO: visualizing " << Z << "-sigma uncertainties in parameters "
2620 << errorParams << " from fit result " << fr.GetName() << " using " << n << " samplings." << std::endl ;
2621
2622 // Generate variation curves with above set of parameter values
2623 double ymin = frame->GetMinimum() ;
2624 double ymax = frame->GetMaximum() ;
2625 std::unique_ptr<RooDataSet> generatedData{paramPdf->generate(errorParams,n)};
2626 std::vector<RooCurve*> cvec ;
2627 for (int i=0 ; i<generatedData->numEntries() ; i++) {
2628 cloneParams.assign(*generatedData->get(i)) ;
2630 cvec.push_back(frame->getCurve()) ;
2631 frame->remove(nullptr,false) ;
2632 }
2633 frame->SetMinimum(ymin) ;
2634 frame->SetMaximum(ymax) ;
2635
2636
2637 // Generate upper and lower curve points from 68% interval around each point of central curve
2638 band = cenCurve->makeErrorBand(cvec,Z) ;
2639
2640 // Cleanup
2641 delete paramPdf ;
2642 delete cloneFunc ;
2643 for (std::vector<RooCurve*>::iterator i=cvec.begin() ; i!=cvec.end() ; ++i) {
2644 delete (*i) ;
2645 }
2646
2647 } else {
2648
2649 // *** Linear Method ***
2650 //
2651 // Make a one-sigma up- and down fluctation for each parameter and visualize
2652 // a from a linearized calculation as follows
2653 //
2654 // error(x) = F(a) C_aa' F(a')
2655 //
2656 // Where F(a) = (f(x,a+da) - f(x,a-da))/2
2657 // and C_aa' is the correlation matrix
2658
2659 // Strip out parameters with zero error
2661 for (auto const* frv : static_range_cast<RooRealVar*>(fr.floatParsFinal())) {
2662 if (frv->getError() > frv->getVal() * std::numeric_limits<double>::epsilon()) {
2663 fpf_stripped.add(*frv);
2664 }
2665 }
2666
2667 // Clone self for internal use
2668 RooAbsReal* cloneFunc = static_cast<RooAbsReal*>(cloneTree()) ;
2670 cloneFunc->getObservables(&fpf_stripped, cloneParams) ;
2672 if(params) {
2673 // clear and fill errorParams only with parameters that both in params and cloneParams
2674 cloneParams.selectCommon(*params, errorParams);
2675 }
2676
2677
2678 // Make list of parameter instances of cloneFunc in order of error matrix
2679 RooArgList paramList ;
2680 const RooArgList& fpf = fr.floatParsFinal() ;
2681 std::vector<int> fpf_idx ;
2682 for (std::size_t i=0 ; i<fpf.size() ; i++) {
2683 RooAbsArg* par = errorParams.find(fpf[i].GetName()) ;
2684 if (par) {
2685 paramList.add(*par) ;
2686 fpf_idx.push_back(i) ;
2687 }
2688 }
2689
2690 std::vector<RooCurve *> plusVar;
2691 std::vector<RooCurve *> minusVar;
2692
2693 // Create std::vector of plus,minus variations for each parameter
2694
2695 TMatrixDSym V(paramList.size() == fr.floatParsFinal().size() ?
2696 fr.covarianceMatrix():
2697 fr.reducedCovarianceMatrix(paramList)) ;
2698
2699
2700 for (std::size_t ivar=0 ; ivar<paramList.size() ; ivar++) {
2701
2702 RooRealVar& rrv = static_cast<RooRealVar&>(fpf[fpf_idx[ivar]]) ;
2703
2704 double cenVal = rrv.getVal() ;
2705 double errVal = sqrt(V(ivar,ivar)) ;
2706
2707 // Make Plus variation
2708 (static_cast<RooRealVar*>(paramList.at(ivar)))->setVal(cenVal+Z*errVal) ;
2709
2710
2712 plusVar.push_back(frame->getCurve()) ;
2713 frame->remove(nullptr,false) ;
2714
2715
2716 // Make Minus variation
2717 (static_cast<RooRealVar*>(paramList.at(ivar)))->setVal(cenVal-Z*errVal) ;
2719 minusVar.push_back(frame->getCurve()) ;
2720 frame->remove(nullptr,false) ;
2721
2722 (static_cast<RooRealVar*>(paramList.at(ivar)))->setVal(cenVal) ;
2723 }
2724
2725 TMatrixDSym C(paramList.size()) ;
2726 std::vector<double> errVec(paramList.size()) ;
2727 for (std::size_t i=0 ; i<paramList.size() ; i++) {
2728 errVec[i] = sqrt(V(i,i)) ;
2729 for (std::size_t j=i ; j<paramList.size() ; j++) {
2730 C(i,j) = V(i,j)/sqrt(V(i,i)*V(j,j)) ;
2731 C(j,i) = C(i,j) ;
2732 }
2733 }
2734
2735 band = cenCurve->makeErrorBand(plusVar,minusVar,C,Z) ;
2736
2737
2738 // Cleanup
2739 delete cloneFunc ;
2740 for (std::vector<RooCurve*>::iterator i=plusVar.begin() ; i!=plusVar.end() ; ++i) {
2741 delete (*i) ;
2742 }
2743 for (std::vector<RooCurve*>::iterator i=minusVar.begin() ; i!=minusVar.end() ; ++i) {
2744 delete (*i) ;
2745 }
2746
2747 }
2748
2749 delete cenCurve ;
2750 if (!band) return frame ;
2751
2752 // Define configuration for this method
2753 RooCmdConfig pc("RooAbsPdf::plotOn(" + std::string(GetName()) + ")");
2754 pc.defineString("drawOption","DrawOption",0,"F") ;
2755 pc.defineString("curveNameSuffix","CurveNameSuffix",0,"") ;
2756 pc.defineInt("lineColor","LineColor",0,-999) ;
2757 pc.defineInt("lineStyle","LineStyle",0,-999) ;
2758 pc.defineInt("lineWidth","LineWidth",0,-999) ;
2759 pc.defineInt("markerColor","MarkerColor",0,-999) ;
2760 pc.defineInt("markerStyle","MarkerStyle",0,-999) ;
2761 pc.defineDouble("markerSize","MarkerSize",0,-999) ;
2762 pc.defineInt("fillColor","FillColor",0,-999) ;
2763 pc.defineInt("fillStyle","FillStyle",0,-999) ;
2764 pc.defineString("curveName","Name",0,"") ;
2765 pc.defineInt("curveInvisible","Invisible",0,0) ;
2766 pc.defineInt("moveToBack","MoveToBack",0,0) ;
2767 pc.allowUndefined() ;
2768
2769 // Process & check varargs
2770 pc.process(argList) ;
2771 if (!pc.ok(true)) {
2772 return frame ;
2773 }
2774
2775 // Insert error band in plot frame
2776 frame->addPlotable(band,pc.getString("drawOption"),pc.getInt("curveInvisible")) ;
2777
2778 // Optionally adjust line/fill attributes
2779 Int_t lineColor = pc.getInt("lineColor") ;
2780 Int_t lineStyle = pc.getInt("lineStyle") ;
2781 Int_t lineWidth = pc.getInt("lineWidth") ;
2782 Int_t markerColor = pc.getInt("markerColor") ;
2783 Int_t markerStyle = pc.getInt("markerStyle") ;
2784 Size_t markerSize = pc.getDouble("markerSize") ;
2785 Int_t fillColor = pc.getInt("fillColor") ;
2786 Int_t fillStyle = pc.getInt("fillStyle") ;
2787 if (lineColor!=-999) frame->getAttLine()->SetLineColor(lineColor) ;
2788 if (lineStyle!=-999) frame->getAttLine()->SetLineStyle(lineStyle) ;
2789 if (lineWidth!=-999) frame->getAttLine()->SetLineWidth(lineWidth) ;
2790 if (fillColor!=-999) frame->getAttFill()->SetFillColor(fillColor) ;
2791 if (fillStyle!=-999) frame->getAttFill()->SetFillStyle(fillStyle) ;
2792 if (markerColor!=-999) frame->getAttMarker()->SetMarkerColor(markerColor) ;
2793 if (markerStyle!=-999) frame->getAttMarker()->SetMarkerStyle(markerStyle) ;
2794 if (markerSize!=-999) frame->getAttMarker()->SetMarkerSize(markerSize) ;
2795
2796 // Adjust name if requested
2797 if (pc.getString("curveName",nullptr,true)) {
2798 band->SetName(pc.getString("curveName",nullptr,true)) ;
2799 } else if (pc.getString("curveNameSuffix",nullptr,true)) {
2800 TString name(band->GetName()) ;
2801 name.Append(pc.getString("curveNameSuffix",nullptr,true)) ;
2802 band->SetName(name.Data()) ;
2803 }
2804
2805 // Move last inserted object to back to drawing stack if requested
2806 if (pc.getInt("moveToBack") && frame->numItems()>1) {
2807 frame->drawBefore(frame->getObject(0)->GetName(), frame->getCurve()->GetName());
2808 }
2809
2810
2811 return frame ;
2812}
2813
2814
2815
2816
2817////////////////////////////////////////////////////////////////////////////////
2818/// Utility function for plotOn(), perform general sanity check on frame to ensure safe plotting operations
2819
2821{
2822 // check that we are passed a valid plot frame to use
2823 if(nullptr == frame) {
2824 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: frame is null" << std::endl;
2825 return true;
2826 }
2827
2828 // check that this frame knows what variable to plot
2829 RooAbsReal* var = frame->getPlotVar() ;
2830 if(!var) {
2831 coutE(Plotting) << ClassName() << "::" << GetName()
2832 << ":plotOn: frame does not specify a plot variable" << std::endl;
2833 return true;
2834 }
2835
2836 // check that the plot variable is not derived
2837 if(!dynamic_cast<RooAbsRealLValue*>(var)) {
2838 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: cannot plot variable \""
2839 << var->GetName() << "\" of type " << var->ClassName() << std::endl;
2840 return true;
2841 }
2842
2843 // check if we actually depend on the plot variable
2844 if(!this->dependsOn(*var)) {
2845 coutE(Plotting) << ClassName() << "::" << GetName() << ":plotOn: WARNING: variable is not an explicit dependent: "
2846 << var->GetName() << std::endl;
2847 }
2848
2849 return false ;
2850}
2851
2852
2853
2854
2855////////////////////////////////////////////////////////////////////////////////
2856/// Utility function for plotOn() that constructs the set of
2857/// observables to project when plotting ourselves as function of
2858/// 'plotVar'. 'allVars' is the list of variables that must be
2859/// projected, but may contain variables that we do not depend on. If
2860/// 'silent' is cleared, warnings about inconsistent input parameters
2861/// will be printed.
2862
2864 RooArgSet& projectedVars, bool silent) const
2865{
2866 cxcoutD(Plotting) << "RooAbsReal::makeProjectionSet(" << GetName() << ") plotVar = " << plotVar->GetName()
2867 << " allVars = " << (allVars?(*allVars):RooArgSet()) << std::endl ;
2868
2869 projectedVars.removeAll() ;
2870 if (!allVars) return ;
2871
2872 // Start out with suggested list of variables
2873 projectedVars.add(*allVars) ;
2874
2875 // Take out plot variable
2876 RooAbsArg *found= projectedVars.find(plotVar->GetName());
2877 if(found) {
2878 projectedVars.remove(*found);
2879
2880 // Take out eventual servers of plotVar
2881 std::unique_ptr<RooArgSet> plotServers{plotVar->getObservables(&projectedVars)};
2882 for(RooAbsArg * ps : *plotServers) {
2883 RooAbsArg* tmp = projectedVars.find(ps->GetName()) ;
2884 if (tmp) {
2885 cxcoutD(Plotting) << "RooAbsReal::makeProjectionSet(" << GetName() << ") removing " << tmp->GetName()
2886 << " from projection set because it a server of " << plotVar->GetName() << std::endl ;
2887 projectedVars.remove(*tmp) ;
2888 }
2889 }
2890
2891 if (!silent) {
2892 coutW(Plotting) << "RooAbsReal::plotOn(" << GetName()
2893 << ") WARNING: cannot project out frame variable ("
2894 << found->GetName() << "), ignoring" << std::endl ;
2895 }
2896 }
2897
2898 // Take out all non-dependents of function
2899 for(RooAbsArg * arg : *allVars) {
2900 if (!dependsOnValue(*arg)) {
2901 projectedVars.remove(*arg,true) ;
2902
2903 cxcoutD(Plotting) << "RooAbsReal::plotOn(" << GetName()
2904 << ") function doesn't depend on projection variable "
2905 << arg->GetName() << ", ignoring" << std::endl ;
2906 }
2907 }
2908}
2909
2910
2911
2912
2913////////////////////////////////////////////////////////////////////////////////
2914/// If true, the current pdf is a selected component (for use in plotting)
2915
2917{
2918 return _selectComp || _globalSelectComp ;
2919}
2920
2921
2922
2923////////////////////////////////////////////////////////////////////////////////
2924/// Global switch controlling the activation of the selectComp() functionality
2925
2930
2931
2932
2933
2934////////////////////////////////////////////////////////////////////////////////
2935/// Create an interface adaptor f(vars) that binds us to the specified variables
2936/// (in arbitrary order). For example, calling bindVars({x1,x3}) on an object
2937/// F(x1,x2,x3,x4) returns an object f(x1,x3) that is evaluated using the
2938/// current values of x2 and x4. The caller takes ownership of the returned adaptor.
2939
2941{
2942 auto binding = std::make_unique<RooRealBinding>(*this,vars,nset,clipInvalid);
2943 if(!binding->isValid()) {
2944 coutE(InputArguments) << ClassName() << "::" << GetName() << ":bindVars: cannot bind to " << vars << std::endl ;
2945 return nullptr;
2946 }
2947 return RooFit::makeOwningPtr(std::unique_ptr<RooAbsFunc>{std::move(binding)});
2948}
2949
2950
2951
2952////////////////////////////////////////////////////////////////////////////////
2953/// Copy the cached value of another RooAbsArg to our cache.
2954/// Warning: This function just copies the cached values of source,
2955/// it is the callers responsibility to make sure the cache is clean.
2956
2957void RooAbsReal::copyCache(const RooAbsArg* source, bool /*valueOnly*/, bool setValDirty)
2958{
2959 auto other = static_cast<const RooAbsReal*>(source);
2960 assert(dynamic_cast<const RooAbsReal*>(source));
2961
2962 _value = other->_treeReadBuffer ? other->_treeReadBuffer->operator double() : other->_value;
2963
2964 if (setValDirty) {
2965 setValueDirty() ;
2966 }
2967}
2968
2969
2970////////////////////////////////////////////////////////////////////////////////
2971
2973{
2974 vstore.addReal(this)->setBuffer(this,&_value);
2975}
2976
2977
2978////////////////////////////////////////////////////////////////////////////////
2979/// Attach object to a branch of given TTree. By default it will
2980/// register the internal value cache RooAbsReal::_value as branch
2981/// buffer for a double tree branch with the same name as this
2982/// object. If no double branch is found with the name of this
2983/// object, this method looks for a Float_t Int_t, UChar_t and UInt_t, etc
2984/// branch. If any of these are found, a TreeReadBuffer
2985/// that branch is created, and saved in _treeReadBuffer.
2986/// TreeReadBuffer::operator double() can be used to convert the values.
2987/// This is used by copyCache().
2989{
2990 // First determine if branch is taken
2993 if (branch) {
2994
2995 // Determine if existing branch is Float_t or double
2996 TLeaf* leaf = static_cast<TLeaf*>(branch->GetListOfLeaves()->At(0)) ;
2997
2998 // Check that leaf is _not_ an array
2999 Int_t dummy ;
3000 TLeaf* counterLeaf = leaf->GetLeafCounter(dummy) ;
3001 if (counterLeaf) {
3002 coutE(Eval) << "RooAbsReal::attachToTree(" << GetName() << ") ERROR: TTree branch " << GetName()
3003 << " is an array and cannot be attached to a RooAbsReal" << std::endl ;
3004 return ;
3005 }
3006
3007 TString typeName(leaf->GetTypeName()) ;
3008
3009
3010 // For different type names, store three items:
3011 // first: A tag attached to this instance. Not used inside RooFit, any more, but users might rely on it.
3012 // second: A function to attach
3013 std::map<std::string, std::pair<std::string, std::function<std::unique_ptr<TreeReadBuffer>()>>> typeMap {
3014 {"Float_t", {"FLOAT_TREE_BRANCH", [&](){ return createTreeReadBuffer<Float_t >(cleanName, t); }}},
3015 {"Int_t", {"INTEGER_TREE_BRANCH", [&](){ return createTreeReadBuffer<Int_t >(cleanName, t); }}},
3016 {"UChar_t", {"BYTE_TREE_BRANCH", [&](){ return createTreeReadBuffer<UChar_t >(cleanName, t); }}},
3017 {"Bool_t", {"BOOL_TREE_BRANCH", [&](){ return createTreeReadBuffer<Bool_t >(cleanName, t); }}},
3018 {"Char_t", {"SIGNEDBYTE_TREE_BRANCH", [&](){ return createTreeReadBuffer<Char_t >(cleanName, t); }}},
3019 {"UInt_t", {"UNSIGNED_INTEGER_TREE_BRANCH", [&](){ return createTreeReadBuffer<UInt_t >(cleanName, t); }}},
3020 {"Long64_t", {"LONG_TREE_BRANCH", [&](){ return createTreeReadBuffer<Long64_t >(cleanName, t); }}},
3021 {"ULong64_t", {"UNSIGNED_LONG_TREE_BRANCH", [&](){ return createTreeReadBuffer<ULong64_t>(cleanName, t); }}},
3022 {"Short_t", {"SHORT_TREE_BRANCH", [&](){ return createTreeReadBuffer<Short_t >(cleanName, t); }}},
3023 {"UShort_t", {"UNSIGNED_SHORT_TREE_BRANCH", [&](){ return createTreeReadBuffer<UShort_t >(cleanName, t); }}},
3024 };
3025
3026 auto typeDetails = typeMap.find(typeName.Data());
3027 if (typeDetails != typeMap.end()) {
3028 coutI(DataHandling) << "RooAbsReal::attachToTree(" << GetName() << ") TTree " << typeDetails->first << " branch " << GetName()
3029 << " will be converted to double precision." << std::endl ;
3030 setAttribute(typeDetails->second.first.c_str(), true);
3031 _treeReadBuffer = typeDetails->second.second().release();
3032 } else {
3033 if (_treeReadBuffer) {
3034 delete _treeReadBuffer;
3035 }
3036 _treeReadBuffer = nullptr;
3037
3038 if (!typeName.CompareTo("Double_t")) {
3040 }
3041 else {
3042 coutE(InputArguments) << "RooAbsReal::attachToTree(" << GetName() << ") data type " << typeName << " is not supported." << std::endl ;
3043 }
3044 }
3045 } else {
3046
3048 format.Append("/D");
3050 }
3051
3052}
3053
3054
3055
3056////////////////////////////////////////////////////////////////////////////////
3057/// Fill the tree branch that associated with this object with its current value
3058
3060{
3061 // First determine if branch is taken
3063 if (!branch) {
3064 coutE(Eval) << "RooAbsReal::fillTreeBranch(" << GetName() << ") ERROR: not attached to tree: " << cleanBranchName() << std::endl ;
3065 assert(0) ;
3066 }
3067 branch->Fill() ;
3068
3069}
3070
3071
3072
3073////////////////////////////////////////////////////////////////////////////////
3074/// (De)Activate associated tree branch
3075
3077{
3079 if (branch) {
3080 t.SetBranchStatus(cleanBranchName(),active?true:false) ;
3081 }
3082}
3083
3084
3085
3086////////////////////////////////////////////////////////////////////////////////
3087/// Create a RooRealVar fundamental object with our properties. The new
3088/// object will be created without any fit limits.
3089
3091{
3092 auto fund = std::make_unique<RooRealVar>(newname?newname:GetName(),GetTitle(),_value,getUnit());
3093 fund->removeRange();
3094 fund->setPlotLabel(getPlotLabel());
3095 fund->setAttribute("fundamentalCopy");
3096 return RooFit::makeOwningPtr<RooAbsArg>(std::move(fund));
3097}
3098
3099
3100
3101////////////////////////////////////////////////////////////////////////////////
3102/// Utility function for use in getAnalyticalIntegral(). If the
3103/// content of proxy 'a' occurs in set 'allDeps' then the argument
3104/// held in 'a' is copied from allDeps to analDeps
3105
3107 const RooArgProxy& a) const
3108{
3109 TList nameList ;
3110 nameList.Add(new TObjString(a.absArg()->GetName())) ;
3112 nameList.Delete() ;
3113 return result ;
3114}
3115
3116
3117
3118////////////////////////////////////////////////////////////////////////////////
3119/// Utility function for use in getAnalyticalIntegral(). If the
3120/// contents of proxies a,b occur in set 'allDeps' then the arguments
3121/// held in a,b are copied from allDeps to analDeps
3122
3124 const RooArgProxy& a, const RooArgProxy& b) const
3125{
3126 TList nameList ;
3127 nameList.Add(new TObjString(a.absArg()->GetName())) ;
3128 nameList.Add(new TObjString(b.absArg()->GetName())) ;
3130 nameList.Delete() ;
3131 return result ;
3132}
3133
3134
3135
3136////////////////////////////////////////////////////////////////////////////////
3137/// Utility function for use in getAnalyticalIntegral(). If the
3138/// contents of proxies a,b,c occur in set 'allDeps' then the arguments
3139/// held in a,b,c are copied from allDeps to analDeps
3140
3142 const RooArgProxy& a, const RooArgProxy& b,
3143 const RooArgProxy& c) const
3144{
3145 TList nameList ;
3146 nameList.Add(new TObjString(a.absArg()->GetName())) ;
3147 nameList.Add(new TObjString(b.absArg()->GetName())) ;
3148 nameList.Add(new TObjString(c.absArg()->GetName())) ;
3150 nameList.Delete() ;
3151 return result ;
3152}
3153
3154
3155
3156////////////////////////////////////////////////////////////////////////////////
3157/// Utility function for use in getAnalyticalIntegral(). If the
3158/// contents of proxies a,b,c,d occur in set 'allDeps' then the arguments
3159/// held in a,b,c,d are copied from allDeps to analDeps
3160
3162 const RooArgProxy& a, const RooArgProxy& b,
3163 const RooArgProxy& c, const RooArgProxy& d) const
3164{
3165 TList nameList ;
3166 nameList.Add(new TObjString(a.absArg()->GetName())) ;
3167 nameList.Add(new TObjString(b.absArg()->GetName())) ;
3168 nameList.Add(new TObjString(c.absArg()->GetName())) ;
3169 nameList.Add(new TObjString(d.absArg()->GetName())) ;
3171 nameList.Delete() ;
3172 return result ;
3173}
3174
3175
3176////////////////////////////////////////////////////////////////////////////////
3177/// Utility function for use in getAnalyticalIntegral(). If the
3178/// contents of 'refset' occur in set 'allDeps' then the arguments
3179/// held in 'refset' are copied from allDeps to analDeps.
3180
3182 const RooArgSet& refset) const
3183{
3184 TList nameList ;
3185 for(RooAbsArg * arg : refset) {
3186 nameList.Add(new TObjString(arg->GetName())) ;
3187 }
3188
3190 nameList.Delete() ;
3191 return result ;
3192}
3193
3194
3195
3196////////////////////////////////////////////////////////////////////////////////
3197/// Check if allArgs contains matching elements for each name in nameList. If it does,
3198/// add the corresponding args from allArgs to matchedArgs and return true. Otherwise
3199/// return false and do not change matchedArgs.
3200
3202 const TList &nameList) const
3203{
3204 RooArgSet matched("matched");
3205 bool isMatched(true);
3207 RooAbsArg *found= allArgs.find(name->String().Data());
3208 if(found) {
3209 matched.add(*found);
3210 }
3211 else {
3212 isMatched= false;
3213 break;
3214 }
3215 }
3216
3217 // nameList may not contain multiple entries with the same name
3218 // that are both matched
3219 if (isMatched && int(matched.size())!=nameList.GetSize()) {
3220 isMatched = false ;
3221 }
3222
3223 if(isMatched) matchedArgs.add(matched);
3224 return isMatched;
3225}
3226
3227
3228
3229////////////////////////////////////////////////////////////////////////////////
3230/// Returns the default numeric integration configuration for all RooAbsReals
3231
3236
3237
3238////////////////////////////////////////////////////////////////////////////////
3239/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3240/// If this object has no specialized configuration, a null pointer is returned.
3241
3246
3247
3248////////////////////////////////////////////////////////////////////////////////
3249/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3250/// If this object has no specialized configuration, a null pointer is returned,
3251/// unless createOnTheFly is true in which case a clone of the default integrator
3252/// configuration is created, installed as specialized configuration, and returned
3253
3255{
3257 _specIntegratorConfig = std::make_unique<RooNumIntConfig>(*defaultIntegratorConfig()) ;
3258 }
3259 return _specIntegratorConfig.get();
3260}
3261
3262
3263
3264////////////////////////////////////////////////////////////////////////////////
3265/// Return the numeric integration configuration used for this object. If
3266/// a specialized configuration was associated with this object, that configuration
3267/// is returned, otherwise the default configuration for all RooAbsReals is returned
3268
3270{
3271 const RooNumIntConfig* config = specialIntegratorConfig() ;
3272 if (config) return config ;
3273 return defaultIntegratorConfig() ;
3274}
3275
3276
3277////////////////////////////////////////////////////////////////////////////////
3278/// Return the numeric integration configuration used for this object. If
3279/// a specialized configuration was associated with this object, that configuration
3280/// is returned, otherwise the default configuration for all RooAbsReals is returned
3281
3283{
3285 if (config) return config ;
3286 return defaultIntegratorConfig() ;
3287}
3288
3289
3290
3291////////////////////////////////////////////////////////////////////////////////
3292/// Set the given integrator configuration as default numeric integration
3293/// configuration for this object
3294
3296{
3297 _specIntegratorConfig = std::make_unique<RooNumIntConfig>(config);
3298}
3299
3300
3301
3302////////////////////////////////////////////////////////////////////////////////
3303/// Remove the specialized numeric integration configuration associated
3304/// with this object
3305
3310
3311
3312
3313
3314////////////////////////////////////////////////////////////////////////////////
3315/// Interface function to force use of a given set of observables
3316/// to interpret function value. Needed for functions or p.d.f.s
3317/// whose shape depends on the choice of normalization such as
3318/// RooAddPdf
3319
3321{
3322}
3323
3324
3325
3326
3327////////////////////////////////////////////////////////////////////////////////
3328/// Interface function to force use of a given normalization range
3329/// to interpret function value. Needed for functions or p.d.f.s
3330/// whose shape depends on the choice of normalization such as
3331/// RooAddPdf
3332
3334{
3335}
3336
3337
3338
3339////////////////////////////////////////////////////////////////////////////////
3340/// Advertise capability to determine maximum value of function for given set of
3341/// observables. If no direct generator method is provided, this information
3342/// will assist the accept/reject generator to operate more efficiently as
3343/// it can skip the initial trial sampling phase to empirically find the function
3344/// maximum
3345
3347{
3348 return 0 ;
3349}
3350
3351
3352
3353////////////////////////////////////////////////////////////////////////////////
3354/// Return maximum value for set of observables identified by code assigned
3355/// in getMaxVal
3356
3357double RooAbsReal::maxVal(Int_t /*code*/) const
3358{
3359 assert(1) ;
3360 return 0 ;
3361}
3362
3363
3364
3365////////////////////////////////////////////////////////////////////////////////
3366/// Interface to insert remote error logging messages received by RooRealMPFE into current error logging stream.
3367
3368void RooAbsReal::logEvalError(const RooAbsReal* originator, const char* origName, const char* message, const char* serverValueString)
3369{
3370 if (evalErrorData().mode == Ignore) {
3371 return ;
3372 }
3373
3374 if (evalErrorData().mode == CountErrors) {
3375 evalErrorData().count++ ;
3376 return ;
3377 }
3378
3379 static bool inLogEvalError = false ;
3380
3381 if (inLogEvalError) {
3382 return ;
3383 }
3385
3386 EvalError ee ;
3387 ee.setMessage(message) ;
3388
3389 if (serverValueString) {
3390 ee.setServerValues(serverValueString) ;
3391 }
3392
3393 if (evalErrorData().mode == PrintErrors) {
3394 oocoutE(nullptr,Eval) << "RooAbsReal::logEvalError(" << "<STATIC>" << ") evaluation error, " << std::endl
3395 << " origin : " << origName << std::endl
3396 << " message : " << ee._msg << std::endl
3397 << " server values: " << ee._srvval << std::endl ;
3398 } else if (evalErrorData().mode == CollectErrors) {
3399 auto &evalErrorList = evalErrorData().errorList[originator];
3400 evalErrorList.first = origName ;
3401 evalErrorList.second.push_back(ee) ;
3402 }
3403
3404
3406}
3407
3408
3409
3410////////////////////////////////////////////////////////////////////////////////
3411/// Log evaluation error message. Evaluation errors may be routed through a different
3412/// protocol than generic RooFit warning message (which go straight through RooMsgService)
3413/// because evaluation errors can occur in very large numbers in the use of likelihood
3414/// evaluations. In logEvalError mode, controlled by global method enableEvalErrorLogging()
3415/// messages reported through this function are not printed but all stored in a list,
3416/// along with server values at the time of reporting. Error messages logged in this
3417/// way can be printed in a structured way, eliminating duplicates and with the ability
3418/// to truncate the list by printEvalErrors. This is the standard mode of error logging
3419/// during MINUIT operations. If enableEvalErrorLogging() is false, all errors
3420/// reported through this method are passed for immediate printing through RooMsgService.
3421/// A string with server names and values is constructed automatically for error logging
3422/// purposes, unless a custom string with similar information is passed as argument.
3423
3424void RooAbsReal::logEvalError(const char* message, const char* serverValueString) const
3425{
3426 if (evalErrorData().mode == Ignore) {
3427 return ;
3428 }
3429
3430 if (evalErrorData().mode == CountErrors) {
3431 evalErrorData().count++ ;
3432 return ;
3433 }
3434
3435 static bool inLogEvalError = false ;
3436
3437 if (inLogEvalError) {
3438 return ;
3439 }
3441
3442 EvalError ee ;
3443 ee.setMessage(message) ;
3444
3445 if (serverValueString) {
3446 ee.setServerValues(serverValueString) ;
3447 } else {
3448 std::string srvval ;
3449 std::ostringstream oss ;
3450 bool first(true) ;
3451 for (Int_t i=0 ; i<numProxies() ; i++) {
3452 RooAbsProxy* p = getProxy(i) ;
3453 if (!p) continue ;
3454 //if (p->name()[0]=='!') continue ;
3455 if (first) {
3456 first=false ;
3457 } else {
3458 oss << ", " ;
3459 }
3460 p->print(oss,true) ;
3461 }
3462 ee.setServerValues(oss.str().c_str()) ;
3463 }
3464
3465 std::ostringstream oss2 ;
3467
3468 if (evalErrorData().mode == PrintErrors) {
3469 coutE(Eval) << "RooAbsReal::logEvalError(" << GetName() << ") evaluation error, " << std::endl
3470 << " origin : " << oss2.str() << std::endl
3471 << " message : " << ee._msg << std::endl
3472 << " server values: " << ee._srvval << std::endl ;
3473 } else if (evalErrorData().mode == CollectErrors) {
3474 auto &evalErrorList = evalErrorData().errorList[this];
3475 if (evalErrorList.second.size() >= 2048) {
3476 // avoid overflowing the error list, so if there are very many, print
3477 // the oldest one first, and pop it off the list
3478 const EvalError& oee = evalErrorList.second.front();
3479 // print to debug stream, since these would normally be suppressed, and
3480 // we do not want to increase the error count in the message service...
3481 ccoutD(Eval) << "RooAbsReal::logEvalError(" << GetName()
3482 << ") delayed evaluation error, " << std::endl
3483 << " origin : " << oss2.str() << std::endl
3484 << " message : " << oee._msg << std::endl
3485 << " server values: " << oee._srvval << std::endl ;
3486 evalErrorList.second.pop_front();
3487 }
3488 evalErrorList.first = oss2.str() ;
3489 evalErrorList.second.push_back(ee) ;
3490 }
3491
3493 //coutE(Tracing) << "RooAbsReal::logEvalError(" << GetName() << ") message = " << message << std::endl ;
3494}
3495
3496
3497
3498
3499////////////////////////////////////////////////////////////////////////////////
3500/// Clear the stack of evaluation error messages
3501
3503{
3504 if (evalErrorData().mode == PrintErrors) {
3505 return ;
3506 } else if (evalErrorData().mode == CollectErrors) {
3507 evalErrorData().errorList.clear() ;
3508 } else {
3509 evalErrorData().count = 0 ;
3510 }
3511}
3512
3513
3514////////////////////////////////////////////////////////////////////////////////
3515/// Retrieve bin boundaries if this distribution is binned in `obs`.
3516/// \param[in] obs Observable to retrieve boundaries for.
3517/// \param[in] xlo Beginning of range.
3518/// \param[in] xhi End of range.
3519/// \return The caller owns the returned std::list.
3520std::list<double>* RooAbsReal::binBoundaries(RooAbsRealLValue& /*obs*/, double /*xlo*/, double /*xhi*/) const {
3521 return nullptr;
3522}
3523
3524
3525////////////////////////////////////////////////////////////////////////////////
3526/// Interface for returning an optional hint for initial sampling points when constructing a curve projected on observable `obs`.
3527/// \param[in] obs Observable to retrieve sampling hint for.
3528/// \param[in] xlo Beginning of range.
3529/// \param[in] xhi End of range.
3530/// \return The caller owns the returned std::list.
3531std::list<double>* RooAbsReal::plotSamplingHint(RooAbsRealLValue& /*obs*/, double /*xlo*/, double /*xhi*/) const {
3532 return nullptr;
3533}
3534
3535////////////////////////////////////////////////////////////////////////////////
3536/// Print all outstanding logged evaluation error on the given ostream. If maxPerNode
3537/// is zero, only the number of errors for each source (object with unique name) is listed.
3538/// If maxPerNode is greater than zero, up to maxPerNode detailed error messages are shown
3539/// per source of errors. A truncation message is shown if there were more errors logged
3540/// than shown.
3541
3543{
3544 if (evalErrorData().mode == CountErrors) {
3545 os << evalErrorData().count << " errors counted" << std::endl;
3546 }
3547
3548 if (maxPerNode < 0)
3549 return;
3550
3551 for (auto const &item : evalErrorData().errorList) {
3552 if (maxPerNode == 0) {
3553
3554 // Only print node name with total number of errors
3555 os << item.second.first;
3556 // item.first->printStream(os,kName|kClassName|kArgs,kInline) ;
3557 os << " has " << item.second.second.size() << " errors" << std::endl;
3558
3559 } else {
3560
3561 // Print node name and details of 'maxPerNode' errors
3562 os << item.second.first << std::endl;
3563 // item.first->printStream(os,kName|kClassName|kArgs,kSingleLine) ;
3564
3565 Int_t i(0);
3566 for (auto const &item2 : item.second.second) {
3567 os << " " << item2._msg << " @ " << item2._srvval << std::endl;
3568 if (i > maxPerNode) {
3569 os << " ... (remaining " << item.second.second.size() - maxPerNode << " messages suppressed)"
3570 << std::endl;
3571 break;
3572 }
3573 i++;
3574 }
3575 }
3576 }
3577}
3578
3579
3580
3581////////////////////////////////////////////////////////////////////////////////
3582/// Return the number of logged evaluation errors since the last clearing.
3583
3585{
3586 auto &evalErrors = evalErrorData();
3587 if (evalErrors.mode == CountErrors) {
3588 return evalErrors.count;
3589 }
3590
3591 Int_t ntot(0);
3592 for (auto const &elem : evalErrors.errorList) {
3593 ntot += elem.second.second.size();
3594 }
3595 return ntot;
3596}
3597
3598
3599
3600////////////////////////////////////////////////////////////////////////////////
3601/// Fix the interpretation of the coefficient of any RooAddPdf component in
3602/// the expression tree headed by this object to the given set of observables.
3603///
3604/// If the force flag is false, the normalization choice is only fixed for those
3605/// RooAddPdf components that have the default 'automatic' interpretation of
3606/// coefficients (i.e. the interpretation is defined by the observables passed
3607/// to getVal()). If force is true, also RooAddPdf that already have a fixed
3608/// interpretation are changed to a new fixed interpretation.
3609
3611{
3612 std::unique_ptr<RooArgSet> compSet{getComponents()};
3613 for(auto * pdf : dynamic_range_cast<RooAbsPdf*>(*compSet)) {
3614 if (pdf) {
3615 if (!addNormSet.empty()) {
3616 pdf->selectNormalization(&addNormSet,force) ;
3617 } else {
3618 pdf->selectNormalization(nullptr,force) ;
3619 }
3620 }
3621 }
3622}
3623
3624
3625
3626////////////////////////////////////////////////////////////////////////////////
3627/// Fix the interpretation of the coefficient of any RooAddPdf component in
3628/// the expression tree headed by this object to the given set of observables.
3629///
3630/// If the force flag is false, the normalization range choice is only fixed for those
3631/// RooAddPdf components that currently use the default full domain to interpret their
3632/// coefficients. If force is true, also RooAddPdf that already have a fixed
3633/// interpretation range are changed to a new fixed interpretation range.
3634
3636{
3637 std::unique_ptr<RooArgSet> compSet{getComponents()};
3638 for(auto * pdf : dynamic_range_cast<RooAbsPdf*>(*compSet)) {
3639 if (pdf) {
3640 pdf->selectNormalizationRange(rangeName,force) ;
3641 }
3642 }
3643}
3644
3645
3646
3647////////////////////////////////////////////////////////////////////////////////
3648/// Interface method for function objects to indicate their preferred order of observables
3649/// for scanning their values into a (multi-dimensional) histogram or RooDataSet. The observables
3650/// to be ordered are offered in argument 'obs' and should be copied in their preferred
3651/// order into argument 'orderedObs', This default implementation indicates no preference
3652/// and copies the original order of 'obs' into 'orderedObs'
3653
3655{
3656 // Dummy implementation, do nothing
3657 orderedObs.removeAll() ;
3658 orderedObs.add(obs) ;
3659}
3660
3661
3662
3663////////////////////////////////////////////////////////////////////////////////
3664/// Calls createRunningIntegral(const RooArgSet&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&, const RooCmdArg&)
3665
3670
3671
3672
3673////////////////////////////////////////////////////////////////////////////////
3674/// Create an object that represents the running integral of the function over one or more observables listed in iset, i.e.
3675/// \f[
3676/// \int_{x_\mathrm{lo}}^x f(x') \, \mathrm{d}x'
3677/// \f]
3678///
3679/// The actual integration calculation is only performed when the return object is evaluated. The name
3680/// of the integral object is automatically constructed from the name of the input function, the variables
3681/// it integrates and the range integrates over. The default strategy to calculate the running integrals is
3682///
3683/// - If the integrand (this object) supports analytical integration, construct an integral object
3684/// that calculate the running integrals value by calculating the analytical integral each
3685/// time the running integral object is evaluated
3686///
3687/// - If the integrand (this object) requires numeric integration to construct the running integral
3688/// create an object of class RooNumRunningInt which first samples the entire function and integrates
3689/// the sampled function numerically. This method has superior performance as there is no need to
3690/// perform a full (numeric) integration for each evaluation of the running integral object, but
3691/// only when one of its parameters has changed.
3692///
3693/// The choice of strategy can be changed with the ScanAll() argument, which forces the use of the
3694/// scanning technique implemented in RooNumRunningInt for all use cases, and with the ScanNone()
3695/// argument which forces the 'integrate each evaluation' technique for all use cases. The sampling
3696/// granularity for the scanning technique can be controlled with the ScanParameters technique
3697/// which allows to specify the number of samples to be taken, and to which order the resulting
3698/// running integral should be interpolated. The default values are 1000 samples and 2nd order
3699/// interpolation.
3700///
3701/// The following named arguments are accepted
3702/// | | Effect on integral creation
3703/// |-|-------------------------------
3704/// | `SupNormSet(const RooArgSet&)` | Observables over which should be normalized _in addition_ to the integration observables
3705/// | `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
3706/// | `ScanNum()` | Apply scanning technique if cdf integral involves numeric integration
3707/// | `ScanAll()` | Always apply scanning technique
3708/// | `ScanNone()` | Never apply scanning technique
3709
3711 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
3712 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
3713{
3714 // Define configuration for this method
3715 RooCmdConfig pc("RooAbsReal::createRunningIntegral(" + std::string(GetName()) + ")");
3716 pc.defineSet("supNormSet","SupNormSet",0,nullptr) ;
3717 pc.defineInt("numScanBins","ScanParameters",0,1000) ;
3718 pc.defineInt("intOrder","ScanParameters",1,2) ;
3719 pc.defineInt("doScanNum","ScanNum",0,1) ;
3720 pc.defineInt("doScanAll","ScanAll",0,0) ;
3721 pc.defineInt("doScanNon","ScanNone",0,0) ;
3722 pc.defineMutex("ScanNum","ScanAll","ScanNone") ;
3723
3724 // Process & check varargs
3726 if (!pc.ok(true)) {
3727 return nullptr ;
3728 }
3729
3730 // Extract values from named arguments
3731 RooArgSet nset ;
3732 if (const RooArgSet* snset = pc.getSet("supNormSet",nullptr)) {
3733 nset.add(*snset) ;
3734 }
3735 Int_t numScanBins = pc.getInt("numScanBins") ;
3736 Int_t intOrder = pc.getInt("intOrder") ;
3737 Int_t doScanNum = pc.getInt("doScanNum") ;
3738 Int_t doScanAll = pc.getInt("doScanAll") ;
3739 Int_t doScanNon = pc.getInt("doScanNon") ;
3740
3741 // If scanning technique is not requested make integral-based cdf and return
3742 if (doScanNon) {
3743 return createIntRI(iset,nset) ;
3744 }
3745 if (doScanAll) {
3746 return createScanRI(iset,nset,numScanBins,intOrder) ;
3747 }
3748 if (doScanNum) {
3749 std::unique_ptr<RooAbsReal> tmp{createIntegral(iset)} ;
3750 Int_t isNum= !static_cast<RooRealIntegral&>(*tmp).numIntRealVars().empty();
3751
3752 if (isNum) {
3753 coutI(NumIntegration) << "RooAbsPdf::createRunningIntegral(" << GetName() << ") integration over observable(s) " << iset << " involves numeric integration," << std::endl
3754 << " constructing cdf though numeric integration of sampled pdf in " << numScanBins << " bins and applying order "
3755 << intOrder << " interpolation on integrated histogram." << std::endl
3756 << " To override this choice of technique use argument ScanNone(), to change scan parameters use ScanParameters(nbins,order) argument" << std::endl ;
3757 }
3758
3759 return isNum ? createScanRI(iset,nset,numScanBins,intOrder) : createIntRI(iset,nset) ;
3760 }
3761 return nullptr;
3762}
3763
3764
3765
3766////////////////////////////////////////////////////////////////////////////////
3767/// Utility function for createRunningIntegral that construct an object
3768/// implementing the numeric scanning technique for calculating the running integral
3769
3771{
3772 std::string name = std::string(GetName()) + "_NUMRUNINT_" + integralNameSuffix(iset,&nset).Data() ;
3773 RooRealVar* ivar = static_cast<RooRealVar*>(iset.first()) ;
3774 ivar->setBins(numScanBins,"numcdf") ;
3775 auto ret = std::make_unique<RooNumRunningInt>(name.c_str(),name.c_str(),*this,*ivar,"numrunint") ;
3776 ret->setInterpolationOrder(intOrder) ;
3777 return RooFit::makeOwningPtr<RooAbsReal>(std::move(ret));
3778}
3779
3780
3781
3782////////////////////////////////////////////////////////////////////////////////
3783/// Utility function for createRunningIntegral. It creates an
3784/// object implementing the standard (analytical) integration
3785/// technique for calculating the running integral.
3786
3788{
3789 // Make list of input arguments keeping only RooRealVars
3791 for(RooAbsArg * arg : iset) {
3792 if (dynamic_cast<RooRealVar*>(arg)) {
3793 ilist.add(*arg) ;
3794 } else {
3795 coutW(InputArguments) << "RooAbsPdf::createRunningIntegral(" << GetName() << ") WARNING ignoring non-RooRealVar input argument " << arg->GetName() << std::endl ;
3796 }
3797 }
3798
3802
3803 // Setup customizer that stores all cloned branches in our non-owning list
3804 RooCustomizer cust(*this,"cdf") ;
3805 cust.setCloneBranchSet(clonedBranchNodes) ;
3806 cust.setOwning(false) ;
3807
3808 // Make integration observable x_prime for each observable x as well as an x_lowbound
3810
3811 // Make clone x_prime of each c.d.f observable x represening running integral
3812 RooRealVar* cloneArg = static_cast<RooRealVar*>(rrv->clone(Form("%s_prime",rrv->GetName()))) ;
3813 cloneList.add(*cloneArg) ;
3814 cust.replaceArg(*rrv,*cloneArg) ;
3815
3816 // Make clone x_lowbound of each c.d.f observable representing low bound of x
3817 RooRealVar* cloneLo = static_cast<RooRealVar*>(rrv->clone(Form("%s_lowbound",rrv->GetName()))) ;
3818 cloneLo->setVal(rrv->getMin()) ;
3819 loList.add(*cloneLo) ;
3820
3821 // Make parameterized binning from [x_lowbound,x] for each x_prime
3822 RooParamBinning pb(*cloneLo,*rrv,100) ;
3823 cloneArg->setBinning(pb,"CDF") ;
3824
3825 }
3826
3827 RooAbsReal* tmp = static_cast<RooAbsReal*>(cust.build()) ;
3828
3829 // Construct final normalization set for c.d.f = integrated observables + any extra specified by user
3830 RooArgSet finalNset(nset) ;
3831 finalNset.add(cloneList,true) ;
3832 std::unique_ptr<RooAbsReal> cdf{tmp->createIntegral(cloneList,finalNset,"CDF")};
3833
3834 // Transfer ownership of cloned items to top-level c.d.f object
3835 cdf->addOwnedComponents(*tmp) ;
3836 cdf->addOwnedComponents(cloneList) ;
3837 cdf->addOwnedComponents(loList) ;
3838
3839 return RooFit::makeOwningPtr(std::move(cdf));
3840}
3841
3842
3843////////////////////////////////////////////////////////////////////////////////
3844/// Return a RooFunctor object bound to this RooAbsReal with given definition of observables
3845/// and parameters
3846
3847RooFunctor* RooAbsReal::functor(const RooArgList& obs, const RooArgList& pars, const RooArgSet& nset) const
3848{
3850 getObservables(&obs, realObs);
3851 if (realObs.size() != obs.size()) {
3852 coutE(InputArguments) << "RooAbsReal::functor(" << GetName() << ") ERROR: one or more specified observables are not variables of this p.d.f" << std::endl ;
3853 return nullptr;
3854 }
3856 getObservables(&pars, realPars);
3857 if (realPars.size() != pars.size()) {
3858 coutE(InputArguments) << "RooAbsReal::functor(" << GetName() << ") ERROR: one or more specified parameters are not variables of this p.d.f" << std::endl ;
3859 return nullptr;
3860 }
3861
3862 return new RooFunctor(*this,obs,pars,nset) ;
3863}
3864
3865
3866
3867////////////////////////////////////////////////////////////////////////////////
3868/// Return a ROOT TF1,2,3 object bound to this RooAbsReal with given definition of observables
3869/// and parameters
3870
3871TF1* RooAbsReal::asTF(const RooArgList& obs, const RooArgList& pars, const RooArgSet& nset) const
3872{
3873 // Check that specified input are indeed variables of this function
3875 getObservables(&obs, realObs) ;
3876 if (realObs.size() != obs.size()) {
3877 coutE(InputArguments) << "RooAbsReal::functor(" << GetName() << ") ERROR: one or more specified observables are not variables of this p.d.f" << std::endl ;
3878 return nullptr ;
3879 }
3881 getObservables(&pars, realPars) ;
3882 if (realPars.size() != pars.size()) {
3883 coutE(InputArguments) << "RooAbsReal::functor(" << GetName() << ") ERROR: one or more specified parameters are not variables of this p.d.f" << std::endl ;
3884 return nullptr ;
3885 }
3886
3887 // Check that all obs and par are of type RooRealVar
3888 for (std::size_t i=0 ; i<obs.size() ; i++) {
3889 if (dynamic_cast<RooRealVar*>(obs.at(i))==nullptr) {
3890 coutE(ObjectHandling) << "RooAbsReal::asTF(" << GetName() << ") ERROR: proposed observable " << obs.at(0)->GetName() << " is not of type RooRealVar" << std::endl ;
3891 return nullptr ;
3892 }
3893 }
3894 for (std::size_t i=0 ; i<pars.size() ; i++) {
3895 if (dynamic_cast<RooRealVar*>(pars.at(i))==nullptr) {
3896 coutE(ObjectHandling) << "RooAbsReal::asTF(" << GetName() << ") ERROR: proposed parameter " << pars.at(0)->GetName() << " is not of type RooRealVar" << std::endl ;
3897 return nullptr ;
3898 }
3899 }
3900
3901 // Create functor and TFx of matching dimension
3902 TF1* tf=nullptr ;
3903 RooFunctor* f ;
3904 switch(obs.size()) {
3905 case 1: {
3906 RooRealVar* x = static_cast<RooRealVar*>(obs.at(0)) ;
3907 f = functor(obs,pars,nset) ;
3908 tf = new TF1(GetName(),f,x->getMin(),x->getMax(),pars.size()) ;
3909 break ;
3910 }
3911 case 2: {
3912 RooRealVar* x = static_cast<RooRealVar*>(obs.at(0)) ;
3913 RooRealVar* y = static_cast<RooRealVar*>(obs.at(1)) ;
3914 f = functor(obs,pars,nset) ;
3915 tf = new TF2(GetName(),f,x->getMin(),x->getMax(),y->getMin(),y->getMax(),pars.size()) ;
3916 break ;
3917 }
3918 case 3: {
3919 RooRealVar* x = static_cast<RooRealVar*>(obs.at(0)) ;
3920 RooRealVar* y = static_cast<RooRealVar*>(obs.at(1)) ;
3921 RooRealVar* z = static_cast<RooRealVar*>(obs.at(2)) ;
3922 f = functor(obs,pars,nset) ;
3923 tf = new TF3(GetName(),f,x->getMin(),x->getMax(),y->getMin(),y->getMax(),z->getMin(),z->getMax(),pars.size()) ;
3924 break ;
3925 }
3926 default:
3927 coutE(InputArguments) << "RooAbsReal::asTF(" << GetName() << ") ERROR: " << obs.size()
3928 << " observables specified, but a ROOT TFx can only have 1,2 or 3 observables" << std::endl ;
3929 return nullptr ;
3930 }
3931
3932 // Set initial parameter values of TFx to those of RooRealVars
3933 for (std::size_t i=0 ; i<pars.size() ; i++) {
3934 RooRealVar* p = static_cast<RooRealVar*>(pars.at(i)) ;
3935 tf->SetParameter(i,p->getVal()) ;
3936 tf->SetParName(i,p->GetName()) ;
3937 //tf->SetParLimits(i,p->getMin(),p->getMax()) ;
3938 }
3939
3940 return tf ;
3941}
3942
3943
3944////////////////////////////////////////////////////////////////////////////////
3945/// Return function representing first, second or third order derivative of this function
3946
3948{
3949 std::string name=Form("%s_DERIV_%s",GetName(),obs.GetName()) ;
3950 std::string title=Form("Derivative of %s w.r.t %s ",GetName(),obs.GetName()) ;
3951 return new RooDerivative(name.c_str(),title.c_str(),*this,obs,order,eps) ;
3952}
3953
3954
3955
3956////////////////////////////////////////////////////////////////////////////////
3957/// Return function representing first, second or third order derivative of this function
3958
3960{
3961 std::string name=Form("%s_DERIV_%s",GetName(),obs.GetName()) ;
3962 std::string title=Form("Derivative of %s w.r.t %s ",GetName(),obs.GetName()) ;
3963 return new RooDerivative(name.c_str(),title.c_str(),*this,obs,normSet,order,eps) ;
3964}
3965
3966
3967
3968////////////////////////////////////////////////////////////////////////////////
3969/// Return function representing moment of function of given order.
3970/// \param[in] obs Observable to calculate the moments for
3971/// \param[in] order Order of the moment
3972/// \param[in] central If true, the central moment is given by \f$ \langle (x- \langle x \rangle )^2 \rangle \f$
3973/// \param[in] takeRoot Calculate the square root
3974
3976{
3977 std::string name=Form("%s_MOMENT_%d%s_%s",GetName(),order,(central?"C":""),obs.GetName()) ;
3978 std::string title=Form("%sMoment of order %d of %s w.r.t %s ",(central?"Central ":""),order,GetName(),obs.GetName()) ;
3979 if (order==1) return new RooFirstMoment(name.c_str(),title.c_str(),*this,obs) ;
3980 if (order==2) return new RooSecondMoment(name.c_str(),title.c_str(),*this,obs,central,takeRoot) ;
3981 return new RooMoment(name.c_str(),title.c_str(),*this,obs,order,central,takeRoot) ;
3982}
3983
3984
3985////////////////////////////////////////////////////////////////////////////////
3986/// Return function representing moment of p.d.f (normalized w.r.t given observables) of given order.
3987/// \param[in] obs Observable to calculate the moments for
3988/// \param[in] normObs Normalise w.r.t. these observables
3989/// \param[in] order Order of the moment
3990/// \param[in] central If true, the central moment is given by \f$ \langle (x- \langle x \rangle )^2 \rangle \f$
3991/// \param[in] takeRoot Calculate the square root
3992/// \param[in] intNormObs If true, the moment of the function integrated over all normalization observables is returned.
3993
3995{
3996 std::string name=Form("%s_MOMENT_%d%s_%s",GetName(),order,(central?"C":""),obs.GetName()) ;
3997 std::string title=Form("%sMoment of order %d of %s w.r.t %s ",(central?"Central ":""),order,GetName(),obs.GetName()) ;
3998
3999 if (order==1) return new RooFirstMoment(name.c_str(),title.c_str(),*this,obs,normObs,intNormObs) ;
4000 if (order==2) return new RooSecondMoment(name.c_str(),title.c_str(),*this,obs,normObs,central,takeRoot,intNormObs) ;
4001 return new RooMoment(name.c_str(),title.c_str(),*this,obs,normObs,order,central,takeRoot,intNormObs) ;
4002}
4003
4004
4005
4006////////////////////////////////////////////////////////////////////////////////
4007///
4008/// Return value of x (in range xmin,xmax) at which function equals yval.
4009/// (Calculation is performed with Brent root finding algorithm)
4010
4011double RooAbsReal::findRoot(RooRealVar& x, double xmin, double xmax, double yval)
4012{
4013 double result(0) ;
4015 return result ;
4016}
4017
4018
4019
4020////////////////////////////////////////////////////////////////////////////////
4021/// Perform a \f$ \chi^2 \f$ fit to given histogram. By default the fit is executed through the MINUIT
4022/// commands MIGRAD, HESSE in succession
4023///
4024/// The following named arguments are supported
4025///
4026/// <table>
4027/// <tr><th> <th> Options to control construction of chi2
4028/// <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.
4029/// This imposes a constraint on the predicted number of events analogous to the extended term in a likelihood fit.
4030/// - 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
4031/// (in RooFit jargon, "if the pdf can be extended").
4032/// - Passing `Extended(true)` when the the pdf makes no prediction on the expected number of events will result in error messages,
4033/// and the chi2 will fall back to the total data weight to scale the normalized pdf.
4034/// - There are cases where the fit **must** be done in extended mode. This happens for example when you have a RooAddPdf
4035/// where the coefficients represent component yields. If the fit is not extended, these coefficients will not be
4036/// well-defined, as the RooAddPdf always normalizes itself. If you pass `Extended(false)` in such a case, an error will be
4037/// printed and you'll most likely get garbage results.
4038/// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name
4039/// <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.
4040/// Multiple comma separated range names can be specified.
4041/// <tr><td> `NumCPU(int num)` <td> Parallelize NLL calculation on num CPUs
4042/// <tr><td> `Optimize(bool flag)` <td> Activate constant term optimization (on by default)
4043/// <tr><td> `IntegrateBins()` <td> Integrate PDF within each bin. This sets the desired precision.
4044///
4045/// <tr><th> <th> Options to control flow of fit procedure
4046/// <tr><td> `InitialHesse(bool flag)` <td> Flag controls if HESSE before MIGRAD as well, off by default
4047/// <tr><td> `Hesse(bool flag)` <td> Flag controls if HESSE is run after MIGRAD, on by default
4048/// <tr><td> `Minos(bool flag)` <td> Flag controls if MINOS is run after HESSE, on by default
4049/// <tr><td> `Minos(const RooArgSet& set)` <td> Only run MINOS on given subset of arguments
4050/// <tr><td> `Save(bool flag)` <td> Flag controls if RooFitResult object is produced and returned, off by default
4051/// <tr><td> `Strategy(Int_t flag)` <td> Set Minuit strategy (0 through 2, default is 1)
4052///
4053/// <tr><th> <th> Options to control informational output
4054/// <tr><td> `Verbose(bool flag)` <td> Flag controls if verbose output is printed (NLL, parameter changes during fit
4055/// <tr><td> `Timer(bool flag)` <td> Time CPU and wall clock consumption of fit steps, off by default
4056/// <tr><td> `PrintLevel(Int_t level)` <td> Set Minuit print level (-1 through 3, default is 1). At -1 all RooFit informational
4057/// messages are suppressed as well
4058/// <tr><td> `Warnings(bool flag)` <td> Enable or disable MINUIT warnings (enabled by default)
4059/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per likelihood evaluation. A negative
4060/// value suppress output completely, a zero value will only print the error count per p.d.f component,
4061/// a positive value is will print details of each error up to numErr messages per p.d.f component.
4062/// </table>
4063///
4064
4066 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
4067 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
4068{
4070 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
4071 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
4072 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
4073 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
4074 return chi2FitTo(data,l) ;
4075}
4076
4077
4078
4079////////////////////////////////////////////////////////////////////////////////
4080/// Calls RooAbsReal::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
4081///
4082/// List of possible commands in the `cmdList`:
4083///
4084/// <table>
4085/// <tr><th> Type of CmdArg <th> Effect on \f$ \chi^2 \f$
4086/// <tr><td>
4087/// <tr><td> `DataError()` <td> Choose between:
4088/// - RooAbsData::Expected: Expected Poisson error (\f$ \sqrt{n_\text{expected}} \f$ from the PDF).
4089/// - RooAbsData::SumW2: The observed error from the square root of the sum of weights,
4090/// i.e., symmetric errors calculated with the standard deviation of a Poisson distribution.
4091/// - RooAbsData::Poisson: Asymmetric errors from the central 68 % interval around a Poisson distribution with mean \f$ n_\text{observed} \f$.
4092/// If for a given bin \f$ n_\text{expected} \f$ is lower than the \f$ n_\text{observed} \f$, the lower uncertainty is taken
4093/// (e.g., the difference between the mean and the 16 % quantile).
4094/// If \f$ n_\text{expected} \f$ is higher than \f$ n_\text{observed} \f$, the higher uncertainty is taken
4095/// (e.g., the difference between the 84 % quantile and the mean).
4096/// - RooAbsData::Auto (default): RooAbsData::Expected for unweighted data, RooAbsData::SumW2 for weighted data.
4097/// <tr><td>
4098/// `Extended()` <td> Use expected number of events of an extended p.d.f as normalization
4099/// <tr><td>
4100/// NumCPU() <td> Activate parallel processing feature
4101/// <tr><td>
4102/// Range() <td> Calculate \f$ \chi^2 \f$ only in selected region
4103/// <tr><td>
4104/// Verbose() <td> Verbose output of GOF framework
4105/// <tr><td>
4106/// IntegrateBins() <td> Integrate PDF within each bin. This sets the desired precision. Only useful for binned fits.
4107/// <tr><td> `SumCoefRange()` <td> Set the range in which to interpret the coefficients of RooAddPdf components
4108/// <tr><td> `SplitRange()` <td> Fit ranges used in different categories get named after the category.
4109/// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
4110/// ```
4111/// myVariable.setRange("range_pi0", 135, 210);
4112/// myVariable.setRange("range_gamma", 50, 210);
4113/// ```
4114/// <tr><td> `ConditionalObservables(Args_t &&... argsOrArgSet)` <td> Define projected observables.
4115/// Arguments can either be multiple RooRealVar or a single RooArgSet containing them.
4116///
4117/// </table>
4118
4120{
4121 return RooFit::makeOwningPtr(RooFit::FitHelpers::fitTo(*this, data, cmdList, true));
4122}
4123
4124
4125
4126
4127////////////////////////////////////////////////////////////////////////////////
4128/// Create a \f$ \chi^2 \f$ variable from a histogram and this function.
4129///
4130/// \param arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8 ordered arguments
4131///
4132/// The list of supported command arguments is given in the documentation for
4133/// 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&).
4134///
4135/// \param data Histogram with data
4136/// \return \f$ \chi^2 \f$ variable
4137
4139 const RooCmdArg &arg3, const RooCmdArg &arg4,
4140 const RooCmdArg &arg5, const RooCmdArg &arg6,
4141 const RooCmdArg &arg7, const RooCmdArg &arg8)
4142{
4144 l.Add((TObject *)&arg1);
4145 l.Add((TObject *)&arg2);
4146 l.Add((TObject *)&arg3);
4147 l.Add((TObject *)&arg4);
4148 l.Add((TObject *)&arg5);
4149 l.Add((TObject *)&arg6);
4150 l.Add((TObject *)&arg7);
4151 l.Add((TObject *)&arg8);
4152 return createChi2(data, l);
4153}
4154
4155////////////////////////////////////////////////////////////////////////////////
4156/// \see RooAbsReal::createChi2(RooDataHist&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
4157/// \param data hist data
4158/// \param cmdList List with RooCmdArg() from the table
4159
4161{
4162 return RooFit::makeOwningPtr(RooFit::FitHelpers::createChi2(*this, data, cmdList));
4163}
4164
4165////////////////////////////////////////////////////////////////////////////////
4166/// Perform a 2-D \f$ \chi^2 \f$ fit using a series of x and y values stored in the dataset `xydata`.
4167/// The y values can either be the event weights, or can be another column designated
4168/// by the YVar() argument. The y value must have errors defined for the \f$ \chi^2 \f$ to
4169/// be well defined.
4170///
4171/// <table>
4172/// <tr><th><th> Options to control construction of the chi-square
4173/// <tr><td> `YVar(RooRealVar& yvar)` <td> Designate given column in dataset as Y value
4174/// <tr><td> `Integrate(bool flag)` <td> Integrate function over range specified by X errors
4175/// rather than take value at bin center.
4176///
4177/// <tr><th><th> Options to control flow of fit procedure
4178/// <tr><td> `InitialHesse(bool flag)` <td> Flag controls if HESSE before MIGRAD as well, off by default
4179/// <tr><td> `Hesse(bool flag)` <td> Flag controls if HESSE is run after MIGRAD, on by default
4180/// <tr><td> `Minos(bool flag)` <td> Flag controls if MINOS is run after HESSE, on by default
4181/// <tr><td> `Minos(const RooArgSet& set)` <td> Only run MINOS on given subset of arguments
4182/// <tr><td> `Save(bool flag)` <td> Flag controls if RooFitResult object is produced and returned, off by default
4183/// <tr><td> `Strategy(Int_t flag)` <td> Set Minuit strategy (0 through 2, default is 1)
4184///
4185/// <tr><th><th> Options to control informational output
4186/// <tr><td> `Verbose(bool flag)` <td> Flag controls if verbose output is printed (NLL, parameter changes during fit
4187/// <tr><td> `Timer(bool flag)` <td> Time CPU and wall clock consumption of fit steps, off by default
4188/// <tr><td> `PrintLevel(Int_t level)` <td> Set Minuit print level (-1 through 3, default is 1). At -1 all RooFit informational
4189/// messages are suppressed as well
4190/// <tr><td> `Warnings(bool flag)` <td> Enable or disable MINUIT warnings (enabled by default)
4191/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per likelihood evaluation. A negative
4192/// value suppress output completely, a zero value will only print the error count per p.d.f component,
4193/// a positive value is will print details of each error up to numErr messages per p.d.f component.
4194/// </table>
4195
4197 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
4198 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
4199{
4201 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
4202 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
4203 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
4204 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
4205 return chi2FitTo(xydata,l) ;
4206}
4207
4208
4209
4210
4211////////////////////////////////////////////////////////////////////////////////
4212/// \copydoc RooAbsReal::chi2FitTo(RooDataSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
4213
4215{
4216 return RooFit::makeOwningPtr(RooFit::FitHelpers::fitTo(*this, xydata, cmdList, true));
4217}
4218
4219
4220
4221
4222////////////////////////////////////////////////////////////////////////////////
4223/// Create a \f$ \chi^2 \f$ from a series of x and y values stored in a dataset.
4224/// The y values can either be the event weights (default), or can be another column designated
4225/// by the YVar() argument. The y value must have errors defined for the \f$ \chi^2 \f$ to
4226/// be well defined.
4227///
4228/// The following named arguments are supported
4229///
4230/// | | Options to control construction of the \f$ \chi^2 \f$
4231/// |-|-----------------------------------------
4232/// | `YVar(RooRealVar& yvar)` | Designate given column in dataset as Y value
4233/// | `Integrate(bool flag)` | Integrate function over range specified by X errors rather than take value at bin center.
4234///
4235
4237 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
4238 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
4239{
4241 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
4242 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
4243 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
4244 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
4245 return createChi2(data,l) ;
4246}
4247
4248
4249////////////////////////////////////////////////////////////////////////////////
4250/// See RooAbsReal::createChi2(RooDataSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
4251
4253{
4254 return RooFit::makeOwningPtr(RooFit::FitHelpers::createChi2(*this, data, cmdList));
4255}
4256
4257
4258
4259////////////////////////////////////////////////////////////////////////////////
4260/// Return current evaluation error logging mode.
4261
4266
4267////////////////////////////////////////////////////////////////////////////////
4268/// Set evaluation error logging mode. Options are
4269///
4270/// PrintErrors - Print each error through RooMsgService() as it occurs
4271/// CollectErrors - Accumulate errors, but do not print them. A subsequent call
4272/// to printEvalErrors() will print a summary
4273/// CountErrors - Accumulate error count, but do not print them.
4274///
4275
4280
4281
4282////////////////////////////////////////////////////////////////////////////////
4283
4285{
4286 std::string plist ;
4287 for (auto const* arg : paramVars) {
4288 if (!dependsOnValue(*arg)) {
4289 coutW(InputArguments) << "RooAbsReal::setParameterizeIntegral(" << GetName()
4290 << ") function does not depend on listed parameter " << arg->GetName() << ", ignoring" << std::endl ;
4291 continue ;
4292 }
4293 if (!plist.empty()) plist += ":" ;
4294 plist += arg->GetName() ;
4295 }
4296 setStringAttribute("CACHEPARAMINT",plist.c_str()) ;
4297}
4298
4299
4300/** Base function for computing multiple values of a RooAbsReal.
4301\param ctx An evaluation context object
4302**/
4304{
4305 std::span<double> output = ctx.output();
4306
4307 // Find all servers that are serving real numbers to us, retrieve their batch data,
4308 // and switch them into "always clean" operating mode, so they return always the last-set value.
4309 struct ServerData {
4311 std::span<const double> batch;
4312 double oldValue;
4314 bool oldValueDirty;
4315 bool oldShapeDirty;
4316 };
4317 std::vector<ServerData> ourServers;
4318 ourServers.reserve(servers().size());
4319
4320 for (auto server : servers()) {
4321 auto serverValues = ctx.at(server);
4322 if(serverValues.empty()) continue;
4323
4324 // maybe we are still missing inhibit dirty here
4325 auto oldOperMode = server->operMode();
4326 // See note at the bottom of this function to learn why we can only set
4327 // the operation mode to "always clean" if there are no other value
4328 // clients.
4329 server->setOperMode(RooAbsArg::AClean);
4330 ourServers.push_back({server,
4332 server->isCategory() ? static_cast<RooAbsCategory const*>(server)->getCurrentIndex() : static_cast<RooAbsReal const*>(server)->_value,
4334 server->_valueDirty,
4335 server->_shapeDirty});
4336 // Prevent the server from evaluating; just return cached result, which we will side load:
4337 }
4338
4339
4340 // Make sure that we restore all state when we finish:
4341 struct RestoreStateRAII {
4342 RestoreStateRAII(std::vector<ServerData>& servers) :
4343 _servers{servers} { }
4344
4346 for (auto& serverData : _servers) {
4347 serverData.server->setCachedValue(serverData.oldValue, true);
4348 serverData.server->setOperMode(serverData.oldOperMode);
4349 serverData.server->_valueDirty = serverData.oldValueDirty;
4350 serverData.server->_shapeDirty = serverData.oldShapeDirty;
4351 }
4352 }
4353
4354 std::vector<ServerData>& _servers;
4355 } restoreState{ourServers};
4356
4357
4358 // Advising to implement the batch interface makes only sense if the batch was not a scalar.
4359 // Otherwise, there would be no speedup benefit.
4360 if(output.size() > 1 && RooMsgService::instance().isActive(this, RooFit::FastEvaluations, RooFit::INFO)) {
4361 coutI(FastEvaluations) << "The class " << ClassName() << " does not implement the faster batch evaluation interface."
4362 << " Consider requesting or implementing it to benefit from a speed up." << std::endl;
4363 }
4364
4365
4366 // For each event, write temporary values into our servers' caches, and run a single-value computation.
4367
4368 for (std::size_t i=0; i < output.size(); ++i) {
4369 for (auto& serv : ourServers) {
4370 serv.server->setCachedValue(serv.batch[std::min(i, serv.batch.size()-1)], false);
4371 }
4372
4373 output[i] = evaluate();
4374 }
4375}
4376
4378
4379 const bool tmpFast = _fast;
4380 const double tmp = _value;
4381
4382 double fullEval = 0.;
4383 try {
4385 }
4386 catch (CachingError& error) {
4387 throw CachingError(std::move(error),
4388 FormatPdfTree() << *this);
4389 }
4390
4391 const double ret = (_fast && !_inhibitDirty) ? _value : fullEval;
4392
4393 if (std::isfinite(ret) && ( ret != 0. ? (ret - fullEval)/ret : ret - fullEval) > 1.E-9) {
4394#ifndef NDEBUG
4396#endif
4398 formatter << "--> (Scalar computation wrong here:)\n"
4399 << GetName() << " " << this << " _fast=" << tmpFast
4400 << "\n\tcached _value=" << std::setprecision(16) << tmp
4401 << "\n\treturning =" << ret
4402 << "\n\trecomputed =" << fullEval
4403 << "\n\tnew _value =" << _value << "] ";
4404 formatter << "\nServers:";
4405 for (const auto server : _serverList) {
4406 formatter << "\n ";
4407 server->printStream(formatter.stream(), kName | kClassName | kArgs | kExtras | kAddress | kValue, kInline);
4408 }
4409
4410 throw CachingError(formatter);
4411 }
4412
4413 return ret;
4414}
4415
4416
4423
4424
4425////////////////////////////////////////////////////////////////////////////////
4426
4428{
4429 for (RooAbsArg* arg : servers()) {
4430 if(auto realArg = dynamic_cast<RooAbsReal*>(arg)) {
4431 realArg->enableOffsetting(flag) ;
4432 }
4433 }
4434}
4435
4436
4437RooAbsReal::Ref::Ref(double val) : _ref{RooFit::RooConst(val)} {}
4438
4439////////////////////////////////////////////////////////////////////////////////
4440/// Calling RooAbsReal::getVal() with an r-value reference is a common
4441/// performance trap, because this usually happens when implicitly constructing
4442/// the RooArgSet to be used as the parameter (for example, in calls like
4443/// `pdf.getVal(x)`).
4444///
4445/// Creating the RooArgSet can cause quite some overhead, especially when the
4446/// evaluated object is just a simple variable. Even worse, many RooFit objects
4447/// internally cache information using the uniqueId() of the normalization set
4448/// as the key. So by constructing normalization sets in place, RooFits caching
4449/// logic is broken.
4450///
4451/// To avoid these kind of problems, getVal() will just throw an error when
4452/// it's called with an r-value reference. This also catches the cases where
4453/// one uses it in Python, implicitly creating the normalization set from a
4454/// Python list or set.
4456{
4457 std::stringstream errMsg;
4458 errMsg << "calling RooAbsReal::getVal() with r-value references to the normalization set is not allowed, because "
4459 "it breaks RooFits caching logic and potentially introduces significant overhead. Please explicitly "
4460 "create the RooArgSet outside the call to getVal().";
4461 coutF(Eval) << errMsg.str() << std::endl;
4462 throw std::runtime_error(errMsg.str());
4463}
#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.
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
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:546
A TTree is a list of TBranches.
Definition TBranch.h:93
1-Dim function class
Definition TF1.h:234
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:2330
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
TAxis * GetZaxis()
Definition TH1.h:346
virtual Int_t GetNbinsY() const
Definition TH1.h:315
virtual Int_t GetNbinsZ() const
Definition TH1.h:316
virtual Int_t GetDimension() const
Definition TH1.h:300
TAxis * GetXaxis()
Definition TH1.h:344
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:4964
virtual Int_t GetNbinsX() const
Definition TH1.h:314
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:9202
TAxis * GetYaxis()
Definition TH1.h:345
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:9218
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:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
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:457
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
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:745
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:8628
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5295
virtual Int_t SetBranchAddress(const char *bname, void *add, TBranch **ptr=nullptr)
Change branch address, dealing with clone trees properly.
Definition TTree.cxx:8479
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:354
RooCmdArg ZVar(const RooAbsRealLValue &var, const RooCmdArg &arg={})
RooCmdArg SupNormSet(const RooArgSet &nset)
RooCmdArg SelectVars(const RooArgSet &vars)
RooCmdArg YVar(const RooAbsRealLValue &var, const RooCmdArg &arg={})
RooCmdArg Binning(const RooAbsBinning &binning)
RooCmdArg NormRange(const char *rangeNameList)
RooCmdArg Cut(const char *cutSpec)
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::string makeSliceCutString(RooArgSet const &sliceDataSet)
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()