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