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