Logo ROOT  
Reference Guide
RooAbsPdf.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 /** \class RooAbsPdf
19  \ingroup Roofitcore
20 
21 ## RooAbsPdf, the base class of all PDFs
22 
23 RooAbsPdf is the abstract interface for all probability density
24 functions. The class provides hybrid analytical/numerical
25 normalization for its implementations, error tracing and a MC
26 generator interface.
27 
28 ### A Minimal PDF Implementation
29 
30 A minimal implementation of a PDF class derived from RooAbsPdf
31 should override the `evaluate()` function. This function should
32 return the PDF's value (which does not need to be normalised).
33 
34 
35 #### Normalization/Integration
36 
37 Although the normalization of a PDF is an integral part of a
38 probability density function, normalization is treated separately
39 in RooAbsPdf. The reason is that a RooAbsPdf object is more than a
40 PDF: it can be a building block for a more complex, composite PDF
41 if any of its variables are functions instead of variables. In
42 such cases the normalization of the composite may not be simply the
43 integral over the dependents of the top level PDF as these are
44 functions with potentially non-trivial Jacobian terms themselves.
45 \note Therefore, no explicit attempt should be made to normalize the
46 function output in evaluate(). In particular, normalisation constants
47 can be omitted to speed up the function evaluations, and included later
48 in the integration of the PDF (see below), which is called rarely in
49 comparison to the `evaluate()` function.
50 
51 In addition, RooAbsPdf objects do not have a static concept of what
52 variables are parameters and what variables are dependents (which
53 need to be integrated over for a correct PDF normalization).
54 Instead, the choice of normalization is always specified each time a
55 normalized value is requested from the PDF via the getVal()
56 method.
57 
58 RooAbsPdf manages the entire normalization logic of each PDF with
59 help of a RooRealIntegral object, which coordinates the integration
60 of a given choice of normalization. By default, RooRealIntegral will
61 perform a fully numeric integration of all dependents. However,
62 PDFs can advertise one or more (partial) analytical integrals of
63 their function, and these will be used by RooRealIntegral, if it
64 determines that this is safe (i.e. no hidden Jacobian terms,
65 multiplication with other PDFs that have one or more dependents in
66 commen etc).
67 
68 #### Implementing analytical integrals
69 To implement analytical integrals, two functions must be implemented. First,
70 
71 ```
72 Int_t getAnalyticalIntegral(const RooArgSet& integSet, RooArgSet& anaIntSet)
73 ```
74 should return the analytical integrals that are supported. `integSet`
75 is the set of dependents for which integration is requested. The
76 function should copy the subset of dependents it can analytically
77 integrate to `anaIntSet`, and return a unique identification code for
78 this integration configuration. If no integration can be
79 performed, zero should be returned. Second,
80 
81 ```
82 Double_t analyticalIntegral(Int_t code)
83 ```
84 
85 implements the actual analytical integral(s) advertised by
86 `getAnalyticalIntegral()`. This function will only be called with
87 codes returned by `getAnalyticalIntegral()`, except code zero.
88 
89 The integration range for each dependent to be integrated can
90 be obtained from the dependent's proxy functions `min()` and
91 `max()`. Never call these proxy functions for any proxy not known to
92 be a dependent via the integration code. Doing so may be
93 ill-defined, e.g. in case the proxy holds a function, and will
94 trigger an assert. Integrated category dependents should always be
95 summed over all of their states.
96 
97 
98 
99 ### Direct generation of observables
100 
101 Distributions for any PDF can be generated with the accept/reject method,
102 but for certain PDFs, more efficient methods may be implemented. To
103 implement direct generation of one or more observables, two
104 functions need to be implemented, similar to those for analytical
105 integrals:
106 
107 ```
108 Int_t getGenerator(const RooArgSet& generateVars, RooArgSet& directVars)
109 ```
110 and
111 ```
112 void generateEvent(Int_t code)
113 ```
114 
115 The first function advertises observables, for which distributions can be generated,
116 similar to the way analytical integrals are advertised. The second
117 function implements the actual generator for the advertised observables.
118 
119 The generated dependent values should be stored in the proxy
120 objects. For this, the assignment operator can be used (i.e. `xProxy
121 = 3.0` ). Never call assign to any proxy not known to be a dependent
122 via the generation code. Doing so may be ill-defined, e.g. in case
123 the proxy holds a function, and will trigger an assert.
124 
125 
126 ### Batched function evaluations (Advanced usage)
127 
128 To speed up computations with large numbers of data events in unbinned fits,
129 it is beneficial to override `evaluateBatch()`. Like this, large batches of
130 computations can be done, without having to call `evaluate()` for each single data event.
131 `evaluateBatch()` should execute the same computation as `evaluate()`, but it
132 may choose an implementation that is capable of SIMD computations.
133 If evaluateBatch is not implemented, the classic and slower `evaluate()` will be
134 called for each data event.
135 */
136 
137 #include "RooAbsPdf.h"
138 
139 #include "RooFit.h"
140 #include "RooMsgService.h"
141 #include "RooDataSet.h"
142 #include "RooArgSet.h"
143 #include "RooArgProxy.h"
144 #include "RooRealProxy.h"
145 #include "RooRealVar.h"
146 #include "RooGenContext.h"
147 #include "RooBinnedGenContext.h"
148 #include "RooPlot.h"
149 #include "RooCurve.h"
150 #include "RooNLLVar.h"
151 #include "RooMinuit.h"
152 #include "RooCategory.h"
153 #include "RooNameReg.h"
154 #include "RooCmdConfig.h"
155 #include "RooGlobalFunc.h"
156 #include "RooAddition.h"
157 #include "RooRandom.h"
158 #include "RooNumIntConfig.h"
159 #include "RooProjectedPdf.h"
160 #include "RooInt.h"
161 #include "RooCustomizer.h"
162 #include "RooConstraintSum.h"
163 #include "RooParamBinning.h"
164 #include "RooNumCdf.h"
165 #include "RooFitResult.h"
166 #include "RooNumGenConfig.h"
167 #include "RooCachedReal.h"
168 #include "RooXYChi2Var.h"
169 #include "RooChi2Var.h"
170 #include "RooMinimizer.h"
171 #include "RooRealIntegral.h"
172 #include "RooWorkspace.h"
173 
174 #include "RooHelpers.h"
175 #include "RooVDTHeaders.h"
176 
177 #include "TClass.h"
178 #include "TMath.h"
179 #include "TPaveText.h"
180 #include "TList.h"
181 #include "TMatrixD.h"
182 #include "TMatrixDSym.h"
183 #include "Math/CholeskyDecomp.h"
184 #include "RooDerivative.h"
185 
186 #include <iostream>
187 #include <string>
188 
189 using namespace std;
190 
192 
194 
195 
198 
199 ////////////////////////////////////////////////////////////////////////////////
200 /// Default constructor
201 
202 RooAbsPdf::RooAbsPdf() : _norm(0), _normSet(0), _specGeneratorConfig(0)
203 {
204  _errorCount = 0 ;
205  _negCount = 0 ;
206  _rawValue = 0 ;
207  _selectComp = kFALSE ;
208  _traceCount = 0 ;
209 }
210 
211 
212 
213 ////////////////////////////////////////////////////////////////////////////////
214 /// Constructor with name and title only
215 
216 RooAbsPdf::RooAbsPdf(const char *name, const char *title) :
217  RooAbsReal(name,title), _norm(0), _normSet(0), _normMgr(this,10), _selectComp(kTRUE), _specGeneratorConfig(0)
218 {
220  setTraceCounter(0) ;
221 }
222 
223 
224 
225 ////////////////////////////////////////////////////////////////////////////////
226 /// Constructor with name, title, and plot range
227 
228 RooAbsPdf::RooAbsPdf(const char *name, const char *title,
229  Double_t plotMin, Double_t plotMax) :
230  RooAbsReal(name,title,plotMin,plotMax), _norm(0), _normSet(0), _normMgr(this,10), _selectComp(kTRUE), _specGeneratorConfig(0)
231 {
233  setTraceCounter(0) ;
234 }
235 
236 
237 
238 ////////////////////////////////////////////////////////////////////////////////
239 /// Copy constructor
240 
241 RooAbsPdf::RooAbsPdf(const RooAbsPdf& other, const char* name) :
242  RooAbsReal(other,name), _norm(0), _normSet(0),
243  _normMgr(other._normMgr,this), _selectComp(other._selectComp), _normRange(other._normRange)
244 {
247 
248  if (other._specGeneratorConfig) {
250  } else {
252  }
253 }
254 
255 
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Destructor
259 
261 {
263 }
264 
265 
266 
267 ////////////////////////////////////////////////////////////////////////////////
268 /// Return current value, normalized by integrating over
269 /// the observables in `nset`. If `nset` is 0, the unnormalized value
270 /// is returned. All elements of `nset` must be lvalues.
271 ///
272 /// Unnormalized values are not cached.
273 /// Doing so would be complicated as `_norm->getVal()` could
274 /// spoil the cache and interfere with returning the cached
275 /// return value. Since unnormalized calls are typically
276 /// done in integration calls, there is no performance hit.
277 
279 {
280 
281  // Special handling of case without normalization set (used in numeric integration of pdfs)
282  if (!nset) {
283  RooArgSet* tmp = _normSet ;
284  _normSet = 0 ;
285  Double_t val = evaluate() ;
286  _normSet = tmp ;
287  Bool_t error = traceEvalPdf(val) ;
288 
289  if (error) {
290  return 0 ;
291  }
292  return val ;
293  }
294 
295 
296  // Process change in last data set used
297  Bool_t nsetChanged(kFALSE) ;
298  if (nset!=_normSet || _norm==0) {
299  nsetChanged = syncNormalization(nset) ;
300  }
301 
302  // Return value of object. Calculated if dirty, otherwise cached value is returned.
303  if (isValueDirty() || nsetChanged || _norm->isValueDirty()) {
304 
305  // Evaluate numerator
306  Double_t rawVal = evaluate() ;
307  Bool_t error = traceEvalPdf(rawVal) ; // Error checking and printing
308 
309  // Evaluate denominator
310  Double_t normVal(_norm->getVal()) ;
311 
312  if (normVal < 0. || (normVal == 0. && rawVal != 0)) {
313  //Unreasonable normalisations. A zero integral can be tolerated if the function vanishes.
314  error=kTRUE ;
315  std::stringstream msg;
316  msg << "p.d.f normalization integral is zero or negative: " << normVal;
317  logEvalError(msg.str().c_str());
318  }
319 
320  // Raise global error flag if problems occur
321  if (error || (rawVal == 0. && normVal == 0.)) {
322  _value = 0 ;
323  } else {
324  _value = rawVal / normVal ;
325  }
326 
328  }
329 
330  return _value ;
331 }
332 
333 
334 ////////////////////////////////////////////////////////////////////////////////
335 /// Compute batch of values for given range, and normalise by integrating over
336 /// the observables in `nset`. If `nset` is `nullptr`, unnormalized values
337 /// are returned. All elements of `nset` must be lvalues.
338 ///
339 /// \param[in] begin Begin of the batch.
340 /// \param[in] maxSize Size of the requested range. May come out smaller.
341 /// \param[in] normSet If not nullptr, normalise results by integrating over
342 /// the variables in this set. The normalisation is only computed once, and applied
343 /// to the full batch.
344 ///
345 RooSpan<const double> RooAbsPdf::getValBatch(std::size_t begin, std::size_t maxSize,
346  const RooArgSet* normSet) const
347 {
348  // Some PDFs do preprocessing here, e.g. of the norm
349  getValV(normSet);
350 
351  if (_allBatchesDirty || _operMode == ADirty) {
353  _allBatchesDirty = false;
354  }
355 
356  // Special handling of case without normalization set (used in numeric integration of pdfs)
357  if (!normSet) {
358  RooArgSet* tmp = _normSet ;
359  _normSet = nullptr;
360  auto outputs = evaluateBatch(begin, maxSize);
361  maxSize = outputs.size();
362  _normSet = tmp;
363 
365 
366  return outputs;
367  }
368 
369 
370  // TODO wait if batch is computing?
372  || _norm->isValueDirty()) {
373 
374  auto outputs = evaluateBatch(begin, maxSize);
375  maxSize = outputs.size();
376 
377  // Evaluate denominator
378  const double normVal = _norm->getVal();
379 
380  if (normVal < 0.
381  || (normVal == 0. && std::any_of(outputs.begin(), outputs.end(), [](double val){return val != 0;}))) {
382  logEvalError(Form("p.d.f normalization integral is zero or negative."
383  "\n\tInt(%s) = %f", GetName(), normVal));
384  }
385 
386  if (normVal != 1. && normVal > 0.) {
387  const double invNorm = 1./normVal;
388  for (double& val : outputs) { //CHECK_VECTORISE
389  val *= invNorm;
390  }
391  }
392 
394  }
395 
396  const auto ret = _batchData.getBatch(begin, maxSize);
397 
398  return ret;
399 }
400 
401 ////////////////////////////////////////////////////////////////////////////////
402 /// Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further information)
403 ///
404 /// This function applies the normalization specified by 'normSet' to the integral returned
405 /// by RooAbsReal::analyticalIntegral(). The passthrough scenario (code=0) is also changed
406 /// to return a normalized answer
407 
408 Double_t RooAbsPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
409 {
410  cxcoutD(Eval) << "RooAbsPdf::analyticalIntegralWN(" << GetName() << ") code = " << code << " normset = " << (normSet?*normSet:RooArgSet()) << endl ;
411 
412 
413  if (code==0) return getVal(normSet) ;
414  if (normSet) {
415  return analyticalIntegral(code,rangeName) / getNorm(normSet) ;
416  } else {
417  return analyticalIntegral(code,rangeName) ;
418  }
419 }
420 
421 
422 
423 ////////////////////////////////////////////////////////////////////////////////
424 /// Check that passed value is positive and not 'not-a-number'. If
425 /// not, print an error, until the error counter reaches its set
426 /// maximum.
427 
429 {
430  // check for a math error or negative value
431  Bool_t error(kFALSE) ;
432  if (TMath::IsNaN(value)) {
433  logEvalError(Form("p.d.f value is Not-a-Number (%f), forcing value to zero",value)) ;
434  error=kTRUE ;
435  }
436  if (value<0) {
437  logEvalError(Form("p.d.f value is less than zero (%f), forcing value to zero",value)) ;
438  error=kTRUE ;
439  }
440 
441  // do nothing if we are no longer tracing evaluations and there was no error
442  if(!error) return error ;
443 
444  // otherwise, print out this evaluations input values and result
445  if(++_errorCount <= 10) {
446  cxcoutD(Tracing) << "*** Evaluation Error " << _errorCount << " ";
447  if(_errorCount == 10) cxcoutD(Tracing) << "(no more will be printed) ";
448  }
449  else {
450  return error ;
451  }
452 
453  Print() ;
454  return error ;
455 }
456 
457 
458 ////////////////////////////////////////////////////////////////////////////////
459 /// Get normalisation term needed to normalise the raw values returned by
460 /// getVal(). Note that `getVal(normalisationVariables)` will automatically
461 /// apply the normalisation term returned here.
462 /// \param nset Set of variables to normalise over.
464 {
465  if (!nset) return 1 ;
466 
467  syncNormalization(nset,kTRUE) ;
468  if (_verboseEval>1) cxcoutD(Tracing) << IsA()->GetName() << "::getNorm(" << GetName() << "): norm(" << _norm << ") = " << _norm->getVal() << endl ;
469 
470  Double_t ret = _norm->getVal() ;
471  if (ret==0.) {
472  if(++_errorCount <= 10) {
473  coutW(Eval) << "RooAbsPdf::getNorm(" << GetName() << ":: WARNING normalization is zero, nset = " ; nset->Print("1") ;
474  if(_errorCount == 10) coutW(Eval) << "RooAbsPdf::getNorm(" << GetName() << ") INFO: no more messages will be printed " << endl ;
475  }
476  }
477 
478  return ret ;
479 }
480 
481 
482 
483 ////////////////////////////////////////////////////////////////////////////////
484 /// Return pointer to RooAbsReal object that implements calculation of integral over observables iset in range
485 /// rangeName, optionally taking the integrand normalized over observables nset
486 
487 const RooAbsReal* RooAbsPdf::getNormObj(const RooArgSet* nset, const RooArgSet* iset, const TNamed* rangeName) const
488 {
489 
490  // Check normalization is already stored
491  CacheElem* cache = (CacheElem*) _normMgr.getObj(nset,iset,0,rangeName) ;
492  if (cache) {
493  return cache->_norm ;
494  }
495 
496  // If not create it now
497  RooArgSet* depList = getObservables(iset) ;
498  RooAbsReal* norm = createIntegral(*depList,*nset, *getIntegratorConfig(), RooNameReg::str(rangeName)) ;
499  delete depList ;
500 
501  // Store it in the cache
502  cache = new CacheElem(*norm) ;
503  _normMgr.setObj(nset,iset,cache,rangeName) ;
504 
505  // And return the newly created integral
506  return norm ;
507 }
508 
509 
510 
511 ////////////////////////////////////////////////////////////////////////////////
512 /// Verify that the normalization integral cached with this PDF
513 /// is valid for given set of normalization observables.
514 ///
515 /// If not, the cached normalization integral (if any) is deleted
516 /// and a new integral is constructed for use with 'nset'.
517 /// Elements in 'nset' can be discrete and real, but must be lvalues.
518 ///
519 /// For functions that declare to be self-normalized by overloading the
520 /// selfNormalized() function, a unit normalization is always constructed.
521 
522 Bool_t RooAbsPdf::syncNormalization(const RooArgSet* nset, Bool_t adjustProxies) const
523 {
524 
525 // cout << IsA()->GetName() << "::syncNormalization(" << GetName() << ") nset = " << nset << " = " << (nset?*nset:RooArgSet()) << endl ;
526 
527  _normSet = (RooArgSet*) nset ;
528 
529  // Check if data sets are identical
530  CacheElem* cache = (CacheElem*) _normMgr.getObj(nset) ;
531  if (cache) {
532 
533  Bool_t nsetChanged = (_norm!=cache->_norm) ;
534  _norm = cache->_norm ;
535 
536 
537 // cout << "returning existing object " << _norm->GetName() << endl ;
538 
539  if (nsetChanged && adjustProxies) {
540  // Update dataset pointers of proxies
541  ((RooAbsPdf*) this)->setProxyNormSet(nset) ;
542  }
543 
544  return nsetChanged ;
545  }
546 
547  // Update dataset pointers of proxies
548  if (adjustProxies) {
549  ((RooAbsPdf*) this)->setProxyNormSet(nset) ;
550  }
551 
552  std::unique_ptr<RooArgSet> depList(getObservables(nset));
553 
554  if (_verboseEval>0) {
555  if (!selfNormalized()) {
556  cxcoutD(Tracing) << IsA()->GetName() << "::syncNormalization(" << GetName()
557  << ") recreating normalization integral " << endl ;
558  if (depList) depList->printStream(ccoutD(Tracing),kName|kValue|kArgs,kSingleLine) ; else ccoutD(Tracing) << "<none>" << endl ;
559  } else {
560  cxcoutD(Tracing) << IsA()->GetName() << "::syncNormalization(" << GetName() << ") selfNormalized, creating unit norm" << endl;
561  }
562  }
563 
564  // Destroy old normalization & create new
565  if (selfNormalized() || !dependsOn(*depList)) {
566  TString ntitle(GetTitle()) ; ntitle.Append(" Unit Normalization") ;
567  TString nname(GetName()) ; nname.Append("_UnitNorm") ;
568  _norm = new RooRealVar(nname.Data(),ntitle.Data(),1) ;
569  } else {
570  const char* nr = (_normRangeOverride.Length()>0 ? _normRangeOverride.Data() : (_normRange.Length()>0 ? _normRange.Data() : 0)) ;
571 
572 // cout << "RooAbsPdf::syncNormalization(" << GetName() << ") rangeName for normalization is " << (nr?nr:"<null>") << endl ;
573  RooAbsReal* normInt = createIntegral(*depList,*getIntegratorConfig(),nr) ;
574  normInt->getVal() ;
575 // cout << "resulting normInt = " << normInt->GetName() << endl ;
576 
577  const char* cacheParamsStr = getStringAttribute("CACHEPARAMINT") ;
578  if (cacheParamsStr && strlen(cacheParamsStr)) {
579 
580  RooArgSet* intParams = normInt->getVariables() ;
581 
582  RooNameSet cacheParamNames ;
583  cacheParamNames.setNameList(cacheParamsStr) ;
584  RooArgSet* cacheParams = cacheParamNames.select(*intParams) ;
585 
586  if (cacheParams->getSize()>0) {
587  cxcoutD(Caching) << "RooAbsReal::createIntObj(" << GetName() << ") INFO: constructing " << cacheParams->getSize()
588  << "-dim value cache for integral over " << *depList << " as a function of " << *cacheParams << " in range " << (nr?nr:"<default>") << endl ;
589  string name = Form("%s_CACHE_[%s]",normInt->GetName(),cacheParams->contentsString().c_str()) ;
590  RooCachedReal* cachedIntegral = new RooCachedReal(name.c_str(),name.c_str(),*normInt,*cacheParams) ;
591  cachedIntegral->setInterpolationOrder(2) ;
592  cachedIntegral->addOwnedComponents(*normInt) ;
593  cachedIntegral->setCacheSource(kTRUE) ;
594  if (normInt->operMode()==ADirty) {
595  cachedIntegral->setOperMode(ADirty) ;
596  }
597  normInt= cachedIntegral ;
598  }
599 
600  delete cacheParams ;
601  delete intParams ;
602  }
603  _norm = normInt ;
604  }
605 
606  // Register new normalization with manager (takes ownership)
607  cache = new CacheElem(*_norm) ;
608  _normMgr.setObj(nset,cache) ;
609 
610 // cout << "making new object " << _norm->GetName() << endl ;
611 
612  return kTRUE ;
613 }
614 
615 
616 
617 ////////////////////////////////////////////////////////////////////////////////
618 /// Reset error counter to given value, limiting the number
619 /// of future error messages for this pdf to 'resetValue'
620 
622 {
623  _errorCount = resetValue ;
624  _negCount = resetValue ;
625 }
626 
627 
628 
629 ////////////////////////////////////////////////////////////////////////////////
630 /// Reset trace counter to given value, limiting the
631 /// number of future trace messages for this pdf to 'value'
632 
634 {
635  if (!allNodes) {
636  _traceCount = value ;
637  return ;
638  } else {
639  RooArgList branchList ;
640  branchNodeServerList(&branchList) ;
641  TIterator* iter = branchList.createIterator() ;
642  RooAbsArg* arg ;
643  while((arg=(RooAbsArg*)iter->Next())) {
644  RooAbsPdf* pdf = dynamic_cast<RooAbsPdf*>(arg) ;
645  if (pdf) pdf->setTraceCounter(value,kFALSE) ;
646  }
647  delete iter ;
648  }
649 
650 }
651 
652 
653 
654 
655 ////////////////////////////////////////////////////////////////////////////////
656 /// Return the log of the current value with given normalization
657 /// An error message is printed if the argument of the log is negative.
658 
660 {
661  Double_t prob = getVal(nset) ;
662 
663  if (fabs(prob)>1e6) {
664  coutW(Eval) << "RooAbsPdf::getLogVal(" << GetName() << ") WARNING: large likelihood value: " << prob << endl ;
665  }
666 
667  if(prob < 0) {
668  logEvalError("getLogVal() top-level p.d.f evaluates to a negative number") ;
669 
670  return std::numeric_limits<double>::quiet_NaN();
671  }
672 
673  if(prob == 0) {
674  logEvalError("getLogVal() top-level p.d.f evaluates to zero") ;
675 
676  return -std::numeric_limits<double>::infinity();
677  }
678 
679  if (TMath::IsNaN(prob)) {
680  logEvalError("getLogVal() top-level p.d.f evaluates to NaN") ;
681 
682  return -std::numeric_limits<double>::infinity();
683  }
684 
685  return log(prob);
686 }
687 
688 
689 ////////////////////////////////////////////////////////////////////////////////
690 /// Check for infinity or NaN.
691 /// \param[in] inputs Array to check
692 /// \return True if either infinity or NaN were found.
693 namespace {
694 template<class T>
695 bool checkInfNaNNeg(const T& inputs) {
696  // check for a math error or negative value
697  bool inf = false;
698  bool nan = false;
699  bool neg = false;
700 
701  for (double val : inputs) { //CHECK_VECTORISE
702  inf |= !std::isfinite(val);
703  nan |= TMath::IsNaN(val); // Works also during fast math
704  neg |= val < 0;
705  }
706 
707  return inf || nan || neg;
708 }
709 }
710 
711 
712 ////////////////////////////////////////////////////////////////////////////////
713 /// Scan through outputs and fix+log all nans and negative values.
714 /// \param[in/out] outputs Array to be scanned & fixed.
715 /// \param[in] begin Begin of event range. Only needed to print the correct event number
716 /// where the error occurred.
717 void RooAbsPdf::logBatchComputationErrors(RooSpan<const double>& outputs, std::size_t begin) const {
718  for (unsigned int i=0; i<outputs.size(); ++i) {
719  const double value = outputs[i];
720  if (TMath::IsNaN(outputs[i])) {
721  logEvalError(Form("p.d.f value of (%s) is Not-a-Number (%f) for entry %zu",
722  GetName(), value, begin+i));
723  } else if (!std::isfinite(outputs[i])){
724  logEvalError(Form("p.d.f value of (%s) is (%f) for entry %zu",
725  GetName(), value, begin+i));
726  } else if (outputs[i] < 0.) {
727  logEvalError(Form("p.d.f value of (%s) is less than zero (%f) for entry %zu",
728  GetName(), value, begin+i));
729  }
730  }
731 }
732 
733 ////////////////////////////////////////////////////////////////////////////////
734 /// Compute the log-likelihoods for all events in the requested batch.
735 /// The arguments are passed over to getValBatch().
736 /// \param[in] begin Start of the batch.
737 /// \param[in] size Maximum size of the batch. Depending on data layout and memory, the batch
738 /// may come back smaller.
739 /// \return Returns a batch of doubles that contains the log probabilities.
740 RooSpan<const double> RooAbsPdf::getLogValBatch(std::size_t begin, std::size_t maxSize,
741  const RooArgSet* normSet) const
742 {
743  auto pdfValues = getValBatch(begin, maxSize, normSet);
744 
745  if (checkInfNaNNeg(pdfValues)) {
746  logBatchComputationErrors(pdfValues, begin);
747  }
748 
749  auto output = _batchData.makeWritableBatchUnInit(begin, pdfValues.size(),
751 
752  for (std::size_t i = 0; i < pdfValues.size(); ++i) { //CHECK_VECTORISE
753  const double prob = pdfValues[i];
754 
755  double theLog = _rf_fast_log(prob);
756 
757  if (prob < 0) {
758  theLog = std::numeric_limits<double>::quiet_NaN();
759  } else if (prob == 0 || TMath::IsNaN(prob)) {
760  theLog = -std::numeric_limits<double>::infinity();
761  }
762 
763  output[i] = theLog;
764  }
765 
766  return output;
767 }
768 
769 ////////////////////////////////////////////////////////////////////////////////
770 /// Return the extended likelihood term (\f$ N_\mathrm{expect} - N_\mathrm{observed} \cdot \log(N_\mathrm{expect} \f$)
771 /// of this PDF for the given number of observed events.
772 ///
773 /// For successful operation, the PDF implementation must indicate that
774 /// it is extendable by overloading `canBeExtended()`, and must
775 /// implement the `expectedEvents()` function.
776 
778 {
779  // check if this PDF supports extended maximum likelihood fits
780  if(!canBeExtended()) {
781  coutE(InputArguments) << fName << ": this PDF does not support extended maximum likelihood"
782  << endl;
783  return 0;
784  }
785 
786  Double_t expected= expectedEvents(nset);
787  if(expected < 0) {
788  coutE(InputArguments) << fName << ": calculated negative expected events: " << expected
789  << endl;
790  return 0;
791  }
792 
793 
794  // Explicitly handle case Nobs=Nexp=0
795  if (fabs(expected)<1e-10 && fabs(observed)<1e-10) {
796  return 0 ;
797  }
798 
799  // Check for errors in Nexpected
800  if (expected<0 || TMath::IsNaN(expected)) {
801  logEvalError("extendedTerm #expected events is <0 or NaN") ;
802  return 0 ;
803  }
804 
805  // calculate and return the negative log-likelihood of the Poisson
806  // factor for this dataset, dropping the constant log(observed!)
807  // Double_t extra=0;
808  // if(observed<1000000) {
809  // Double_t Delta1 = (expected-observed);
810  // Double_t Delta2 = observed*(log(expected)-log(observed+1));
811  // Double_t Const3 = 0.5*log(observed+1);
812  // extra= Delta1 - Delta2 + Const3;
813 
814  // cout << " extra obs = " << observed << " exp = " << expected << endl ;
815  // cout << " extra orig = " << expected - observed*log(expected) << endl ;
816  // cout << " extra orig fix = " << expected - observed*log(expected) + log(TMath::Gamma(observed+1)) << endl ;
817  // cout << " extra new = " << extra << endl ;
818 
819  // } else {
820  // Double_t sigma_square=expected;
821  // Double_t diff=observed-expected;
822  // extra=-log(sigma_square)/2 + (diff*diff)/(2*sigma_square);
823  // }
824 
825  Double_t extra= expected - observed*log(expected);
826 
827 // cout << "RooAbsPdf::extendedTerm(" << GetName() << ") observed = " << observed << " expected = " << expected << endl ;
828 
829  Bool_t trace(kFALSE) ;
830  if(trace) {
831  cxcoutD(Tracing) << fName << "::extendedTerm: expected " << expected << " events, got "
832  << observed << " events. extendedTerm = " << extra << endl;
833  }
834 
835 // cout << "RooAbsPdf::extendedTerm(" << GetName() << ") nExp = " << expected << " nObs = " << observed << endl ;
836  return extra;
837 }
838 
839 
840 
841 ////////////////////////////////////////////////////////////////////////////////
842 /// Construct representation of -log(L) of PDF with given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset
843 /// is binned, a binned likelihood is constructed.
844 ///
845 /// The following named arguments are supported
846 ///
847 /// <table>
848 /// <tr><th> Type of CmdArg <th> Effect on nll
849 /// <tr><td> `ConditionalObservables(const RooArgSet& set)` <td> Do not normalize PDF over listed observables
850 /// <tr><td> `Extended(Bool_t flag)` <td> Add extended likelihood term, off by default
851 /// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name
852 /// <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.
853 /// Multiple comma separated range names can be specified.
854 /// <tr><td> `SumCoefRange(const char* name)` <td> Set the range in which to interpret the coefficients of RooAddPdf components
855 /// <tr><td> `NumCPU(int num, int strat)` <td> Parallelize NLL calculation on num CPUs
856 /// <table>
857 /// <tr><th> Strategy <th> Effect
858 /// <tr><td> 0 = RooFit::BulkPartition (Default) <td> Divide events in N equal chunks
859 /// <tr><td> 1 = RooFit::Interleave <td> Process event i%N in process N. Recommended for binned data with
860 /// a substantial number of zero-bins, which will be distributed across processes more equitably in this strategy
861 /// <tr><td> 2 = RooFit::SimComponents <td> Process each component likelihood of a RooSimultaneous fully in a single process
862 /// and distribute components over processes. This approach can be benificial if normalization calculation time
863 /// dominates the total computation time of a component (since the normalization calculation must be performed
864 /// in each process in strategies 0 and 1. However beware that if the RooSimultaneous components do not share many
865 /// parameters this strategy is inefficient: as most minuit-induced likelihood calculations involve changing
866 /// a single parameter, only 1 of the N processes will be active most of the time if RooSimultaneous components
867 /// do not share many parameters
868 /// <tr><td> 3 = RooFit::Hybrid <td> Follow strategy 0 for all RooSimultaneous components, except those with less than
869 /// 30 dataset entries, for which strategy 2 is followed.
870 /// </table>
871 /// <tr><td> `BatchMode(bool on)` <td> Batch evaluation mode. See createNLL().
872 /// <tr><td> `Optimize(Bool_t flag)` <td> Activate constant term optimization (on by default)
873 /// <tr><td> `SplitRange(Bool_t flag)` <td> Use separate fit ranges in a simultaneous fit. Actual range name for each subsample is assumed to
874 /// be `rangeName_indexState`, where `indexState` is the state of the master index category of the simultaneous fit.
875 /// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
876 /// ```
877 /// myVariable.setRange("range_pi0", 135, 210);
878 /// myVariable.setRange("range_gamma", 50, 210);
879 /// ```
880 /// <tr><td> `Constrain(const RooArgSet&pars)` <td> For p.d.f.s that contain internal parameter constraint terms (that is usually product PDFs, where one
881 /// term of the product depends on parameters but not on the observable(s),), only apply constraints to the given subset of parameters.
882 /// <tr><td> `ExternalConstraints(const RooArgSet& )` <td> Include given external constraints to likelihood by multiplying them with the original likelihood.
883 /// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of normalization observables to be used for the constraint terms.
884 /// If none are specified the constrained parameters are used.
885 /// <tr><td> `GlobalObservablesTag(const char* tagName)` <td> Define the set of normalization observables to be used for the constraint terms by
886 /// a string attribute associated with pdf observables that match the given tagName.
887 /// <tr><td> `Verbose(Bool_t flag)` <td> Controls RooFit informational messages in likelihood construction
888 /// <tr><td> `CloneData(Bool flag)` <td> Use clone of dataset in NLL (default is true)
889 /// <tr><td> `Offset(Bool_t)` <td> Offset likelihood by initial value (so that starting value of FCN in minuit is zero).
890 /// This can improve numeric stability in simultaneous fits with components with large likelihood values
891 /// </table>
892 ///
893 ///
894 
895 RooAbsReal* RooAbsPdf::createNLL(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
896  const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
897 {
898  RooLinkedList l ;
899  l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
900  l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
901  l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
902  l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
903  return createNLL(data,l) ;
904 }
905 
906 
907 
908 
909 ////////////////////////////////////////////////////////////////////////////////
910 /// Construct representation of -log(L) of PDFwith given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset
911 /// is binned, a binned likelihood is constructed.
912 ///
913 /// See RooAbsPdf::createNLL(RooAbsData& data, RooCmdArg arg1, RooCmdArg arg2, RooCmdArg arg3, RooCmdArg arg4,
914 /// RooCmdArg arg5, RooCmdArg arg6, RooCmdArg arg7, RooCmdArg arg8)
915 /// for documentation of options
916 
918 {
919 
920  // Select the pdf-specific commands
921  RooCmdConfig pc(Form("RooAbsPdf::createNLL(%s)",GetName())) ;
922 
923  pc.defineString("rangeName","RangeWithName",0,"",kTRUE) ;
924  pc.defineString("addCoefRange","SumCoefRange",0,"") ;
925  pc.defineString("globstag","GlobalObservablesTag",0,"") ;
926  pc.defineDouble("rangeLo","Range",0,-999.) ;
927  pc.defineDouble("rangeHi","Range",1,-999.) ;
928  pc.defineInt("splitRange","SplitRange",0,0) ;
929  pc.defineInt("ext","Extended",0,2) ;
930  pc.defineInt("numcpu","NumCPU",0,1) ;
931  pc.defineInt("interleave","NumCPU",1,0) ;
932  pc.defineInt("verbose","Verbose",0,0) ;
933  pc.defineInt("optConst","Optimize",0,0) ;
934  pc.defineInt("cloneData","CloneData", 0, 2);
935  pc.defineSet("projDepSet","ProjectedObservables",0,0) ;
936  pc.defineSet("cPars","Constrain",0,0) ;
937  pc.defineSet("glObs","GlobalObservables",0,0) ;
938 // pc.defineInt("constrAll","Constrained",0,0) ;
939  pc.defineInt("doOffset","OffsetLikelihood",0,0) ;
940  pc.defineSet("extCons","ExternalConstraints",0,0) ;
941  pc.defineInt("BatchMode", "BatchMode", 0, 0);
942  pc.defineMutex("Range","RangeWithName") ;
943 // pc.defineMutex("Constrain","Constrained") ;
944  pc.defineMutex("GlobalObservables","GlobalObservablesTag") ;
945 
946  // Process and check varargs
947  pc.process(cmdList) ;
948  if (!pc.ok(kTRUE)) {
949  return 0 ;
950  }
951 
952  // Decode command line arguments
953  const char* rangeName = pc.getString("rangeName",0,kTRUE) ;
954  const char* addCoefRangeName = pc.getString("addCoefRange",0,kTRUE) ;
955  const char* globsTag = pc.getString("globstag",0,kTRUE) ;
956  Int_t ext = pc.getInt("ext") ;
957  Int_t numcpu = pc.getInt("numcpu") ;
958  Int_t numcpu_strategy = pc.getInt("interleave");
959  // strategy 3 works only for RooSimultaneus.
960  if (numcpu_strategy==3 && !this->InheritsFrom("RooSimultaneous") ) {
961  coutW(Minimization) << "Cannot use a NumCpu Strategy = 3 when the pdf is not a RooSimultaneus, "
962  "falling back to default strategy = 0" << endl;
963  numcpu_strategy = 0;
964  }
965  RooFit::MPSplit interl = (RooFit::MPSplit) numcpu_strategy;
966 
967  Int_t splitr = pc.getInt("splitRange") ;
968  Bool_t verbose = pc.getInt("verbose") ;
969  Int_t optConst = pc.getInt("optConst") ;
970  Int_t cloneData = pc.getInt("cloneData") ;
971  Int_t doOffset = pc.getInt("doOffset") ;
972 
973  // If no explicit cloneData command is specified, cloneData is set to true if optimization is activated
974  if (cloneData==2) {
975  cloneData = optConst ;
976  }
977 
978 
979  RooArgSet* cPars = pc.getSet("cPars") ;
980  RooArgSet* glObs = pc.getSet("glObs") ;
981  if (pc.hasProcessed("GlobalObservablesTag")) {
982  if (glObs) delete glObs ;
983  RooArgSet* allVars = getVariables() ;
984  glObs = (RooArgSet*) allVars->selectByAttrib(globsTag,kTRUE) ;
985  coutI(Minimization) << "User-defined specification of global observables definition with tag named '" << globsTag << "'" << endl ;
986  delete allVars ;
987  } else if (!pc.hasProcessed("GlobalObservables")) {
988 
989  // Neither GlobalObservables nor GlobalObservablesTag has been processed - try if a default tag is defined in the head node
990  // Check if head not specifies default global observable tag
991  const char* defGlobObsTag = getStringAttribute("DefaultGlobalObservablesTag") ;
992  if (defGlobObsTag) {
993  coutI(Minimization) << "p.d.f. provides built-in specification of global observables definition with tag named '" << defGlobObsTag << "'" << endl ;
994  if (glObs) delete glObs ;
995  RooArgSet* allVars = getVariables() ;
996  glObs = (RooArgSet*) allVars->selectByAttrib(defGlobObsTag,kTRUE) ;
997  }
998  }
999 
1000 
1001  Bool_t doStripDisconnected=kFALSE ;
1002 
1003  // If no explicit list of parameters to be constrained is specified apply default algorithm
1004  // All terms of RooProdPdfs that do not contain observables and share a parameters with one or more
1005  // terms that do contain observables are added as constraints.
1006  if (!cPars) {
1007  cPars = getParameters(data,kFALSE) ;
1008  doStripDisconnected=kTRUE ;
1009  }
1010  const RooArgSet* extCons = pc.getSet("extCons") ;
1011 
1012  // Process automatic extended option
1013  if (ext==2) {
1014  ext = ((extendMode()==CanBeExtended || extendMode()==MustBeExtended)) ? 1 : 0 ;
1015  if (ext) {
1016  coutI(Minimization) << "p.d.f. provides expected number of events, including extended term in likelihood." << endl ;
1017  }
1018  }
1019 
1020  // Clear possible range attributes from previous fits.
1021  setStringAttribute("fitrange", nullptr);
1022 
1023  if (pc.hasProcessed("Range")) {
1024  Double_t rangeLo = pc.getDouble("rangeLo") ;
1025  Double_t rangeHi = pc.getDouble("rangeHi") ;
1026 
1027  // Create range with name 'fit' with above limits on all observables
1028  RooArgSet* obs = getObservables(&data) ;
1029  for (auto arg : *obs) {
1030  RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
1031  if (rrv) rrv->setRange("fit",rangeLo,rangeHi) ;
1032  }
1033 
1034  // Set range name to be fitted to "fit"
1035  rangeName = "fit" ;
1036  }
1037 
1038  RooArgSet projDeps ;
1039  RooArgSet* tmp = pc.getSet("projDepSet") ;
1040  if (tmp) {
1041  projDeps.add(*tmp) ;
1042  }
1043 
1044  // Construct NLL
1046  RooAbsReal* nll ;
1047  string baseName = Form("nll_%s_%s",GetName(),data.GetName()) ;
1048  if (!rangeName || strchr(rangeName,',')==0) {
1049  // Simple case: default range, or single restricted range
1050  //cout<<"FK: Data test 1: "<<data.sumEntries()<<endl;
1051 
1052  auto theNLL = new RooNLLVar(baseName.c_str(),"-log(likelihood)",
1053  *this,data,projDeps,ext,rangeName,addCoefRangeName,numcpu,interl,
1054  verbose,splitr,cloneData);
1055  theNLL->batchMode(pc.getInt("BatchMode"));
1056  nll = theNLL;
1057  } else {
1058  // Composite case: multiple ranges
1059  RooArgList nllList ;
1060  auto tokens = RooHelpers::tokenise(rangeName, ",");
1061  for (const auto& token : tokens) {
1062  auto nllComp = new RooNLLVar(Form("%s_%s",baseName.c_str(),token.c_str()),"-log(likelihood)",
1063  *this,data,projDeps,ext,token.c_str(),addCoefRangeName,numcpu,interl,
1064  verbose,splitr,cloneData);
1065  nllComp->batchMode(pc.getInt("BatchMode"));
1066  nllList.add(*nllComp) ;
1067  }
1068  nll = new RooAddition(baseName.c_str(),"-log(likelihood)",nllList,kTRUE) ;
1069  }
1071 
1072  // Collect internal and external constraint specifications
1073  RooArgSet allConstraints ;
1074 
1075  if (_myws && _myws->set(Form("CACHE_CONSTR_OF_PDF_%s_FOR_OBS_%s", GetName(), RooNameSet(*data.get()).content()))) {
1076 
1077  // retrieve from cache
1078  const RooArgSet *constr =
1079  _myws->set(Form("CACHE_CONSTR_OF_PDF_%s_FOR_OBS_%s", GetName(), RooNameSet(*data.get()).content()));
1080  coutI(Minimization) << "createNLL picked up cached consraints from workspace with " << constr->getSize()
1081  << " entries" << endl;
1082  allConstraints.add(*constr);
1083 
1084  } else {
1085 
1086  if (cPars && cPars->getSize() > 0) {
1087  RooArgSet *constraints = getAllConstraints(*data.get(), *cPars, doStripDisconnected);
1088  allConstraints.add(*constraints);
1089  delete constraints;
1090  }
1091  if (extCons) {
1092  allConstraints.add(*extCons);
1093  }
1094 
1095  // write to cache
1096  if (_myws) {
1097  // cout << "createNLL: creating cache for allconstraints=" << allConstraints << endl ;
1098  coutI(Minimization) << "createNLL: caching constraint set under name "
1099  << Form("CONSTR_OF_PDF_%s_FOR_OBS_%s", GetName(), RooNameSet(*data.get()).content())
1100  << " with " << allConstraints.getSize() << " entries" << endl;
1102  Form("CACHE_CONSTR_OF_PDF_%s_FOR_OBS_%s", GetName(), RooNameSet(*data.get()).content()), allConstraints);
1103  }
1104  }
1105 
1106  // Include constraints, if any, in likelihood
1107  RooAbsReal* nllCons(0) ;
1108  if (allConstraints.getSize()>0 && cPars) {
1109 
1110  coutI(Minimization) << " Including the following constraint terms in minimization: " << allConstraints << endl ;
1111  if (glObs) {
1112  coutI(Minimization) << "The following global observables have been defined: " << *glObs << endl ;
1113  }
1114  nllCons = new RooConstraintSum(Form("%s_constr",baseName.c_str()),"nllCons",allConstraints,glObs ? *glObs : *cPars) ;
1115  nllCons->setOperMode(ADirty) ;
1116  RooAbsReal* orignll = nll ;
1117 
1118  nll = new RooAddition(Form("%s_with_constr",baseName.c_str()),"nllWithCons",RooArgSet(*nll,*nllCons)) ;
1119  nll->addOwnedComponents(RooArgSet(*orignll,*nllCons)) ;
1120  }
1121 
1122 
1123  if (optConst) {
1125  }
1126 
1127  if (doStripDisconnected) {
1128  delete cPars ;
1129  }
1130 
1131  if (doOffset) {
1132  nll->enableOffsetting(kTRUE) ;
1133  }
1134 
1135  return nll ;
1136 }
1137 
1138 
1139 
1140 
1141 
1142 
1143 ////////////////////////////////////////////////////////////////////////////////
1144 /// Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset
1145 /// is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT
1146 /// commands MIGRAD, HESSE in succession.
1147 /// \param[in] data Data to fit the PDF to
1148 /// \param[in] arg1 One or more arguments to control the behaviour of the fit
1149 /// \return RooFitResult * with the fit status if option Save() is used, 0 otherwise.
1150 ///
1151 /// The following named arguments are supported
1152 ///
1153 /// <table>
1154 /// <tr><th> Type of CmdArg <th> Options to control construction of -log(L)
1155 /// <tr><td> `ConditionalObservables(const RooArgSet& set)` <td> Do not normalize PDF over listed observables
1156 /// <tr><td> `Extended(Bool_t flag)` <td> Add extended likelihood term, off by default
1157 /// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name. Multiple comma-separated range names can be specified.
1158 /// <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.
1159 /// <tr><td> `SumCoefRange(const char* name)` <td> Set the range in which to interpret the coefficients of RooAddPdf components
1160 /// <tr><td> `NumCPU(int num, int strat)` <td> Parallelize NLL calculation on `num` CPUs
1161 /// <table>
1162 /// <tr><th> Strategy <th> Effect
1163 /// <tr><td> 0 = RooFit::BulkPartition (Default) <td> Divide events in N equal chunks
1164 /// <tr><td> 1 = RooFit::Interleave <td> Process event i%N in process N. Recommended for binned data with
1165 /// a substantial number of zero-bins, which will be distributed across processes more equitably in this strategy
1166 /// <tr><td> 2 = RooFit::SimComponents <td> Process each component likelihood of a RooSimultaneous fully in a single process
1167 /// and distribute components over processes. This approach can be benificial if normalization calculation time
1168 /// dominates the total computation time of a component (since the normalization calculation must be performed
1169 /// in each process in strategies 0 and 1. However beware that if the RooSimultaneous components do not share many
1170 /// parameters this strategy is inefficient: as most minuit-induced likelihood calculations involve changing
1171 /// a single parameter, only 1 of the N processes will be active most of the time if RooSimultaneous components
1172 /// do not share many parameters
1173 /// <tr><td> 3 = RooFit::Hybrid <td> Follow strategy 0 for all RooSimultaneous components, except those with less than
1174 /// 30 dataset entries, for which strategy 2 is followed.
1175 /// </table>
1176 /// <tr><td> `SplitRange(Bool_t flag)` <td> Use separate fit ranges in a simultaneous fit. Actual range name for each subsample is assumed
1177 /// to by `rangeName_indexState` where indexState is the state of the master index category of the simultaneous fit.
1178 /// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
1179 /// ```
1180 /// myVariable.setRange("range_pi0", 135, 210);
1181 /// myVariable.setRange("range_gamma", 50, 210);
1182 /// ```
1183 /// <tr><td> `Constrain(const RooArgSet&pars)` <td> For p.d.f.s that contain internal parameter constraint terms (that is usually product PDFs, where one
1184 /// term of the product depends on parameters but not on the observable(s),), only apply constraints to the given subset of parameters.
1185 /// <tr><td> `ExternalConstraints(const RooArgSet& )` <td> Include given external constraints to likelihood by multiplying them with the original likelihood.
1186 /// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of normalization observables to be used for the constraint terms.
1187 /// If none are specified the constrained parameters are used.
1188 /// <tr><td> `Offset(Bool_t)` <td> Offset likelihood by initial value (so that starting value of FCN in minuit is zero).
1189 /// This can improve numeric stability in simultaneously fits with components with large likelihood values
1190 /// <tr><td> `BatchMode(bool on)` <td> **Experimental** batch evaluation mode. This computes a batch of likelihood values at a time,
1191 /// uses faster math functions and possibly auto vectorisation (this depends on the compiler flags).
1192 /// Depending on hardware capabilities, the compiler flags and whether a batch evaluation function was
1193 /// implemented for the PDFs of the model, likelihood computations are 2x to 10x faster.
1194 /// The relative difference of the single log-likelihoods w.r.t. the legacy mode is usually better than 1.E-12,
1195 /// and fit parameters usually agree to better than 1.E-6.
1196 ///
1197 /// <tr><th><th> Options to control flow of fit procedure
1198 /// <tr><td> `Minimizer(type,algo)` <td> Choose minimization package and algorithm to use. Default is MINUIT/MIGRAD through the RooMinimizer interface,
1199 /// but others can be specified (through RooMinimizer interface). Select OldMinuit to use MINUIT through the old RooMinuit interface
1200 /// <table>
1201 /// <tr><th> Type <th> Algorithm
1202 /// <tr><td> OldMinuit <td> migrad, simplex, minimize (=migrad+simplex), migradimproved (=migrad+improve)
1203 /// <tr><td> Minuit <td> migrad, simplex, minimize (=migrad+simplex), migradimproved (=migrad+improve)
1204 /// <tr><td> Minuit2 <td> migrad, simplex, minimize, scan
1205 /// <tr><td> GSLMultiMin <td> conjugatefr, conjugatepr, bfgs, bfgs2, steepestdescent
1206 /// <tr><td> GSLSimAn <td> -
1207 /// </table>
1208 ///
1209 /// <tr><td> `InitialHesse(Bool_t flag)` <td> Flag controls if HESSE before MIGRAD as well, off by default
1210 /// <tr><td> `Optimize(Bool_t flag)` <td> Activate constant term optimization of test statistic during minimization (on by default)
1211 /// <tr><td> `Hesse(Bool_t flag)` <td> Flag controls if HESSE is run after MIGRAD, on by default
1212 /// <tr><td> `Minos(Bool_t flag)` <td> Flag controls if MINOS is run after HESSE, off by default
1213 /// <tr><td> `Minos(const RooArgSet& set)` <td> Only run MINOS on given subset of arguments
1214 /// <tr><td> `Save(Bool_t flag)` <td> Flag controls if RooFitResult object is produced and returned, off by default
1215 /// <tr><td> `Strategy(Int_t flag)` <td> Set Minuit strategy (0 to 2, default is 1)
1216 /// <tr><td> `EvalErrorWall(bool flag=true)` <td> When parameters are in disallowed regions (e.g. PDF is negative), return very high value to fitter
1217 /// to force it out of that region. This can, however, mean that the fitter gets lost in this region. If
1218 /// this happens, try switching it off.
1219 /// <tr><td> `FitOptions(const char* optStr)` <td> \deprecated Steer fit with classic options string (for backward compatibility).
1220 /// \attention Use of this option excludes use of any of the new style steering options.
1221 ///
1222 /// <tr><td> `SumW2Error(Bool_t flag)` <td> Apply correction to errors and covariance matrix.
1223 /// This uses two covariance matrices, one with the weights, the other with squared weights,
1224 /// to obtain the correct errors for weighted likelihood fits. If this option is activated, the
1225 /// corrected covariance matrix is calculated as \f$ V_\mathrm{corr} = V C^{-1} V \f$, where \f$ V \f$ is the original
1226 /// covariance matrix and \f$ C \f$ is the inverse of the covariance matrix calculated using the
1227 /// squared weights. This allows to switch between two interpretations of errors:
1228 /// <table>
1229 /// <tr><th> SumW2Error <th> Interpretation
1230 /// <tr><td> true <td> The errors reflect the uncertainty of the Monte Carlo simulation.
1231 /// Use this if you want to know how much accuracy you can get from the available Monte Carlo statistics.
1232 ///
1233 /// **Example**: Simulation with 1000 events, the average weight is 0.1.
1234 /// The errors are as big as if one fitted to 1000 events.
1235 /// <tr><td> false <td> The errors reflect the errors of a dataset, which is as big as the sum of weights.
1236 /// Use this if you want to know what statistical errors you would get if you had a dataset with as many
1237 /// events as the (weighted) Monte Carlo simulation represents.
1238 ///
1239 /// **Example** (Data as above):
1240 /// The errors are as big as if one fitted to 100 events.
1241 /// </table>
1242 /// <tr><td> `AsymptoticError()` <td> Use the asymptotically correct approach to estimate errors in the presence of weights.
1243 /// This is slower but more accurate than `SumW2Error`. See also https://arxiv.org/abs/1911.01303).
1244 /// <tr><td> `PrefitDataFraction(double fraction)`
1245 /// <td> Runs a prefit on a small dataset of size fraction*(actual data size). This can speed up fits
1246 /// by finding good starting values for the parameters for the actual fit.
1247 /// \warning Prefitting may give bad results when used in binned analysis.
1248 ///
1249 /// <tr><th><th> Options to control informational output
1250 /// <tr><td> `Verbose(Bool_t flag)` <td> Flag controls if verbose output is printed (NLL, parameter changes during fit).
1251 /// <tr><td> `Timer(Bool_t flag)` <td> Time CPU and wall clock consumption of fit steps, off by default.
1252 /// <tr><td> `PrintLevel(Int_t level)` <td> Set Minuit print level (-1 to 3, default is 1). At -1 all RooFit informational messages are suppressed as well.
1253 /// See RooMinimizer::PrintLevel for the meaning of the levels.
1254 /// <tr><td> `Warnings(Bool_t flag)` <td> Enable or disable MINUIT warnings (enabled by default)
1255 /// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per likelihood evaluation.
1256 /// A negative value suppresses output completely, a zero value will only print the error count per p.d.f component,
1257 /// a positive value will print details of each error up to `numErr` messages per p.d.f component.
1258 /// </table>
1259 ///
1260 
1261 RooFitResult* RooAbsPdf::fitTo(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
1262  const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1263 {
1264  RooLinkedList l ;
1265  l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
1266  l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
1267  l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
1268  l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
1269  return fitTo(data,l) ;
1270 }
1271 
1272 
1273 
1274 ////////////////////////////////////////////////////////////////////////////////
1275 /// Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset
1276 /// is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT
1277 /// commands MIGRAD, HESSE and MINOS in succession.
1278 ///
1279 /// See RooAbsPdf::fitTo(RooAbsData&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&)
1280 ///
1281 /// for documentation of options
1282 
1284 {
1285  // Select the pdf-specific commands
1286  RooCmdConfig pc(Form("RooAbsPdf::fitTo(%s)",GetName())) ;
1287 
1288  RooLinkedList fitCmdList(cmdList) ;
1289  RooLinkedList nllCmdList = pc.filterCmdList(fitCmdList,"ProjectedObservables,Extended,Range,"
1290  "RangeWithName,SumCoefRange,NumCPU,SplitRange,Constrained,Constrain,ExternalConstraints,"
1291  "CloneData,GlobalObservables,GlobalObservablesTag,OffsetLikelihood,BatchMode");
1292 
1293  pc.defineDouble("prefit", "Prefit",0,0);
1294  pc.defineString("fitOpt","FitOptions",0,"") ;
1295  pc.defineInt("optConst","Optimize",0,2) ;
1296  pc.defineInt("verbose","Verbose",0,0) ;
1297  pc.defineInt("doSave","Save",0,0) ;
1298  pc.defineInt("doTimer","Timer",0,0) ;
1299  pc.defineInt("plevel","PrintLevel",0,1) ;
1300  pc.defineInt("strat","Strategy",0,1) ;
1301  pc.defineInt("initHesse","InitialHesse",0,0) ;
1302  pc.defineInt("hesse","Hesse",0,1) ;
1303  pc.defineInt("minos","Minos",0,0) ;
1304  pc.defineInt("ext","Extended",0,2) ;
1305  pc.defineInt("numcpu","NumCPU",0,1) ;
1306  pc.defineInt("numee","PrintEvalErrors",0,10) ;
1307  pc.defineInt("doEEWall","EvalErrorWall",0,1) ;
1308  pc.defineInt("doWarn","Warnings",0,1) ;
1309  pc.defineInt("doSumW2","SumW2Error",0,-1) ;
1310  pc.defineInt("doAsymptoticError","AsymptoticError",0,-1) ;
1311  pc.defineInt("doOffset","OffsetLikelihood",0,0) ;
1312  pc.defineString("mintype","Minimizer",0,"Minuit") ;
1313  pc.defineString("minalg","Minimizer",1,"minuit") ;
1314  pc.defineObject("minosSet","Minos",0,0) ;
1315  pc.defineSet("cPars","Constrain",0,0) ;
1316  pc.defineSet("extCons","ExternalConstraints",0,0) ;
1317  pc.defineMutex("FitOptions","Verbose") ;
1318  pc.defineMutex("FitOptions","Save") ;
1319  pc.defineMutex("FitOptions","Timer") ;
1320  pc.defineMutex("FitOptions","Strategy") ;
1321  pc.defineMutex("FitOptions","InitialHesse") ;
1322  pc.defineMutex("FitOptions","Hesse") ;
1323  pc.defineMutex("FitOptions","Minos") ;
1324  pc.defineMutex("Range","RangeWithName") ;
1325  pc.defineMutex("InitialHesse","Minimizer") ;
1326 
1327  // Process and check varargs
1328  pc.process(fitCmdList) ;
1329  if (!pc.ok(kTRUE)) {
1330  return 0 ;
1331  }
1332 
1333  // Decode command line arguments
1334  Double_t prefit = pc.getDouble("prefit");
1335  const char* fitOpt = pc.getString("fitOpt",0,kTRUE) ;
1336  Int_t optConst = pc.getInt("optConst") ;
1337  Int_t verbose = pc.getInt("verbose") ;
1338  Int_t doSave = pc.getInt("doSave") ;
1339  Int_t doTimer = pc.getInt("doTimer") ;
1340  Int_t plevel = pc.getInt("plevel") ;
1341  Int_t strat = pc.getInt("strat") ;
1342  Int_t initHesse= pc.getInt("initHesse") ;
1343  Int_t hesse = pc.getInt("hesse") ;
1344  Int_t minos = pc.getInt("minos") ;
1345  Int_t numee = pc.getInt("numee") ;
1346  Int_t doEEWall = pc.getInt("doEEWall") ;
1347  Int_t doWarn = pc.getInt("doWarn") ;
1348  Int_t doSumW2 = pc.getInt("doSumW2") ;
1349  Int_t doAsymptotic = pc.getInt("doAsymptoticError");
1350  const RooArgSet* minosSet = static_cast<RooArgSet*>(pc.getObject("minosSet")) ;
1351 #ifdef __ROOFIT_NOROOMINIMIZER
1352  const char* minType =0 ;
1353 #else
1354  const char* minType = pc.getString("mintype","Minuit") ;
1355  const char* minAlg = pc.getString("minalg","minuit") ;
1356 #endif
1357 
1358  // Determine if the dataset has weights
1359  Bool_t weightedData = data.isNonPoissonWeighted() ;
1360 
1361  // Warn user that a method to determine parameter uncertainties should be provided if weighted data is offered
1362  if (weightedData && doSumW2==-1 && doAsymptotic==-1) {
1363  coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: a likelihood fit is requested of what appears to be weighted data.\n"
1364  << " While the estimated values of the parameters will always be calculated taking the weights into account,\n"
1365  << " there are multiple ways to estimate the errors of the parameters. You are advised to make an \n"
1366  << " explicit choice for the error calculation:\n"
1367  << " - Either provide SumW2Error(true), to calculate a sum-of-weights-corrected HESSE error matrix\n"
1368  << " (error will be proportional to the number of events in MC).\n"
1369  << " - Or provide SumW2Error(false), to return errors from original HESSE error matrix\n"
1370  << " (which will be proportional to the sum of the weights, i.e., a dataset with <sum of weights> events).\n"
1371  << " - Or provide AsymptoticError(true), to use the asymptotically correct expression\n"
1372  << " (for details see https://arxiv.org/abs/1911.01303)."
1373  << endl ;
1374  }
1375 
1376 
1377  // Warn user that sum-of-weights correction does not apply to MINOS errrors
1378  if (doSumW2==1 && minos) {
1379  coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: sum-of-weights correction does not apply to MINOS errors" << endl ;
1380  }
1381  if (doAsymptotic==1 && minos) {
1382  coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: asymptotic correction does not apply to MINOS errors" << endl ;
1383  }
1384 
1385  if (prefit != 0) {
1386  size_t nEvents = static_cast<size_t>(prefit*data.numEntries());
1387  if (prefit > 0.5 || nEvents < 100) {
1388  oocoutW(this,InputArguments) << "PrefitDataFraction should be in suitable range."
1389  << "With the current PrefitDataFraction=" << prefit
1390  << ", the number of events would be " << nEvents<< " out of "
1391  << data.numEntries() << ". Skipping prefit..." << endl;
1392  }
1393  else {
1394  size_t step = data.numEntries()/nEvents;
1395  RooArgSet tinyVars(*data.get());
1396  RooRealVar weight("weight","weight",1);
1397 
1398  if (data.isWeighted()) tinyVars.add(weight);
1399 
1400  RooDataSet tiny("tiny", "tiny", tinyVars,
1401  data.isWeighted() ? RooFit::WeightVar(weight) : RooCmdArg());
1402 
1403  for (int i=0; i<data.numEntries(); i+=step)
1404  {
1405  const RooArgSet *event = data.get(i);
1406  tiny.add(*event, data.weight());
1407  }
1408  RooLinkedList tinyCmdList(cmdList) ;
1409  pc.filterCmdList(tinyCmdList,"Prefit,Hesse,Minos,Verbose,Save,Timer");
1410  RooCmdArg hesse_option = RooFit::Hesse(false);
1411  RooCmdArg print_option = RooFit::PrintLevel(-1);
1412 
1413  tinyCmdList.Add(&hesse_option);
1414  tinyCmdList.Add(&print_option);
1415 
1416  fitTo(tiny,tinyCmdList);
1417  }
1418  }
1419 
1420  RooAbsReal* nll = createNLL(data,nllCmdList) ;
1421  RooFitResult *ret = 0 ;
1422 
1423  //avoid setting both SumW2 and Asymptotic for uncertainty correction
1424  if (doSumW2==1 && doAsymptotic==1) {
1425  coutE(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") ERROR: Cannot compute both asymptotically correct and SumW2 errors." << endl ;
1426  return ret;
1427  }
1428 
1429  // Instantiate MINUIT
1430 
1431  if (string(minType)!="OldMinuit") {
1432 
1433 #ifndef __ROOFIT_NOROOMINIMIZER
1434  RooMinimizer m(*nll) ;
1435 
1436  m.setMinimizerType(minType) ;
1437 
1438  m.setEvalErrorWall(doEEWall) ;
1439  if (doWarn==0) {
1440  // m.setNoWarn() ; WVE FIX THIS
1441  }
1442 
1443  m.setPrintEvalErrors(numee) ;
1444  if (plevel!=1) {
1445  m.setPrintLevel(plevel) ;
1446  }
1447 
1448  if (optConst) {
1449  // Activate constant term optimization
1450  m.optimizeConst(optConst) ;
1451  }
1452 
1453  if (fitOpt) {
1454 
1455  // Play fit options as historically defined
1456  ret = m.fit(fitOpt) ;
1457 
1458  } else {
1459 
1460  if (verbose) {
1461  // Activate verbose options
1462  m.setVerbose(1) ;
1463  }
1464  if (doTimer) {
1465  // Activate timer options
1466  m.setProfile(1) ;
1467  }
1468 
1469  if (strat!=1) {
1470  // Modify fit strategy
1471  m.setStrategy(strat) ;
1472  }
1473 
1474  if (initHesse) {
1475  // Initialize errors with hesse
1476  m.hesse() ;
1477  }
1478 
1479  // Minimize using chosen algorithm
1480  m.minimize(minType,minAlg) ;
1481 
1482  if (hesse) {
1483  // Evaluate errors with Hesse
1484  m.hesse() ;
1485  }
1486 
1487  //asymptotically correct approach
1488  if (doAsymptotic==1 && m.getNPar()>0) {
1489  //Calculated corrected errors for weighted likelihood fits
1490  std::unique_ptr<RooFitResult> rw(m.save());
1491  //Weighted inverse Hessian matrix
1492  const TMatrixDSym& matV = rw->covarianceMatrix();
1493  coutI(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") Calculating covariance matrix according to the asymptotically correct approach. If you find this method useful please consider citing https://arxiv.org/abs/1911.01303." << endl;
1494 
1495  //Initialise matrix containing first derivatives
1496  TMatrixDSym num(rw->floatParsFinal().getSize());
1497  for (int k=0; k<rw->floatParsFinal().getSize(); k++)
1498  for (int l=0; l<rw->floatParsFinal().getSize(); l++)
1499  num(k,l) = 0.0;
1500  RooArgSet* obs = getObservables(data);
1501  //Create derivative objects
1502  std::vector<std::unique_ptr<RooDerivative> > derivatives;
1503  const RooArgList& floated = rw->floatParsFinal();
1504  std::unique_ptr<RooArgSet> floatingparams( (RooArgSet*)getParameters(data)->selectByAttrib("Constant", false) );
1505  for (const auto paramresult : floated) {
1506  auto paraminternal = static_cast<RooRealVar*>(floatingparams->find(*paramresult));
1507  assert(floatingparams->find(*paramresult)->IsA() == RooRealVar::Class());
1508  std::unique_ptr<RooDerivative> deriv( derivative(*paraminternal, *obs, 1) );
1509  derivatives.push_back(std::move(deriv));
1510  }
1511 
1512  //Loop over data
1513  for (int j=0; j<data.numEntries(); j++) {
1514  //Sets obs to current data point, this is where the pdf will be evaluated
1515  *obs = *data.get(j);
1516  //Determine first derivatives
1517  std::vector<Double_t> diffs(floated.getSize(), 0.0);
1518  for (int k=0; k < floated.getSize(); k++) {
1519  const auto paramresult = static_cast<RooRealVar*>(floated.at(k));
1520  auto paraminternal = static_cast<RooRealVar*>(floatingparams->find(*paramresult));
1521  //first derivative to parameter k at best estimate point for this measurement
1522  Double_t diff = derivatives.at(k)->getVal();
1523  //need to reset to best fit point after differentiation
1524  *paraminternal = paramresult->getVal();
1525  diffs.at(k) = diff;
1526  }
1527  //Fill numerator matrix
1528  Double_t prob = getVal(obs);
1529  for (int k=0; k<floated.getSize(); k++) {
1530  for (int l=0; l<floated.getSize(); l++) {
1531  num(k,l) += data.weight()*data.weight()*diffs.at(k)*diffs.at(l)/(prob*prob);
1532  }
1533  }
1534  }
1535  num.Similarity(matV);
1536 
1537  //Propagate corrected errors to parameters objects
1538  m.applyCovarianceMatrix(num);
1539  }
1540 
1541  if (doSumW2==1 && m.getNPar()>0) {
1542  // Make list of RooNLLVar components of FCN
1543  RooArgSet* comps = nll->getComponents();
1544  vector<RooNLLVar*> nllComponents;
1545  nllComponents.reserve(comps->getSize());
1546  TIterator* citer = comps->createIterator();
1547  RooAbsArg* arg;
1548  while ((arg=(RooAbsArg*)citer->Next())) {
1549  RooNLLVar* nllComp = dynamic_cast<RooNLLVar*>(arg);
1550  if (!nllComp) continue;
1551  nllComponents.push_back(nllComp);
1552  }
1553  delete citer;
1554  delete comps;
1555 
1556  // Calculated corrected errors for weighted likelihood fits
1557  RooFitResult* rw = m.save();
1558  for (vector<RooNLLVar*>::iterator it = nllComponents.begin(); nllComponents.end() != it; ++it) {
1559  (*it)->applyWeightSquared(kTRUE);
1560  }
1561  coutI(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") Calculating sum-of-weights-squared correction matrix for covariance matrix" << endl ;
1562  m.hesse();
1563  RooFitResult* rw2 = m.save();
1564  for (vector<RooNLLVar*>::iterator it = nllComponents.begin(); nllComponents.end() != it; ++it) {
1565  (*it)->applyWeightSquared(kFALSE);
1566  }
1567 
1568  // Apply correction matrix
1569  const TMatrixDSym& matV = rw->covarianceMatrix();
1570  TMatrixDSym matC = rw2->covarianceMatrix();
1572  CholeskyDecompGenDim<Double_t> decomp(matC.GetNrows(), matC);
1573  if (!decomp) {
1574  coutE(Fitting) << "RooAbsPdf::fitTo(" << GetName()
1575  << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction matrix calculated with weight-squared is singular" <<endl ;
1576  } else {
1577  // replace C by its inverse
1578  decomp.Invert(matC);
1579  // the class lies about the matrix being symmetric, so fill in the
1580  // part above the diagonal
1581  for (int i = 0; i < matC.GetNrows(); ++i)
1582  for (int j = 0; j < i; ++j) matC(j, i) = matC(i, j);
1583  matC.Similarity(matV);
1584  // C now contiains V C^-1 V
1585  // Propagate corrected errors to parameters objects
1586  m.applyCovarianceMatrix(matC);
1587  }
1588 
1589  delete rw;
1590  delete rw2;
1591  }
1592 
1593  if (minos) {
1594  // Evaluate errs with Minos
1595  if (minosSet) {
1596  m.minos(*minosSet) ;
1597  } else {
1598  m.minos() ;
1599  }
1600  }
1601 
1602  // Optionally return fit result
1603  if (doSave) {
1604  string name = Form("fitresult_%s_%s",GetName(),data.GetName()) ;
1605  string title = Form("Result of fit of p.d.f. %s to dataset %s",GetName(),data.GetName()) ;
1606  ret = m.save(name.c_str(),title.c_str()) ;
1607  }
1608 
1609  }
1610  if (optConst) {
1611  m.optimizeConst(0) ;
1612  }
1613 
1614 #endif
1615 
1616  } else {
1617 
1618  RooMinuit m(*nll) ;
1619 
1620  m.setEvalErrorWall(doEEWall) ;
1621  if (doWarn==0) {
1622  m.setNoWarn() ;
1623  }
1624 
1625  m.setPrintEvalErrors(numee) ;
1626  if (plevel!=1) {
1627  m.setPrintLevel(plevel) ;
1628  }
1629 
1630  if (optConst) {
1631  // Activate constant term optimization
1632  m.optimizeConst(optConst) ;
1633  }
1634 
1635  if (fitOpt) {
1636 
1637  // Play fit options as historically defined
1638  ret = m.fit(fitOpt) ;
1639 
1640  } else {
1641 
1642  if (verbose) {
1643  // Activate verbose options
1644  m.setVerbose(1) ;
1645  }
1646  if (doTimer) {
1647  // Activate timer options
1648  m.setProfile(1) ;
1649  }
1650 
1651  if (strat!=1) {
1652  // Modify fit strategy
1653  m.setStrategy(strat) ;
1654  }
1655 
1656  if (initHesse) {
1657  // Initialize errors with hesse
1658  m.hesse() ;
1659  }
1660 
1661  // Minimize using migrad
1662  m.migrad() ;
1663 
1664  if (hesse) {
1665  // Evaluate errors with Hesse
1666  m.hesse() ;
1667  }
1668 
1669  //asymptotically correct approach
1670  if (doAsymptotic==1 && m.getNPar()>0) {
1671  //Calculated corrected errors for weighted likelihood fits
1672  std::unique_ptr<RooFitResult> rw(m.save());
1673  //Weighted inverse Hessian matrix
1674  const TMatrixDSym& matV = rw->covarianceMatrix();
1675  coutI(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") Calculating covariance matrix according to the asymptotically correct approach. If you find this method useful please consider citing https://arxiv.org/abs/1911.01303." << endl;
1676 
1677  //Initialise matrix containing first derivatives
1678  TMatrixDSym num(rw->floatParsFinal().getSize());
1679  for (int k=0; k<rw->floatParsFinal().getSize(); k++)
1680  for (int l=0; l<rw->floatParsFinal().getSize(); l++)
1681  num(k,l) = 0.0;
1682  RooArgSet* obs = getObservables(data);
1683  //Create derivative objects
1684  std::vector<std::unique_ptr<RooDerivative> > derivatives;
1685  const RooArgList& floated = rw->floatParsFinal();
1686  std::unique_ptr<RooArgSet> floatingparams( (RooArgSet*)getParameters(data)->selectByAttrib("Constant", false) );
1687  for (int k=0; k<floated.getSize(); k++) {
1688  RooRealVar* paramresult = (RooRealVar*)floated.at(k);
1689  RooRealVar* paraminternal = (RooRealVar*)floatingparams->find(paramresult->getTitle());
1690  std::unique_ptr<RooDerivative> deriv( derivative(*paraminternal, *obs, 1) );
1691  derivatives.push_back(std::move(deriv));
1692  }
1693 
1694  //Loop over data
1695  for (int j=0; j<data.numEntries(); j++) {
1696  //Sets obs to current data point, this is where the pdf will be evaluated
1697  *obs = *data.get(j);
1698  //Determine first derivatives
1699  std::vector<Double_t> diffs(floated.getSize(), 0.0);
1700  for (int k=0; k<floated.getSize(); k++) {
1701  RooRealVar* paramresult = (RooRealVar*)floated.at(k);
1702  RooRealVar* paraminternal = (RooRealVar*)floatingparams->find(paramresult->getTitle());
1703  //First derivative to parameter k at best estimate point for this measurement
1704  Double_t diff = derivatives.at(k)->getVal();
1705  //Need to reset to best fit point after differentiation
1706  *paraminternal = paramresult->getVal();
1707  diffs.at(k) = diff;
1708  }
1709  //Fill numerator matrix
1710  Double_t prob = getVal(obs);
1711  for (int k=0; k<floated.getSize(); k++) {
1712  for (int l=0; l<floated.getSize(); l++) {
1713  num(k,l) += data.weight()*data.weight()*diffs.at(k)*diffs.at(l)/(prob*prob);
1714  }
1715  }
1716  }
1717  num.Similarity(matV);
1718 
1719  //Propagate corrected errors to parameters objects
1720  m.applyCovarianceMatrix(num);
1721  }
1722 
1723  if (doSumW2==1 && m.getNPar()>0) {
1724 
1725  // Make list of RooNLLVar components of FCN
1726  list<RooNLLVar*> nllComponents ;
1727  RooArgSet* comps = nll->getComponents() ;
1728  RooAbsArg* arg ;
1729  TIterator* citer = comps->createIterator() ;
1730  while((arg=(RooAbsArg*)citer->Next())) {
1731  RooNLLVar* nllComp = dynamic_cast<RooNLLVar*>(arg) ;
1732  if (nllComp) {
1733  nllComponents.push_back(nllComp) ;
1734  }
1735  }
1736  delete citer ;
1737  delete comps ;
1738 
1739  // Calculated corrected errors for weighted likelihood fits
1740  RooFitResult* rw = m.save() ;
1741  for (list<RooNLLVar*>::iterator iter1=nllComponents.begin() ; iter1!=nllComponents.end() ; ++iter1) {
1742  (*iter1)->applyWeightSquared(kTRUE) ;
1743  }
1744  coutI(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") Calculating sum-of-weights-squared correction matrix for covariance matrix" << endl ;
1745  m.hesse() ;
1746  RooFitResult* rw2 = m.save() ;
1747  for (list<RooNLLVar*>::iterator iter2=nllComponents.begin() ; iter2!=nllComponents.end() ; ++iter2) {
1748  (*iter2)->applyWeightSquared(kFALSE) ;
1749  }
1750 
1751  // Apply correction matrix
1752  const TMatrixDSym& matV = rw->covarianceMatrix();
1753  TMatrixDSym matC = rw2->covarianceMatrix();
1755  CholeskyDecompGenDim<Double_t> decomp(matC.GetNrows(), matC);
1756  if (!decomp) {
1757  coutE(Fitting) << "RooAbsPdf::fitTo(" << GetName()
1758  << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction matrix calculated with weight-squared is singular" <<endl ;
1759  } else {
1760  // replace C by its inverse
1761  decomp.Invert(matC);
1762  // the class lies about the matrix being symmetric, so fill in the
1763  // part above the diagonal
1764  for (int i = 0; i < matC.GetNrows(); ++i)
1765  for (int j = 0; j < i; ++j) matC(j, i) = matC(i, j);
1766  matC.Similarity(matV);
1767  // C now contiains V C^-1 V
1768  // Propagate corrected errors to parameters objects
1769  m.applyCovarianceMatrix(matC);
1770  }
1771 
1772  delete rw ;
1773  delete rw2 ;
1774  }
1775 
1776  if (minos) {
1777  // Evaluate errs with Minos
1778  if (minosSet) {
1779  m.minos(*minosSet) ;
1780  } else {
1781  m.minos() ;
1782  }
1783  }
1784 
1785  // Optionally return fit result
1786  if (doSave) {
1787  string name = Form("fitresult_%s_%s",GetName(),data.GetName()) ;
1788  string title = Form("Result of fit of p.d.f. %s to dataset %s",GetName(),data.GetName()) ;
1789  ret = m.save(name.c_str(),title.c_str()) ;
1790  }
1791 
1792  }
1793 
1794  if (optConst) {
1795  m.optimizeConst(0) ;
1796  }
1797 
1798  }
1799 
1800 
1801 
1802  // Cleanup
1803  delete nll ;
1804  return ret ;
1805 }
1806 
1807 
1808 
1809 ////////////////////////////////////////////////////////////////////////////////
1810 /// Calls RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
1811 
1813 {
1814  // Select the pdf-specific commands
1815  RooCmdConfig pc(Form("RooAbsPdf::chi2FitTo(%s)",GetName())) ;
1816 
1817  // Pull arguments to be passed to chi2 construction from list
1818  RooLinkedList fitCmdList(cmdList) ;
1819  RooLinkedList chi2CmdList = pc.filterCmdList(fitCmdList,"Range,RangeWithName,NumCPU,Optimize,ProjectedObservables,AddCoefRange,SplitRange,DataError,Extended") ;
1820 
1821  RooAbsReal* chi2 = createChi2(data,chi2CmdList) ;
1822  RooFitResult* ret = chi2FitDriver(*chi2,fitCmdList) ;
1823 
1824  // Cleanup
1825  delete chi2 ;
1826  return ret ;
1827 }
1828 
1829 
1830 
1831 
1832 ////////////////////////////////////////////////////////////////////////////////
1833 /// Create a \f$ \chi^2 \f$ from a histogram and this function.
1834 ///
1835 /// Options to control construction of the \f$ \chi^2 \f$
1836 /// ------------------------------------------
1837 /// <table>
1838 /// <tr><th> Type of CmdArg <th> Effect on \f$ \chi^2 \f$
1839 /// <tr><td> `Extended()` <td> Use expected number of events of an extended p.d.f as normalization
1840 /// <tr><td> `DataError()` <td> Choose between:
1841 /// - Expected error [RooAbsData::Expected]
1842 /// - Observed error (e.g. Sum-of-weights) [RooAbsData::SumW2]
1843 /// - Poisson interval [RooAbsData::Poisson]
1844 /// - Default: Expected error for unweighted data, Sum-of-weights for weighted data [RooAbsData::Auto]
1845 /// <tr><td> `NumCPU()` <td> Activate parallel processing feature
1846 /// <tr><td> `Range()` <td> Fit only selected region
1847 /// <tr><td> `SumCoefRange()` <td> Set the range in which to interpret the coefficients of RooAddPdf components
1848 /// <tr><td> `SplitRange()` <td> Fit ranges used in different categories get named after the category.
1849 /// Using `Range("range"), SplitRange()` as switches, different ranges could be set like this:
1850 /// ```
1851 /// myVariable.setRange("range_pi0", 135, 210);
1852 /// myVariable.setRange("range_gamma", 50, 210);
1853 /// ```
1854 /// <tr><td> `ConditionalObservables()` <td> Define projected observables
1855 /// </table>
1856 
1858  const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
1859  const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1860 {
1861  RooLinkedList cmdList ;
1862  cmdList.Add((TObject*)&arg1) ; cmdList.Add((TObject*)&arg2) ;
1863  cmdList.Add((TObject*)&arg3) ; cmdList.Add((TObject*)&arg4) ;
1864  cmdList.Add((TObject*)&arg5) ; cmdList.Add((TObject*)&arg6) ;
1865  cmdList.Add((TObject*)&arg7) ; cmdList.Add((TObject*)&arg8) ;
1866 
1867  RooCmdConfig pc(Form("RooAbsPdf::createChi2(%s)",GetName())) ;
1868  pc.defineString("rangeName","RangeWithName",0,"",kTRUE) ;
1869  pc.allowUndefined(kTRUE) ;
1870  pc.process(cmdList) ;
1871  if (!pc.ok(kTRUE)) {
1872  return 0 ;
1873  }
1874  const char* rangeName = pc.getString("rangeName",0,kTRUE) ;
1875 
1876  // Construct Chi2
1878  RooAbsReal* chi2 ;
1879  string baseName = Form("chi2_%s_%s",GetName(),data.GetName()) ;
1880 
1881  // Clear possible range attributes from previous fits.
1882  setStringAttribute("fitrange", nullptr);
1883 
1884  if (!rangeName || strchr(rangeName,',')==0) {
1885  // Simple case: default range, or single restricted range
1886 
1887  chi2 = new RooChi2Var(baseName.c_str(),baseName.c_str(),*this,data,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1888 
1889  } else {
1890 
1891  // Find which argument is RangeWithName
1892  const RooCmdArg* rarg(0) ;
1893  string rcmd = "RangeWithName" ;
1894  if (arg1.GetName()==rcmd) rarg = &arg1 ;
1895  if (arg2.GetName()==rcmd) rarg = &arg2 ;
1896  if (arg3.GetName()==rcmd) rarg = &arg3 ;
1897  if (arg4.GetName()==rcmd) rarg = &arg4 ;
1898  if (arg5.GetName()==rcmd) rarg = &arg5 ;
1899  if (arg6.GetName()==rcmd) rarg = &arg6 ;
1900  if (arg7.GetName()==rcmd) rarg = &arg7 ;
1901  if (arg8.GetName()==rcmd) rarg = &arg8 ;
1902 
1903  // Composite case: multiple ranges
1904  RooArgList chi2List ;
1905  for (std::string& token : RooHelpers::tokenise(rangeName, ",")) {
1906  RooCmdArg subRangeCmd = RooFit::Range(token.c_str()) ;
1907  // Construct chi2 while substituting original RangeWithName argument with subrange argument created above
1908  RooAbsReal* chi2Comp = new RooChi2Var(Form("%s_%s", baseName.c_str(), token.c_str()), "chi^2", *this, data,
1909  &arg1==rarg?subRangeCmd:arg1,&arg2==rarg?subRangeCmd:arg2,
1910  &arg3==rarg?subRangeCmd:arg3,&arg4==rarg?subRangeCmd:arg4,
1911  &arg5==rarg?subRangeCmd:arg5,&arg6==rarg?subRangeCmd:arg6,
1912  &arg7==rarg?subRangeCmd:arg7,&arg8==rarg?subRangeCmd:arg8) ;
1913  chi2List.add(*chi2Comp) ;
1914  }
1915  chi2 = new RooAddition(baseName.c_str(),"chi^2",chi2List,kTRUE) ;
1916  }
1918 
1919 
1920  return chi2 ;
1921 }
1922 
1923 
1924 
1925 
1926 ////////////////////////////////////////////////////////////////////////////////
1927 /// Argument-list version of RooAbsPdf::createChi2()
1928 
1930 {
1931  // Select the pdf-specific commands
1932  RooCmdConfig pc(Form("RooAbsPdf::createChi2(%s)",GetName())) ;
1933 
1934  pc.defineInt("integrate","Integrate",0,0) ;
1935  pc.defineObject("yvar","YVar",0,0) ;
1936 
1937  // Process and check varargs
1938  pc.process(cmdList) ;
1939  if (!pc.ok(kTRUE)) {
1940  return 0 ;
1941  }
1942 
1943  // Decode command line arguments
1944  Bool_t integrate = pc.getInt("integrate") ;
1945  RooRealVar* yvar = (RooRealVar*) pc.getObject("yvar") ;
1946 
1947  string name = Form("chi2_%s_%s",GetName(),data.GetName()) ;
1948 
1949  if (yvar) {
1950  return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,*yvar,integrate) ;
1951  } else {
1952  return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,integrate) ;
1953  }
1954 }
1955 
1956 
1957 
1958 
1959 ////////////////////////////////////////////////////////////////////////////////
1960 /// Print value of p.d.f, also print normalization integral that was last used, if any
1961 
1962 void RooAbsPdf::printValue(ostream& os) const
1963 {
1964  getVal() ;
1965 
1966  if (_norm) {
1967  os << evaluate() << "/" << _norm->getVal() ;
1968  } else {
1969  os << evaluate() ;
1970  }
1971 }
1972 
1973 
1974 
1975 ////////////////////////////////////////////////////////////////////////////////
1976 /// Print multi line detailed information of this RooAbsPdf
1977 
1978 void RooAbsPdf::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
1979 {
1981  os << indent << "--- RooAbsPdf ---" << endl;
1982  os << indent << "Cached value = " << _value << endl ;
1983  if (_norm) {
1984  os << indent << " Normalization integral: " << endl ;
1985  TString moreIndent(indent) ; moreIndent.Append(" ") ;
1987  }
1988 }
1989 
1990 
1991 
1992 ////////////////////////////////////////////////////////////////////////////////
1993 /// Return a binned generator context
1994 
1996 {
1997  return new RooBinnedGenContext(*this,vars,0,0,verbose) ;
1998 }
1999 
2000 
2001 ////////////////////////////////////////////////////////////////////////////////
2002 /// Interface function to create a generator context from a p.d.f. This default
2003 /// implementation returns a 'standard' context that works for any p.d.f
2004 
2006  const RooArgSet* auxProto, Bool_t verbose) const
2007 {
2008  return new RooGenContext(*this,vars,prototype,auxProto,verbose) ;
2009 }
2010 
2011 
2012 ////////////////////////////////////////////////////////////////////////////////
2013 
2014 RooAbsGenContext* RooAbsPdf::autoGenContext(const RooArgSet &vars, const RooDataSet* prototype, const RooArgSet* auxProto,
2015  Bool_t verbose, Bool_t autoBinned, const char* binnedTag) const
2016 {
2017  if (prototype || (auxProto && auxProto->getSize()>0)) {
2018  return genContext(vars,prototype,auxProto,verbose);
2019  }
2020 
2021  RooAbsGenContext *context(0) ;
2022  if ( (autoBinned && isBinnedDistribution(vars)) || ( binnedTag && strlen(binnedTag) && (getAttribute(binnedTag)||string(binnedTag)=="*"))) {
2023  context = binnedGenContext(vars,verbose) ;
2024  } else {
2025  context= genContext(vars,0,0,verbose);
2026  }
2027  return context ;
2028 }
2029 
2030 
2031 
2032 ////////////////////////////////////////////////////////////////////////////////
2033 /// Generate a new dataset containing the specified variables with events sampled from our distribution.
2034 /// Generate the specified number of events or expectedEvents() if not specified.
2035 /// \param[in] whatVars Choose variables in which to generate events. Variables not listed here will remain
2036 /// constant and not be used for event generation.
2037 /// \param[in] argxx Optional RooCmdArg() to change behaviour of generate().
2038 /// \return RooDataSet *, owned by caller.
2039 ///
2040 /// Any variables of this PDF that are not in whatVars will use their
2041 /// current values and be treated as fixed parameters. Returns zero
2042 /// in case of an error.
2043 ///
2044 /// <table>
2045 /// <tr><th> Type of CmdArg <th> Effect on generate
2046 /// <tr><td> `Name(const char* name)` <td> Name of the output dataset
2047 /// <tr><td> `Verbose(Bool_t flag)` <td> Print informational messages during event generation
2048 /// <tr><td> `NumEvent(int nevt)` <td> Generate specified number of events
2049 /// <tr><td> `Extended()` <td> If no number of events to be generated is given,
2050 /// use expected number of events from extended likelihood term.
2051 /// This evidently only works for extended PDFs.
2052 /// <tr><td> `GenBinned(const char* tag)` <td> Use binned generation for all component pdfs that have 'setAttribute(tag)' set
2053 /// <tr><td> `AutoBinned(Bool_t flag)` <td> Automatically deploy binned generation for binned distributions (e.g. RooHistPdf, sums and products of
2054 /// RooHistPdfs etc)
2055 /// \note Datasets that are generated in binned mode are returned as weighted unbinned datasets. This means that
2056 /// for each bin, there will be one event in the dataset with a weight corresponding to the (possibly randomised) bin content.
2057 ///
2058 ///
2059 /// <tr><td> `AllBinned()` <td> As above, but for all components.
2060 /// \note The notion of components is only meaningful for simultaneous PDFs
2061 /// as binned generation is always executed at the top-level node for a regular
2062 /// PDF, so for those it only mattes that the top-level node is tagged.
2063 ///
2064 /// <tr><td> ProtoData(const RooDataSet& data, Bool_t randOrder)
2065 /// <td> Use specified dataset as prototype dataset. If randOrder in ProtoData() is set to true,
2066 /// the order of the events in the dataset will be read in a random order if the requested
2067 /// number of events to be generated does not match the number of events in the prototype dataset.
2068 /// \note If ProtoData() is used, the specified existing dataset as a prototype: the new dataset will contain
2069 /// the same number of events as the prototype (unless otherwise specified), and any prototype variables not in
2070 /// whatVars will be copied into the new dataset for each generated event and also used to set our PDF parameters.
2071 /// The user can specify a number of events to generate that will override the default. The result is a
2072 /// copy of the prototype dataset with only variables in whatVars randomized. Variables in whatVars that
2073 /// are not in the prototype will be added as new columns to the generated dataset.
2074 ///
2075 /// </table>
2076 ///
2077 /// #### Accessing the underlying event generator
2078 /// Depending on the fit model (if it is difficult to sample), it may be necessary to change generator settings.
2079 /// For the default generator (RooFoamGenerator), the number of samples or cells could be increased by e.g. using
2080 /// myPdf->specialGeneratorConfig()->getConfigSection("RooFoamGenerator").setRealValue("nSample",1e4);
2081 ///
2082 /// The foam generator e.g. has the following config options:
2083 /// - nCell[123N]D
2084 /// - nSample
2085 /// - chatLevel
2086 /// \see rf902_numgenconfig.C
2087 
2088 RooDataSet *RooAbsPdf::generate(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
2089  const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
2090 {
2091  // Select the pdf-specific commands
2092  RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
2093  pc.defineObject("proto","PrototypeData",0,0) ;
2094  pc.defineString("dsetName","Name",0,"") ;
2095  pc.defineInt("randProto","PrototypeData",0,0) ;
2096  pc.defineInt("resampleProto","PrototypeData",1,0) ;
2097  pc.defineInt("verbose","Verbose",0,0) ;
2098  pc.defineInt("extended","Extended",0,0) ;
2099  pc.defineInt("nEvents","NumEvents",0,0) ;
2100  pc.defineInt("autoBinned","AutoBinned",0,1) ;
2101  pc.defineInt("expectedData","ExpectedData",0,0) ;
2102  pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
2103  pc.defineString("binnedTag","GenBinned",0,"") ;
2104  pc.defineMutex("GenBinned","ProtoData") ;
2105  pc.defineMutex("Extended", "NumEvents");
2106 
2107  // Process and check varargs
2108  pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
2109  if (!pc.ok(kTRUE)) {
2110  return 0 ;
2111  }
2112 
2113  // Decode command line arguments
2114  RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
2115  const char* dsetName = pc.getString("dsetName") ;
2116  Bool_t verbose = pc.getInt("verbose") ;
2117  Bool_t randProto = pc.getInt("randProto") ;
2118  Bool_t resampleProto = pc.getInt("resampleProto") ;
2119  Bool_t extended = pc.getInt("extended") ;
2120  Bool_t autoBinned = pc.getInt("autoBinned") ;
2121  const char* binnedTag = pc.getString("binnedTag") ;
2122  Int_t nEventsI = pc.getInt("nEvents") ;
2123  Double_t nEventsD = pc.getInt("nEventsD") ;
2124  //Bool_t verbose = pc.getInt("verbose") ;
2125  Bool_t expectedData = pc.getInt("expectedData") ;
2126 
2127  Double_t nEvents = (nEventsD>0) ? nEventsD : Double_t(nEventsI);
2128 
2129  // Force binned mode for expected data mode
2130  if (expectedData) {
2131  binnedTag="*" ;
2132  }
2133 
2134  if (extended) {
2135  if (nEvents == 0) nEvents = expectedEvents(&whatVars);
2136  } else if (nEvents==0) {
2137  cxcoutI(Generation) << "No number of events specified , number of events generated is "
2138  << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
2139  }
2140 
2141  if (extended && protoData && !randProto) {
2142  cxcoutI(Generation) << "WARNING Using generator option Extended() (Poisson distribution of #events) together "
2143  << "with a prototype dataset implies incomplete sampling or oversampling of proto data. "
2144  << "Set randomize flag in ProtoData() option to randomize prototype dataset order and thus "
2145  << "to randomize the set of over/undersampled prototype events for each generation cycle." << endl ;
2146  }
2147 
2148 
2149  // Forward to appropriate implementation
2150  RooDataSet* data ;
2151  if (protoData) {
2152  data = generate(whatVars,*protoData,Int_t(nEvents),verbose,randProto,resampleProto) ;
2153  } else {
2154  data = generate(whatVars,nEvents,verbose,autoBinned,binnedTag,expectedData, extended) ;
2155  }
2156 
2157  // Rename dataset to given name if supplied
2158  if (dsetName && strlen(dsetName)>0) {
2159  data->SetName(dsetName) ;
2160  }
2161 
2162  return data ;
2163 }
2164 
2165 
2166 
2167 
2168 
2169 
2170 ////////////////////////////////////////////////////////////////////////////////
2171 /// \note This method does not perform any generation. To generate according to generations specification call RooAbsPdf::generate(RooAbsPdf::GenSpec&) const
2172 ///
2173 /// Details copied from RooAbsPdf::generate():
2174 /// --------------------------------------------
2175 /// \copydetails RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
2176 
2178  const RooCmdArg& arg1,const RooCmdArg& arg2,
2179  const RooCmdArg& arg3,const RooCmdArg& arg4,
2180  const RooCmdArg& arg5,const RooCmdArg& arg6)
2181 {
2182 
2183  // Select the pdf-specific commands
2184  RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
2185  pc.defineObject("proto","PrototypeData",0,0) ;
2186  pc.defineString("dsetName","Name",0,"") ;
2187  pc.defineInt("randProto","PrototypeData",0,0) ;
2188  pc.defineInt("resampleProto","PrototypeData",1,0) ;
2189  pc.defineInt("verbose","Verbose",0,0) ;
2190  pc.defineInt("extended","Extended",0,0) ;
2191  pc.defineInt("nEvents","NumEvents",0,0) ;
2192  pc.defineInt("autoBinned","AutoBinned",0,1) ;
2193  pc.defineString("binnedTag","GenBinned",0,"") ;
2194  pc.defineMutex("GenBinned","ProtoData") ;
2195 
2196 
2197  // Process and check varargs
2198  pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
2199  if (!pc.ok(kTRUE)) {
2200  return 0 ;
2201  }
2202 
2203  // Decode command line arguments
2204  RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
2205  const char* dsetName = pc.getString("dsetName") ;
2206  Int_t nEvents = pc.getInt("nEvents") ;
2207  Bool_t verbose = pc.getInt("verbose") ;
2208  Bool_t randProto = pc.getInt("randProto") ;
2209  Bool_t resampleProto = pc.getInt("resampleProto") ;
2210  Bool_t extended = pc.getInt("extended") ;
2211  Bool_t autoBinned = pc.getInt("autoBinned") ;
2212  const char* binnedTag = pc.getString("binnedTag") ;
2213 
2214  RooAbsGenContext* cx = autoGenContext(whatVars,protoData,0,verbose,autoBinned,binnedTag) ;
2215 
2216  return new GenSpec(cx,whatVars,protoData,nEvents,extended,randProto,resampleProto,dsetName) ;
2217 }
2218 
2219 
2220 ////////////////////////////////////////////////////////////////////////////////
2221 /// If many identical generation requests
2222 /// are needed, e.g. in toy MC studies, it is more efficient to use the prepareMultiGen()/generate()
2223 /// combination than calling the standard generate() multiple times as
2224 /// initialization overhead is only incurred once.
2225 
2227 {
2228  //Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen) : spec._nGen ;
2229  //Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen==0?expectedEvents(spec._whatVars):spec._nGen) : spec._nGen ;
2230  //Int_t nEvt = spec._nGen == 0 ? RooRandom::randomGenerator()->Poisson(expectedEvents(spec._whatVars)) : spec._nGen;
2231 
2232  Double_t nEvt = spec._nGen == 0 ? expectedEvents(spec._whatVars) : spec._nGen;
2233 
2234  RooDataSet* ret = generate(*spec._genContext,spec._whatVars,spec._protoData, nEvt,kFALSE,spec._randProto,spec._resampleProto,
2235  spec._init,spec._extended) ;
2236  spec._init = kTRUE ;
2237  return ret ;
2238 }
2239 
2240 
2241 
2242 
2243 
2244 ////////////////////////////////////////////////////////////////////////////////
2245 /// Generate a new dataset containing the specified variables with
2246 /// events sampled from our distribution.
2247 ///
2248 /// \param[in] whatVars Generate a dataset with the variables (and categories) in this set.
2249 /// Any variables of this PDF that are not in `whatVars` will use their
2250 /// current values and be treated as fixed parameters.
2251 /// \param[in] nEvents Generate the specified number of events or else try to use
2252 /// expectedEvents() if nEvents <= 0 (default).
2253 /// \param[in] verbose Show which generator strategies are being used.
2254 /// \param[in] autoBinned If original distribution is binned, return bin centers and randomise weights
2255 /// instead of generating single events.
2256 /// \param[in] binnedTag
2257 /// \param[in] expectedData Call setExpectedData on the genContext.
2258 /// \param[in] extended Randomise number of events generated according to Poisson(nEvents). Only useful
2259 /// if PDF is extended.
2260 /// \return New dataset. Returns zero in case of an error. The caller takes ownership of the returned
2261 /// dataset.
2262 
2263 RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, Double_t nEvents, Bool_t verbose, Bool_t autoBinned, const char* binnedTag, Bool_t expectedData, Bool_t extended) const
2264 {
2265  if (nEvents==0 && extendMode()==CanNotBeExtended) {
2266  return new RooDataSet("emptyData","emptyData",whatVars) ;
2267  }
2268 
2269  // Request for binned generation
2270  RooAbsGenContext *context = autoGenContext(whatVars,0,0,verbose,autoBinned,binnedTag) ;
2271  if (expectedData) {
2272  context->setExpectedData(kTRUE) ;
2273  }
2274 
2275  RooDataSet *generated = 0;
2276  if(0 != context && context->isValid()) {
2277  generated= context->generate(nEvents, kFALSE, extended);
2278  }
2279  else {
2280  coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") cannot create a valid context" << endl;
2281  }
2282  if(0 != context) delete context;
2283  return generated;
2284 }
2285 
2286 
2287 
2288 
2289 ////////////////////////////////////////////////////////////////////////////////
2290 /// Internal method
2291 
2292 RooDataSet *RooAbsPdf::generate(RooAbsGenContext& context, const RooArgSet &whatVars, const RooDataSet *prototype,
2293  Double_t nEvents, Bool_t /*verbose*/, Bool_t randProtoOrder, Bool_t resampleProto,
2294  Bool_t skipInit, Bool_t extended) const
2295 {
2296  if (nEvents==0 && (prototype==0 || prototype->numEntries()==0)) {
2297  return new RooDataSet("emptyData","emptyData",whatVars) ;
2298  }
2299 
2300  RooDataSet *generated = 0;
2301 
2302  // Resampling implies reshuffling in the implementation
2303  if (resampleProto) {
2304  randProtoOrder=kTRUE ;
2305  }
2306 
2307  if (randProtoOrder && prototype && prototype->numEntries()!=nEvents) {
2308  coutI(Generation) << "RooAbsPdf::generate (Re)randomizing event order in prototype dataset (Nevt=" << nEvents << ")" << endl ;
2309  Int_t* newOrder = randomizeProtoOrder(prototype->numEntries(),Int_t(nEvents),resampleProto) ;
2310  context.setProtoDataOrder(newOrder) ;
2311  delete[] newOrder ;
2312  }
2313 
2314  if(context.isValid()) {
2315  generated= context.generate(nEvents,skipInit,extended);
2316  }
2317  else {
2318  coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") do not have a valid generator context" << endl;
2319  }
2320  return generated;
2321 }
2322 
2323 
2324 
2325 
2326 ////////////////////////////////////////////////////////////////////////////////
2327 /// Generate a new dataset using a prototype dataset as a model,
2328 /// with values of the variables in `whatVars` sampled from our distribution.
2329 ///
2330 /// \param[in] whatVars Generate for these variables.
2331 /// \param[in] prototype Use this dataset
2332 /// as a prototype: the new dataset will contain the same number of
2333 /// events as the prototype (by default), and any prototype variables not in
2334 /// whatVars will be copied into the new dataset for each generated
2335 /// event and also used to set our PDF parameters. The user can specify a
2336 /// number of events to generate that will override the default. The result is a
2337 /// copy of the prototype dataset with only variables in whatVars
2338 /// randomized. Variables in whatVars that are not in the prototype
2339 /// will be added as new columns to the generated dataset.
2340 /// \param[in] nEvents Number of events to generate. Defaults to 0, which means number
2341 /// of event in prototype dataset.
2342 /// \param[in] verbose Show which generator strategies are being used.
2343 /// \param[in] randProtoOrder Randomise order of retrieval of events from proto dataset.
2344 /// \param[in] resampleProto Resample from the proto dataset.
2345 /// \return The new dataset. Returns zero in case of an error. The caller takes ownership of the
2346 /// returned dataset.
2347 
2348 RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, const RooDataSet& prototype,
2349  Int_t nEvents, Bool_t verbose, Bool_t randProtoOrder, Bool_t resampleProto) const
2350 {
2351  RooAbsGenContext *context= genContext(whatVars,&prototype,0,verbose);
2352  if (context) {
2353  RooDataSet* data = generate(*context,whatVars,&prototype,nEvents,verbose,randProtoOrder,resampleProto) ;
2354  delete context ;
2355  return data ;
2356  } else {
2357  coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") ERROR creating generator context" << endl ;
2358  return 0 ;
2359  }
2360 }
2361 
2362 
2363 
2364 ////////////////////////////////////////////////////////////////////////////////
2365 /// Return lookup table with randomized access order for prototype events,
2366 /// given nProto prototype data events and nGen events that will actually
2367 /// be accessed
2368 
2370 {
2371  // Make unsorted linked list of indeces
2372  RooLinkedList l ;
2373  Int_t i ;
2374  for (i=0 ; i<nProto ; i++) {
2375  l.Add(new RooInt(i)) ;
2376  }
2377 
2378  // Make output list
2379  Int_t* lut = new Int_t[nProto] ;
2380 
2381  // Randomly samply input list into output list
2382  if (!resampleProto) {
2383  // In this mode, randomization is a strict reshuffle of the order
2384  for (i=0 ; i<nProto ; i++) {
2385  Int_t iran = RooRandom::integer(nProto-i) ;
2386  RooInt* sample = (RooInt*) l.At(iran) ;
2387  lut[i] = *sample ;
2388  l.Remove(sample) ;
2389  delete sample ;
2390  }
2391  } else {
2392  // In this mode, we resample, i.e. events can be used more than once
2393  for (i=0 ; i<nProto ; i++) {
2394  lut[i] = RooRandom::integer(nProto);
2395  }
2396  }
2397 
2398 
2399  return lut ;
2400 }
2401 
2402 
2403 
2404 ////////////////////////////////////////////////////////////////////////////////
2405 /// Load generatedVars with the subset of directVars that we can generate events for,
2406 /// and return a code that specifies the generator algorithm we will use. A code of
2407 /// zero indicates that we cannot generate any of the directVars (in this case, nothing
2408 /// should be added to generatedVars). Any non-zero codes will be passed to our generateEvent()
2409 /// implementation, but otherwise its value is arbitrary. The default implemetation of
2410 /// this method returns zero. Subclasses will usually implement this method using the
2411 /// matchArgs() methods to advertise the algorithms they provide.
2412 
2413 Int_t RooAbsPdf::getGenerator(const RooArgSet &/*directVars*/, RooArgSet &/*generatedVars*/, Bool_t /*staticInitOK*/) const
2414 {
2415  return 0 ;
2416 }
2417 
2418 
2419 
2420 ////////////////////////////////////////////////////////////////////////////////
2421 /// Interface for one-time initialization to setup the generator for the specified code.
2422 
2424 {
2425 }
2426 
2427 
2428 
2429 ////////////////////////////////////////////////////////////////////////////////
2430 /// Interface for generation of an event using the algorithm
2431 /// corresponding to the specified code. The meaning of each code is
2432 /// defined by the getGenerator() implementation. The default
2433 /// implementation does nothing.
2434 
2436 {
2437 }
2438 
2439 
2440 
2441 ////////////////////////////////////////////////////////////////////////////////
2442 /// Check if given observable can be safely generated using the
2443 /// pdfs internal generator mechanism (if that existsP). Observables
2444 /// on which a PDF depends via more than route are not safe
2445 /// for use with internal generators because they introduce
2446 /// correlations not known to the internal generator
2447 
2449 {
2450  // Arg must be direct server of self
2451  if (!findServer(arg.GetName())) return kFALSE ;
2452 
2453  // There must be no other dependency routes
2454  for (const auto server : _serverList) {
2455  if(server == &arg) continue;
2456  if(server->dependsOn(arg)) {
2457  return kFALSE ;
2458  }
2459  }
2460 
2461  return kTRUE ;
2462 }
2463 
2464 
2465 ////////////////////////////////////////////////////////////////////////////////
2466 /// Generate a new dataset containing the specified variables with events sampled from our distribution.
2467 /// \param[in] whatVars Choose variables in which to generate events. Variables not listed here will remain
2468 /// constant and not be used for event generation
2469 /// \param[in] arg1 Optional RooCmdArg to change behaviour of generateBinned()
2470 /// \return RooDataHist *, to be managed by caller.
2471 ///
2472 /// Generate the specified number of events or expectedEvents() if not specified.
2473 ///
2474 /// Any variables of this PDF that are not in whatVars will use their
2475 /// current values and be treated as fixed parameters. Returns zero
2476 /// in case of an error. The caller takes ownership of the returned
2477 /// dataset.
2478 ///
2479 /// The following named arguments are supported
2480 /// | Type of CmdArg | Effect on generation
2481 /// |-------------------------|-----------------------
2482 /// | `Name(const char* name)` | Name of the output dataset
2483 /// | `Verbose(Bool_t flag)` | Print informational messages during event generation
2484 /// | `NumEvent(int nevt)` | Generate specified number of events
2485 /// | `Extended()` | The actual number of events generated will be sampled from a Poisson distribution with mu=nevt. For use with extended maximum likelihood fits
2486 /// | `ExpectedData()` | Return a binned dataset _without_ statistical fluctuations (also aliased as Asimov())
2487 ///
2488 
2489 RooDataHist *RooAbsPdf::generateBinned(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
2490  const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6) const
2491 {
2492 
2493  // Select the pdf-specific commands
2494  RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
2495  pc.defineString("dsetName","Name",0,"") ;
2496  pc.defineInt("verbose","Verbose",0,0) ;
2497  pc.defineInt("extended","Extended",0,0) ;
2498  pc.defineInt("nEvents","NumEvents",0,0) ;
2499  pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
2500  pc.defineInt("expectedData","ExpectedData",0,0) ;
2501 
2502  // Process and check varargs
2503  pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
2504  if (!pc.ok(kTRUE)) {
2505  return 0 ;
2506  }
2507 
2508  // Decode command line arguments
2509  Double_t nEvents = pc.getDouble("nEventsD") ;
2510  if (nEvents<0) {
2511  nEvents = pc.getInt("nEvents") ;
2512  }
2513  //Bool_t verbose = pc.getInt("verbose") ;
2514  Bool_t extended = pc.getInt("extended") ;
2515  Bool_t expectedData = pc.getInt("expectedData") ;
2516  const char* dsetName = pc.getString("dsetName") ;
2517 
2518  if (extended) {
2519  //nEvents = (nEvents==0?Int_t(expectedEvents(&whatVars)+0.5):nEvents) ;
2520  nEvents = (nEvents==0 ? expectedEvents(&whatVars) :nEvents) ;
2521  cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
2522  << GetName() << "::expectedEvents() = " << nEvents << endl ;
2523  // If Poisson fluctuation results in zero events, stop here
2524  if (nEvents==0) {
2525  return 0 ;
2526  }
2527  } else if (nEvents==0) {
2528  cxcoutI(Generation) << "No number of events specified , number of events generated is "
2529  << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
2530  }
2531 
2532  // Forward to appropriate implementation
2533  RooDataHist* data = generateBinned(whatVars,nEvents,expectedData,extended) ;
2534 
2535  // Rename dataset to given name if supplied
2536  if (dsetName && strlen(dsetName)>0) {
2537  data->SetName(dsetName) ;
2538  }
2539 
2540  return data ;
2541 }
2542 
2543 
2544 
2545 
2546 ////////////////////////////////////////////////////////////////////////////////
2547 /// Generate a new dataset containing the specified variables with
2548 /// events sampled from our distribution. Generate the specified
2549 /// number of events or else try to use expectedEvents() if nEvents <= 0.
2550 ///
2551 /// If expectedData is kTRUE (it is kFALSE by default), the returned histogram returns the 'expected'
2552 /// data sample, i.e. no statistical fluctuations are present.
2553 ///
2554 /// Any variables of this PDF that are not in whatVars will use their
2555 /// current values and be treated as fixed parameters. Returns zero
2556 /// in case of an error. The caller takes ownership of the returned
2557 /// dataset.
2558 
2559 RooDataHist *RooAbsPdf::generateBinned(const RooArgSet &whatVars, Double_t nEvents, Bool_t expectedData, Bool_t extended) const
2560 {
2561  // Create empty RooDataHist
2562  RooDataHist* hist = new RooDataHist("genData","genData",whatVars) ;
2563 
2564  // Scale to number of events and introduce Poisson fluctuations
2565  if (nEvents<=0) {
2566  if (!canBeExtended()) {
2567  coutE(InputArguments) << "RooAbsPdf::generateBinned(" << GetName() << ") ERROR: No event count provided and p.d.f does not provide expected number of events" << endl ;
2568  delete hist ;
2569  return 0 ;
2570  } else {
2571 
2572  // Don't round in expectedData or extended mode
2573  if (expectedData || extended) {
2574  nEvents = expectedEvents(&whatVars) ;
2575  } else {
2576  nEvents = Int_t(expectedEvents(&whatVars)+0.5) ;
2577  }
2578  }
2579  }
2580 
2581  // Sample p.d.f. distribution
2582  fillDataHist(hist,&whatVars,1,kTRUE) ;
2583 
2584  vector<int> histOut(hist->numEntries()) ;
2585  Double_t histMax(-1) ;
2586  Int_t histOutSum(0) ;
2587  for (int i=0 ; i<hist->numEntries() ; i++) {
2588  hist->get(i) ;
2589  if (expectedData) {
2590 
2591  // Expected data, multiply p.d.f by nEvents
2592  Double_t w=hist->weight()*nEvents ;
2593  hist->set(w,sqrt(w)) ;
2594 
2595  } else if (extended) {
2596 
2597  // Extended mode, set contents to Poisson(pdf*nEvents)
2598  Double_t w = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
2599  hist->set(w,sqrt(w)) ;
2600 
2601  } else {
2602 
2603  // Regular mode, fill array of weights with Poisson(pdf*nEvents), but to not fill
2604  // histogram yet.
2605  if (hist->weight()>histMax) {
2606  histMax = hist->weight() ;
2607  }
2608  histOut[i] = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
2609  histOutSum += histOut[i] ;
2610  }
2611  }
2612 
2613 
2614  if (!expectedData && !extended) {
2615 
2616  // Second pass for regular mode - Trim/Extend dataset to exact number of entries
2617 
2618  // Calculate difference between what is generated so far and what is requested
2619  Int_t nEvtExtra = abs(Int_t(nEvents)-histOutSum) ;
2620  Int_t wgt = (histOutSum>nEvents) ? -1 : 1 ;
2621 
2622  // Perform simple binned accept/reject procedure to get to exact event count
2623  while(nEvtExtra>0) {
2624 
2625  Int_t ibinRand = RooRandom::randomGenerator()->Integer(hist->numEntries()) ;
2626  hist->get(ibinRand) ;
2627  Double_t ranY = RooRandom::randomGenerator()->Uniform(histMax) ;
2628 
2629  if (ranY<hist->weight()) {
2630  if (wgt==1) {
2631  histOut[ibinRand]++ ;
2632  } else {
2633  // If weight is negative, prior bin content must be at least 1
2634  if (histOut[ibinRand]>0) {
2635  histOut[ibinRand]-- ;
2636  } else {
2637  continue ;
2638  }
2639  }
2640  nEvtExtra-- ;
2641  }
2642  }
2643 
2644  // Transfer working array to histogram
2645  for (int i=0 ; i<hist->numEntries() ; i++) {
2646  hist->get(i) ;
2647  hist->set(histOut[i],sqrt(1.0*histOut[i])) ;
2648  }
2649 
2650  } else if (expectedData) {
2651 
2652  // Second pass for expectedData mode -- Normalize to exact number of requested events
2653  // Minor difference may be present in first round due to difference between
2654  // bin average and bin integral in sampling bins
2655  Double_t corr = nEvents/hist->sumEntries() ;
2656  for (int i=0 ; i<hist->numEntries() ; i++) {
2657  hist->get(i) ;
2658  hist->set(hist->weight()*corr,sqrt(hist->weight()*corr)) ;
2659  }
2660 
2661  }
2662 
2663  return hist;
2664 }
2665 
2666 
2667 
2668 ////////////////////////////////////////////////////////////////////////////////
2669 /// Special generator interface for generation of 'global observables' -- for RooStats tools
2670 
2672 {
2673  return generate(whatVars,nEvents) ;
2674 }
2675 
2676 namespace {
2677 void removeRangeOverlap(std::vector<std::pair<double, double>>& ranges) {
2678  //Sort from left to right
2679  std::sort(ranges.begin(), ranges.end());
2680 
2681  for (auto it = ranges.begin(); it != ranges.end(); ++it) {
2682  double& startL = it->first;
2683  double& endL = it->second;
2684 
2685  for (auto innerIt = it+1; innerIt != ranges.end(); ++innerIt) {
2686  const double startR = innerIt->first;
2687  const double endR = innerIt->second;
2688 
2689  if (startL <= startR && startR <= endL) {
2690  //Overlapping ranges, extend left one
2691  endL = std::max(endL, endR);
2692  *innerIt = make_pair(0., 0.);
2693  }
2694  }
2695  }
2696 
2697  auto newEnd = std::remove_if(ranges.begin(), ranges.end(),
2698  [](const std::pair<double,double>& input){
2699  return input.first == input.second;
2700  });
2701  ranges.erase(newEnd, ranges.end());
2702 }
2703 }
2704 
2705 
2706 ////////////////////////////////////////////////////////////////////////////////
2707 /// Plot (project) PDF on specified frame.
2708 /// - If a PDF is plotted in an empty frame, it
2709 /// will show a unit-normalized curve in the frame variable. When projecting a multi-
2710 /// dimensional PDF onto the frame axis, hidden parameters are taken are taken at
2711 /// their current value.
2712 /// - If a PDF is plotted in a frame in which a dataset has already been plotted, it will
2713 /// show a projection integrated over all variables that were present in the shown
2714 /// dataset (except for the one on the x-axis). The normalization of the curve will
2715 /// be adjusted to the event count of the plotted dataset. An informational message
2716 /// will be printed for each projection step that is performed.
2717 /// - If a PDF is plotted in a frame showing a dataset *after* a fit, the above happens,
2718 /// but the PDF will be drawn and normalised only in the fit range. If this is not desired,
2719 /// plotting and normalisation range can be overridden using Range() and NormRange() as
2720 /// documented in the table below.
2721 ///
2722 /// This function takes the following named arguments (for more arguments, see also
2723 /// RooAbsReal::plotOn(RooPlot*,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,
2724 /// const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,
2725 /// const RooCmdArg&) const )
2726 ///
2727 ///
2728 /// <table>
2729 /// <tr><th> Type of argument <th> Controlling normalisation
2730 /// <tr><td> `NormRange(const char* name)` <td> Calculate curve normalization w.r.t. specified range[s].
2731 /// See the tutorial rf212_plottingInRanges_blinding.C
2732 /// \note Setting a Range() by default also sets a NormRange() on the same range, meaning that the
2733 /// PDF is plotted and normalised in the same range. Overriding this can be useful if the PDF was fit
2734 /// in limited range[s] such as side bands, `NormRange("sidebandLeft,sidebandRight")`, but the PDF
2735 /// should be drawn in the full range, `Range("")`.
2736 ///
2737 /// <tr><td> `Normalization(Double_t scale, ScaleType code)` <td> Adjust normalization by given scale factor.
2738 /// Interpretation of number depends on code:
2739 /// `RooAbsReal::Relative`: relative adjustment factor
2740 /// `RooAbsReal::NumEvent`: scale to match given number of events.
2741 ///
2742 /// <tr><th> Type of argument <th> Misc control
2743 /// <tr><td> `Name(const chat* name)` <td> Give curve specified name in frame. Useful if curve is to be referenced later
2744 /// <tr><td> `Asymmetry(const RooCategory& c)` <td> Show the asymmetry of the PDF in given two-state category
2745 /// \f$ \frac{F(+)-F(-)}{F(+)+F(-)} \f$ rather than the PDF projection. Category must have two
2746 /// states with indices -1 and +1 or three states with indeces -1,0 and +1.
2747 /// <tr><td> `ShiftToZero(Bool_t flag)` <td> Shift entire curve such that lowest visible point is at exactly zero.
2748 /// Mostly useful when plotting -log(L) or \f$ \chi^2 \f$ distributions
2749 /// <tr><td> `AddTo(const char* name, double_t wgtSelf, double_t wgtOther)` <td> Create a projection of this PDF onto the x-axis, but
2750 /// instead of plotting it directly, add it to an existing curve with given name (and relative weight factors).
2751 /// <tr><td> `Components(const char* names)` <td> When plotting sums of PDFs, plot only the named components (*e.g.* only
2752 /// the signal of a signal+background model).
2753 /// <tr><td> `Components(const RooArgSet& compSet)` <td> As above, but pass a RooArgSet of the components themselves.
2754 ///
2755 /// <tr><th> Type of argument <th> Projection control
2756 /// <tr><td> `Slice(const RooArgSet& set)` <td> Override default projection behaviour by omitting
2757 /// observables listed in set from the projection, resulting in a 'slice' plot. Slicing is mostly
2758 /// needed in discrete observables such as categories.
2759 /// <tr><td> `Project(const RooArgSet& set)` <td> Override default projection behaviour by projecting
2760 /// over observables given in set and complete ignoring the default projection behavior. Advanced use only.
2761 /// <tr><td> `ProjWData(const RooAbsData& d)` <td> Override default projection _technique_ (integration). For observables
2762 /// present in given dataset projection of PDF is achieved by constructing an average over all observable
2763 /// values in given set. Consult RooFit plotting tutorial for further explanation of meaning & use of this technique
2764 /// <tr><td> `ProjWData(const RooArgSet& s, const RooAbsData& d)` <td> As above but only consider subset 's' of
2765 /// observables in dataset 'd' for projection through data averaging
2766 /// <tr><td> `ProjectionRange(const char* rn)` <td> When projecting the PDF onto the plot axis, it is usually integrated
2767 /// over the full range of the invisible variables. The ProjectionRange overrides this.
2768 /// This is useful if the PDF was fitted in a limited range in y, but it is now projected onto x. If
2769 /// `ProjectionRange("<name of fit range>")` is passed, the projection is normalised correctly.
2770 ///
2771 /// <tr><th> Type of argument <th> Plotting control
2772 /// <tr><td> `LineStyle(Int_t style)` <td> Select line style by ROOT line style code, default is solid
2773 /// <tr><td> `LineColor(Int_t color)` <td> Select line color by ROOT color code, default is blue
2774 /// <tr><td> `LineWidth(Int_t width)` <td> Select line with in pixels, default is 3
2775 /// <tr><td> `FillStyle(Int_t style)` <td> Select fill style, default is not filled. If a filled style is selected,
2776 /// also use VLines() to add vertical downward lines at end of curve to ensure proper closure
2777 /// <tr><td> `FillColor(Int_t color)` <td> Select fill color by ROOT color code
2778 /// <tr><td> `Range(const char* name)` <td> Only draw curve in range defined by given name. Multiple comma-separated ranges can be given.
2779 /// An empty string "" or `nullptr` means to use the default range of the variable.
2780 /// <tr><td> `Range(double lo, double hi)` <td> Only draw curve in specified range
2781 /// <tr><td> `VLines()` <td> Add vertical lines to y=0 at end points of curve
2782 /// <tr><td> `Precision(Double_t eps)` <td> Control precision of drawn curve w.r.t to scale of plot, default is 1e-3. A higher precision will
2783 /// result in more and more densely spaced curve points. A negative precision value will disable
2784 /// adaptive point spacing and restrict sampling to the grid point of points defined by the binning
2785 /// of the plotted observable (recommended for expensive functions such as profile likelihoods)
2786 /// <tr><td> `Invisible(Bool_t flag)` <td> Add curve to frame, but do not display. Useful in combination AddTo()
2787 /// <tr><td> `VisualizeError(const RooFitResult& fitres, Double_t Z=1, Bool_t linearMethod=kTRUE)`
2788 /// <td> Visualize the uncertainty on the parameters, as given in fitres, at 'Z' sigma.
2789 ///
2790 /// <tr><td> `VisualizeError(const RooFitResult& fitres, const RooArgSet& param, Double_t Z=1, Bool_t linearMethod=kTRUE)`
2791 /// <td> Visualize the uncertainty on the subset of parameters 'param', as given in fitres, at 'Z' sigma.
2792 /// </table>
2793 
2795 {
2796 
2797  // Pre-processing if p.d.f. contains a fit range and there is no command specifying one,
2798  // add a fit range as default range
2799  RooCmdArg* plotRange(0) ;
2800  RooCmdArg* normRange2(0);
2801  if (getStringAttribute("fitrange") && !cmdList.FindObject("Range") &&
2802  !cmdList.FindObject("RangeWithName")) {
2803  plotRange = (RooCmdArg*) RooFit::Range(getStringAttribute("fitrange")).Clone() ;
2804  cmdList.Add(plotRange) ;
2805  }
2806 
2807  if (getStringAttribute("fitrange") && !cmdList.FindObject("NormRange")) {
2808  normRange2 = (RooCmdArg*) RooFit::NormRange(getStringAttribute("fitrange")).Clone() ;
2809  cmdList.Add(normRange2) ;
2810  }
2811 
2812  if (plotRange || normRange2) {
2813  coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f was fitted in a subrange and no explicit "
2814  << (plotRange?"Range()":"") << ((plotRange&&normRange2)?" and ":"")
2815  << (normRange2?"NormRange()":"") << " was specified. Plotting / normalising in fit range. To override, do one of the following"
2816  << "\n\t- Clear the automatic fit range attribute: <pdf>.setStringAttribute(\"fitrange\", nullptr);"
2817  << "\n\t- Explicitly specify the plotting range: Range(\"<rangeName>\")."
2818  << "\n\t- Explicitly specify where to compute the normalisation: NormRange(\"<rangeName>\")."
2819  << "\n\tThe default (full) range can be denoted with Range(\"\") / NormRange(\"\")."<< endl ;
2820  }
2821 
2822  // Sanity checks
2823  if (plotSanityChecks(frame)) return frame ;
2824 
2825  // Select the pdf-specific commands
2826  RooCmdConfig pc(Form("RooAbsPdf::plotOn(%s)",GetName())) ;
2827  pc.defineDouble("scaleFactor","Normalization",0,1.0) ;
2828  pc.defineInt("scaleType","Normalization",0,Relative) ;
2829  pc.defineObject("compSet","SelectCompSet",0) ;
2830  pc.defineString("compSpec","SelectCompSpec",0) ;
2831  pc.defineObject("asymCat","Asymmetry",0) ;
2832  pc.defineDouble("rangeLo","Range",0,-999.) ;
2833  pc.defineDouble("rangeHi","Range",1,-999.) ;
2834  pc.defineString("rangeName","RangeWithName",0,"") ;
2835  pc.defineString("normRangeName","NormRange",0,"") ;
2836  pc.defineInt("rangeAdjustNorm","Range",0,0) ;
2837  pc.defineInt("rangeWNAdjustNorm","RangeWithName",0,0) ;
2838  pc.defineMutex("SelectCompSet","SelectCompSpec") ;
2839  pc.defineMutex("Range","RangeWithName") ;
2840  pc.allowUndefined() ; // unknowns may be handled by RooAbsReal
2841 
2842  // Process and check varargs
2843  pc.process(cmdList) ;
2844  if (!pc.ok(kTRUE)) {
2845  return frame ;
2846  }
2847 
2848  // Decode command line arguments
2849  ScaleType stype = (ScaleType) pc.getInt("scaleType") ;
2850  Double_t scaleFactor = pc.getDouble("scaleFactor") ;
2851  const RooAbsCategoryLValue* asymCat = (const RooAbsCategoryLValue*) pc.getObject("asymCat") ;
2852  const char* compSpec = pc.getString("compSpec") ;
2853  const RooArgSet* compSet = (const RooArgSet*) pc.getObject("compSet") ;
2854  Bool_t haveCompSel = ( (compSpec && strlen(compSpec)>0) || compSet) ;
2855 
2856  // Suffix for curve name
2857  TString nameSuffix ;
2858  if (compSpec && strlen(compSpec)>0) {
2859  nameSuffix.Append("_Comp[") ;
2860  nameSuffix.Append(compSpec) ;
2861  nameSuffix.Append("]") ;
2862  } else if (compSet) {
2863  nameSuffix.Append("_Comp[") ;
2864  nameSuffix.Append(compSet->contentsString().c_str()) ;
2865  nameSuffix.Append("]") ;
2866  }
2867 
2868  // Remove PDF-only commands from command list
2869  pc.stripCmdList(cmdList,"SelectCompSet,SelectCompSpec") ;
2870 
2871  // Adjust normalization, if so requested
2872  if (asymCat) {
2873  RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.Data(),0,0,0) ;
2874  cmdList.Add(&cnsuffix);
2875  return RooAbsReal::plotOn(frame,cmdList) ;
2876  }
2877 
2878  // More sanity checks
2879  Double_t nExpected(1) ;
2880  if (stype==RelativeExpected) {
2881  if (!canBeExtended()) {
2882  coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
2883  << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
2884  return frame ;
2885  }
2886  nExpected = expectedEvents(frame->getNormVars()) ;
2887  }
2888 
2889  if (stype != Raw) {
2890 
2891  if (frame->getFitRangeNEvt() && stype==Relative) {
2892 
2893  Bool_t hasCustomRange(kFALSE), adjustNorm(kFALSE) ;
2894 
2895  std::vector<pair<Double_t,Double_t> > rangeLim;
2896 
2897  // Retrieve plot range to be able to adjust normalization to data
2898  if (pc.hasProcessed("Range")) {
2899 
2900  Double_t rangeLo = pc.getDouble("rangeLo") ;
2901  Double_t rangeHi = pc.getDouble("rangeHi") ;
2902  rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
2903  adjustNorm = pc.getInt("rangeAdjustNorm") ;
2904  hasCustomRange = kTRUE ;
2905 
2906  coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range ["
2907  << rangeLo << "," << rangeHi << "]" ;
2908  if (!pc.hasProcessed("NormRange")) {
2909  ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " range" << endl ;
2910  } else {
2911  ccoutI(Plotting) << endl ;
2912  }
2913 
2914  nameSuffix.Append(Form("_Range[%f_%f]",rangeLo,rangeHi)) ;
2915 
2916  } else if (pc.hasProcessed("RangeWithName")) {
2917 
2918  for (const std::string& rangeNameToken : RooHelpers::tokenise(pc.getString("rangeName", "", false), ",", /*returnEmptyToken=*/true)) {
2919  const char* thisRangeName = rangeNameToken.empty() ? nullptr : rangeNameToken.c_str();
2920  if (thisRangeName && !frame->getPlotVar()->hasRange(thisRangeName)) {
2921  coutE(Plotting) << "Range '" << rangeNameToken << "' not defined for variable '"
2922  << frame->getPlotVar()->GetName() << "'. Ignoring ..." << std::endl;
2923  continue;
2924  }
2925  rangeLim.push_back(frame->getPlotVar()->getRange(thisRangeName));
2926  }
2927  adjustNorm = pc.getInt("rangeWNAdjustNorm") ;
2928  hasCustomRange = kTRUE ;
2929 
2930  coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range '" << pc.getString("rangeName", "", false) << "'" ;
2931  if (!pc.hasProcessed("NormRange")) {
2932  ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " range" << endl ;
2933  } else {
2934  ccoutI(Plotting) << endl ;
2935  }
2936 
2937  nameSuffix.Append(Form("_Range[%s]",pc.getString("rangeName"))) ;
2938  }
2939  // Specification of a normalization range override those in a regular range
2940  if (pc.hasProcessed("NormRange")) {
2941  rangeLim.clear();
2942  for (const auto& rangeNameToken : RooHelpers::tokenise(pc.getString("normRangeName", "", false), ",", /*returnEmptyToken=*/true)) {
2943  const char* thisRangeName = rangeNameToken.empty() ? nullptr : rangeNameToken.c_str();
2944  if (thisRangeName && !frame->getPlotVar()->hasRange(thisRangeName)) {
2945  coutE(Plotting) << "Range '" << rangeNameToken << "' not defined for variable '"
2946  << frame->getPlotVar()->GetName() << "'. Ignoring ..." << std::endl;
2947  continue;
2948  }
2949  rangeLim.push_back(frame->getPlotVar()->getRange(thisRangeName));
2950  }
2951  adjustNorm = kTRUE ;
2952  hasCustomRange = kTRUE ;
2953  coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f. curve is normalized using explicit choice of ranges '" << pc.getString("normRangeName", "", false) << "'" << endl ;
2954 
2955  nameSuffix.Append(Form("_NormRange[%s]",pc.getString("rangeName"))) ;
2956 
2957  }
2958 
2959  if (hasCustomRange && adjustNorm) {
2960  // If overlapping ranges were given, remove them now
2961  const std::size_t oldSize = rangeLim.size();
2962  removeRangeOverlap(rangeLim);
2963 
2964  if (oldSize != rangeLim.size() && !pc.hasProcessed("NormRange")) {
2965  // User gave overlapping ranges. This leads to double-counting events and integrals, and must
2966  // therefore be avoided. If a NormRange has been given, the overlap is alreay gone.
2967  // It's safe to plot even with overlap now.
2968  coutE(Plotting) << "Requested plot/integration ranges overlap. For correct plotting, new ranges "
2969  "will be defined." << std::endl;
2970  auto plotVar = dynamic_cast<RooRealVar*>(frame->getPlotVar());
2971  assert(plotVar);
2972  std::string rangesNoOverlap;
2973  for (auto it = rangeLim.begin(); it != rangeLim.end(); ++it) {
2974  std::stringstream rangeName;
2975  rangeName << "Remove_overlap_range_" << it - rangeLim.begin();
2976  plotVar->setRange(rangeName.str().c_str(), it->first, it->second);
2977  if (!rangesNoOverlap.empty())
2978  rangesNoOverlap += ",";
2979  rangesNoOverlap += rangeName.str();
2980  }
2981 
2982  auto rangeArg = static_cast<RooCmdArg*>(cmdList.FindObject("RangeWithName"));
2983  if (rangeArg)
2984  rangeArg->setString(0, rangesNoOverlap.c_str());
2985  else {
2986  plotRange = new RooCmdArg(RooFit::Range(rangesNoOverlap.c_str()));
2987  cmdList.Add(plotRange);
2988  }
2989  }
2990 
2991  Double_t rangeNevt(0) ;
2992  for (const auto& riter : rangeLim) {
2993  Double_t nevt= frame->getFitRangeNEvt(riter.first, riter.second);
2994  rangeNevt += nevt ;
2995  }
2996 
2997  scaleFactor *= rangeNevt/nExpected ;
2998 
2999  } else {
3000  scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
3001  }
3002  } else if (stype==RelativeExpected) {
3003  scaleFactor *= nExpected ;
3004  } else if (stype==NumEvent) {
3005  scaleFactor /= nExpected ;
3006  }
3007  scaleFactor *= frame->getFitRangeBinW() ;
3008  }
3009  frame->updateNormVars(*frame->getPlotVar()) ;
3010 
3011  // Append overriding scale factor command at end of original command list
3012  RooCmdArg tmp = RooFit::Normalization(scaleFactor,Raw) ;
3013  tmp.setInt(1,1) ; // Flag this normalization command as created for internal use (so that VisualizeError can strip it)
3014  cmdList.Add(&tmp) ;
3015 
3016  // Was a component selected requested
3017  if (haveCompSel) {
3018 
3019  // Get complete set of tree branch nodes
3020  RooArgSet branchNodeSet ;
3021  branchNodeServerList(&branchNodeSet) ;
3022 
3023  // Discard any non-RooAbsReal nodes
3024  for (const auto arg : branchNodeSet) {
3025  if (!dynamic_cast<RooAbsReal*>(arg)) {
3026  branchNodeSet.remove(*arg) ;
3027  }
3028  }
3029 
3030  // Obtain direct selection
3031  RooArgSet* dirSelNodes ;
3032  if (compSet) {
3033  dirSelNodes = (RooArgSet*) branchNodeSet.selectCommon(*compSet) ;
3034  } else {
3035  dirSelNodes = (RooArgSet*) branchNodeSet.selectByName(compSpec) ;
3036  }
3037  if (dirSelNodes->getSize()>0) {
3038  coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") directly selected PDF components: " << *dirSelNodes << endl ;
3039 
3040  // Do indirect selection and activate both
3041  plotOnCompSelect(dirSelNodes) ;
3042  } else {
3043  if (compSet) {
3044  coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection set " << *compSet << " does not match any components of p.d.f." << endl ;
3045  } else {
3046  coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection expression '" << compSpec << "' does not select any components of p.d.f." << endl ;
3047  }
3048  return 0 ;
3049  }
3050 
3051  delete dirSelNodes ;
3052  }
3053 
3054 
3055  RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.Data(),0,0,0) ;
3056  cmdList.Add(&cnsuffix);
3057 
3058  RooPlot* ret = RooAbsReal::plotOn(frame,cmdList) ;
3059 
3060  // Restore selection status ;
3061  if (haveCompSel) plotOnCompSelect(0) ;
3062 
3063  if (plotRange) {
3064  delete plotRange ;
3065  }
3066  if (normRange2) {
3067  delete normRange2 ;
3068  }
3069 
3070  return ret ;
3071 }
3072 
3073 
3074 //_____________________________________________________________________________
3075 /// Plot oneself on 'frame'. In addition to features detailed in RooAbsReal::plotOn(),
3076 /// the scale factor for a PDF can be interpreted in three different ways. The interpretation
3077 /// is controlled by ScaleType
3078 /// ```
3079 /// Relative - Scale factor is applied on top of PDF normalization scale factor
3080 /// NumEvent - Scale factor is interpreted as a number of events. The surface area
3081 /// under the PDF curve will match that of a histogram containing the specified
3082 /// number of event
3083 /// Raw - Scale factor is applied to the raw (projected) probability density.
3084 /// Not too useful, option provided for completeness.
3085 /// ```
3086 // coverity[PASS_BY_VALUE]
3088 {
3089 
3090  // Sanity checks
3091  if (plotSanityChecks(frame)) return frame ;
3092 
3093  // More sanity checks
3094  Double_t nExpected(1) ;
3095  if (o.stype==RelativeExpected) {
3096  if (!canBeExtended()) {
3097  coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
3098  << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
3099  return frame ;
3100  }
3101  nExpected = expectedEvents(frame->getNormVars()) ;
3102  }
3103 
3104  // Adjust normalization, if so requested
3105  if (o.stype != Raw) {
3106 
3107  if (frame->getFitRangeNEvt() && o.stype==Relative) {
3108  // If non-default plotting range is specified, adjust number of events in fit range
3109  o.scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
3110  } else if (o.stype==RelativeExpected) {
3111  o.scaleFactor *= nExpected ;
3112  } else if (o.stype==NumEvent) {
3113  o.scaleFactor /= nExpected ;
3114  }
3115  o.scaleFactor *= frame->getFitRangeBinW() ;
3116  }
3117  frame->updateNormVars(*frame->getPlotVar()) ;
3118 
3119  return RooAbsReal::plotOn(frame,o) ;
3120 }
3121 
3122 
3123 
3124 
3125 ////////////////////////////////////////////////////////////////////////////////
3126 /// The following named arguments are supported
3127 /// <table>
3128 /// <tr><th> Type of CmdArg <th> Effect on parameter box
3129 /// <tr><td> `Parameters(const RooArgSet& param)` <td> Only the specified subset of parameters will be shown. By default all non-constant parameters are shown.
3130 /// <tr><td> `ShowConstants(Bool_t flag)` <td> Also display constant parameters
3131 /// <tr><td> `Format(const char* optStr)` <td> \deprecated Classing parameter formatting options, provided for backward compatibility
3132 ///
3133 /// <tr><td> `Format(const char* what,...)` <td> Parameter formatting options.
3134 /// | Parameter | Format
3135 /// | ---------------------- | --------------------------
3136 /// | `const char* what` | Controls what is shown. "N" adds name, "E" adds error, "A" shows asymmetric error, "U" shows unit, "H" hides the value
3137 /// | `FixedPrecision(int n)`| Controls precision, set fixed number of digits
3138 /// | `AutoPrecision(int n)` | Controls precision. Number of shown digits is calculated from error + n specified additional digits (1 is sensible default)
3139 /// <tr><td> `Label(const chat* label)` <td> Add header label to parameter box
3140 /// <tr><td> `Layout(Double_t xmin, Double_t xmax, Double_t ymax)` <td> Specify relative position of left/right side of box and top of box.
3141 /// Coordinates are given as position on the pad between 0 and 1.
3142 /// The lower end of the box is calculated automatically from the number of lines in the box.
3143 /// </table>
3144 ///
3145 ///
3146 /// Example use:
3147 /// ```
3148 /// pdf.paramOn(frame, Label("fit result"), Format("NEU",AutoPrecision(1)) ) ;
3149 /// ```
3150 ///
3151 
3152 RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
3153  const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
3154  const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
3155 {
3156  // Stuff all arguments in a list
3157  RooLinkedList cmdList;
3158  cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
3159  cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
3160  cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
3161  cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
3162 
3163  // Select the pdf-specific commands
3164  RooCmdConfig pc(Form("RooAbsPdf::paramOn(%s)",GetName())) ;
3165  pc.defineString("label","Label",0,"") ;
3166  pc.defineDouble("xmin","Layout",0,0.50) ;
3167  pc.defineDouble("xmax","Layout",1,0.99) ;
3168  pc.defineInt("ymaxi","Layout",0,Int_t(0.95*10000)) ;
3169  pc.defineInt("showc","ShowConstants",0,0) ;
3170  pc.defineObject("params","Parameters",0,0) ;
3171  pc.defineString("formatStr","Format",0,"NELU") ;
3172  pc.defineInt("sigDigit","Format",0,2) ;
3173  pc.defineInt("dummy","FormatArgs",0,0) ;
3174  pc.defineMutex("Format","FormatArgs") ;
3175 
3176  // Process and check varargs
3177  pc.process(cmdList) ;
3178  if (!pc.ok(kTRUE)) {
3179  return frame ;
3180  }
3181 
3182  const char* label = pc.getString("label") ;
3183  Double_t xmin = pc.getDouble("xmin") ;
3184  Double_t xmax = pc.getDouble("xmax") ;
3185  Double_t ymax = pc.getInt("ymaxi") / 10000. ;
3186  Int_t showc = pc.getInt("showc") ;
3187 
3188 
3189  const char* formatStr = pc.getString("formatStr") ;
3190  Int_t sigDigit = pc.getInt("sigDigit") ;
3191 
3192  // Decode command line arguments
3193  RooArgSet* params = static_cast<RooArgSet*>(pc.getObject("params")) ;
3194  if (!params) {
3195  params = getParameters(frame->getNormVars()) ;
3196  if (pc.hasProcessed("FormatArgs")) {
3197  const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
3198  paramOn(frame,*params,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
3199  } else {
3200  paramOn(frame,*params,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
3201  }
3202  delete params ;
3203  } else {
3204  RooArgSet* pdfParams = getParameters(frame->getNormVars()) ;
3205  RooArgSet* selParams = static_cast<RooArgSet*>(pdfParams->selectCommon(*params)) ;
3206  if (pc.hasProcessed("FormatArgs")) {
3207  const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
3208  paramOn(frame,*selParams,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
3209  } else {
3210  paramOn(frame,*selParams,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
3211  }
3212  delete selParams ;
3213  delete pdfParams ;
3214  }
3215 
3216  return frame ;
3217 }
3218 
3219 
3220 
3221 
3222 ////////////////////////////////////////////////////////////////////////////////
3223 /// \deprecated Obsolete, provided for backward compatibility. Don't use.
3224 
3225 RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooAbsData* data, const char *label,
3226  Int_t sigDigits, Option_t *options, Double_t xmin,
3228 {
3229  RooArgSet* params = getParameters(data) ;
3230  TString opts(options) ;
3231  paramOn(frame,*params,opts.Contains("c"),label,sigDigits,options,xmin,xmax,ymax) ;
3232  delete params ;
3233  return frame ;
3234 }
3235 
3236 
3237 
3238 ////////////////////////////////////////////////////////////////////////////////
3239 /// Add a text box with the current parameter values and their errors to the frame.
3240 /// Observables of this PDF appearing in the 'data' dataset will be omitted.
3241 ///
3242 /// Optional label will be inserted as first line of the text box. Use 'sigDigits'
3243 /// to modify the default number of significant digits printed. The 'xmin,xmax,ymax'
3244 /// values specify the initial relative position of the text box in the plot frame
3245 
3246 RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooArgSet& params, Bool_t showConstants, const char *label,
3247  Int_t sigDigits, Option_t *options, Double_t xmin,
3248  Double_t xmax ,Double_t ymax, const RooCmdArg* formatCmd)
3249 {
3250 
3251  // parse the options
3252  TString opts = options;
3253  opts.ToLower();
3254  Bool_t showLabel= (label != 0 && strlen(label) > 0);
3255 
3256  // calculate the box's size, adjusting for constant parameters
3257  TIterator* pIter = params.createIterator() ;
3258 
3259  Double_t ymin(ymax), dy(0.06);
3260  RooRealVar *var = 0;
3261  while((var=(RooRealVar*)pIter->Next())) {
3262  if(showConstants || !var->isConstant()) ymin-= dy;
3263  }
3264 
3265  if(showLabel) ymin-= dy;
3266 
3267  // create the box and set its options
3268  TPaveText *box= new TPaveText(xmin,ymax,xmax,ymin,"BRNDC");
3269  if(!box) return 0;
3270  box->SetName(Form("%s_paramBox",GetName())) ;
3271  box->SetFillColor(0);
3272  box->SetBorderSize(1);
3273  box->SetTextAlign(12);
3274  box->SetTextSize(0.04F);
3275  box->SetFillStyle(1001);
3276  box->SetFillColor(0);
3277  //char buffer[512];
3278  pIter->Reset() ;
3279  while((var=(RooRealVar*)pIter->Next())) {
3280  if(var->isConstant() && !showConstants) continue;
3281 
3282  TString *formatted= options ? var->format(sigDigits, options) : var->format(*formatCmd) ;
3283  box->AddText(formatted->Data());
3284  delete formatted;
3285  }
3286  // add the optional label if specified
3287  if(showLabel) box->AddText(label);
3288 
3289  // Add box to frame
3290  frame->addObject(box) ;
3291 
3292  delete pIter ;
3293  return frame ;
3294 }
3295 
3296 
3297 
3298 
3299 ////////////////////////////////////////////////////////////////////////////////
3300 /// Return expected number of events from this p.d.f for use in extended
3301 /// likelihood calculations. This default implementation returns zero
3302 
3304 {
3305  return 0 ;
3306 }
3307 
3308 
3309 
3310 ////////////////////////////////////////////////////////////////////////////////
3311 /// Change global level of verbosity for p.d.f. evaluations
3312 
3314 {
3315  _verboseEval = stat ;
3316 }
3317 
3318 
3319 
3320 ////////////////////////////////////////////////////////////////////////////////
3321 /// Return global level of verbosity for p.d.f. evaluations
3322 
3324 {
3325  return _verboseEval ;
3326 }
3327 
3328 
3329 
3330 ////////////////////////////////////////////////////////////////////////////////
3331 /// Dummy implementation
3332 
3334 {
3335 }
3336 
3337 
3338 
3339 ////////////////////////////////////////////////////////////////////////////////
3340 /// Destructor of normalization cache element. If this element
3341 /// provides the 'current' normalization stored in RooAbsPdf::_norm
3342 /// zero _norm pointer here before object pointed to is deleted here
3343 
3345 {
3346  // Zero _norm pointer in RooAbsPdf if it is points to our cache payload
3347  if (_owner) {
3348  RooAbsPdf* pdfOwner = static_cast<RooAbsPdf*>(_owner) ;
3349  if (pdfOwner->_norm == _norm) {
3350  pdfOwner->_norm = 0 ;
3351  }
3352  }
3353 
3354  delete _norm ;
3355 }
3356 
3357 
3358 
3359 ////////////////////////////////////////////////////////////////////////////////
3360 /// Return a p.d.f that represent a projection of this p.d.f integrated over given observables
3361 
3363 {
3364  // Construct name for new object
3365  TString name(GetName()) ;
3366  name.Append("_Proj[") ;
3367  if (iset.getSize()>0) {
3368  TIterator* iter = iset.createIterator() ;
3369  RooAbsArg* arg ;
3370  Bool_t first(kTRUE) ;
3371  while((arg=(RooAbsArg*)iter->Next())) {
3372  if (first) {
3373  first=kFALSE ;
3374  } else {
3375  name.Append(",") ;
3376  }
3377  name.Append(arg->GetName()) ;
3378  }
3379  delete iter ;
3380  }
3381  name.Append("]") ;
3382 
3383  // Return projected p.d.f.
3384  return new RooProjectedPdf(name.Data(),name.Data(),*this,iset) ;
3385 }
3386 
3387 
3388 
3389 ////////////////////////////////////////////////////////////////////////////////
3390 /// Create a cumulative distribution function of this p.d.f in terms
3391 /// of the observables listed in iset. If no nset argument is given
3392 /// the c.d.f normalization is constructed over the integrated
3393 /// observables, so that its maximum value is precisely 1. It is also
3394 /// possible to choose a different normalization for
3395 /// multi-dimensional p.d.f.s: eg. for a pdf f(x,y,z) one can
3396 /// construct a partial cdf c(x,y) that only when integrated itself
3397 /// over z results in a maximum value of 1. To construct such a cdf pass
3398 /// z as argument to the optional nset argument
3399 
3401 {
3402  return createCdf(iset,RooFit::SupNormSet(nset)) ;
3403 }
3404 
3405 
3406 
3407 ////////////////////////////////////////////////////////////////////////////////
3408 /// Create an object that represents the integral of the function over one or more observables listed in `iset`.
3409 /// The actual integration calculation is only performed when the return object is evaluated. The name
3410 /// of the integral object is automatically constructed from the name of the input function, the variables
3411 /// it integrates and the range integrates over
3412 ///
3413 /// The following named arguments are accepted
3414 /// | Type of CmdArg | Effect on CDF
3415 /// | ---------------------|-------------------
3416 /// | SupNormSet(const RooArgSet&) | Observables over which should be normalized _in addition_ to the integration observables
3417 /// | ScanNumCdf() | Apply scanning technique if cdf integral involves numeric integration [ default ]
3418 /// | ScanAllCdf() | Always apply scanning technique
3419 /// | ScanNoCdf() | Never apply scanning technique
3420 /// | 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
3421 
3422 RooAbsReal* RooAbsPdf::createCdf(const RooArgSet& iset, const RooCmdArg& arg1, const RooCmdArg& arg2,
3423  const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
3424  const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
3425 {
3426  // Define configuration for this method
3427  RooCmdConfig pc(Form("RooAbsReal::createCdf(%s)",GetName())) ;
3428  pc.defineObject("supNormSet","SupNormSet",0,0) ;
3429  pc.defineInt("numScanBins","ScanParameters",0,1000) ;
3430  pc.defineInt("intOrder","ScanParameters",1,2) ;
3431  pc.defineInt("doScanNum","ScanNumCdf",0,1) ;
3432  pc.defineInt("doScanAll","ScanAllCdf",0,0) ;
3433  pc.defineInt("doScanNon","ScanNoCdf",0,0) ;
3434  pc.defineMutex("ScanNumCdf","ScanAllCdf","ScanNoCdf") ;
3435 
3436  // Process & check varargs
3437  pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
3438  if (!pc.ok(kTRUE)) {
3439  return 0 ;
3440  }
3441 
3442  // Extract values from named arguments
3443  const RooArgSet* snset = static_cast<const RooArgSet*>(pc.getObject("supNormSet",0)) ;
3444  RooArgSet nset ;
3445  if (snset) {
3446  nset.add(*snset) ;
3447  }
3448  Int_t numScanBins = pc.getInt("numScanBins") ;
3449  Int_t intOrder = pc.getInt("intOrder") ;
3450  Int_t doScanNum = pc.getInt("doScanNum") ;
3451  Int_t doScanAll = pc.getInt("doScanAll") ;
3452  Int_t doScanNon = pc.getInt("doScanNon") ;
3453 
3454  // If scanning technique is not requested make integral-based cdf and return
3455  if (doScanNon) {
3456  return createIntRI(iset,nset) ;
3457  }
3458  if (doScanAll) {
3459  return createScanCdf(iset,nset,numScanBins,intOrder) ;
3460  }
3461  if (doScanNum) {
3463  Int_t isNum= (tmp->numIntRealVars().getSize()>0) ;
3464  delete tmp ;
3465 
3466  if (isNum) {
3467  coutI(NumIntegration) << "RooAbsPdf::createCdf(" << GetName() << ") integration over observable(s) " << iset << " involves numeric integration," << endl
3468  << " constructing cdf though numeric integration of sampled pdf in " << numScanBins << " bins and applying order "
3469  << intOrder << " interpolation on integrated histogram." << endl
3470  << " To override this choice of technique use argument ScanNone(), to change scan parameters use ScanParameters(nbins,order) argument" << endl ;
3471  }
3472 
3473  return isNum ? createScanCdf(iset,nset,numScanBins,intOrder) : createIntRI(iset,nset) ;
3474  }
3475  return 0 ;
3476 }
3477 
3478 RooAbsReal* RooAbsPdf::createScanCdf(const RooArgSet& iset, const RooArgSet& nset, Int_t numScanBins, Int_t intOrder)
3479 {
3480  string name = string(GetName()) + "_NUMCDF_" + integralNameSuffix(iset,&nset).Data() ;
3481  RooRealVar* ivar = (RooRealVar*) iset.first() ;
3482  ivar->setBins(numScanBins,"numcdf") ;
3483  RooNumCdf* ret = new RooNumCdf(name.c_str(),name.c_str(),*this,*ivar,"numcdf") ;
3484  ret->setInterpolationOrder(intOrder) ;
3485  return ret ;
3486 }
3487 
3488 
3489 
3490 
3491 ////////////////////////////////////////////////////////////////////////////////
3492 /// This helper function finds and collects all constraints terms of all component p.d.f.s
3493 /// and returns a RooArgSet with all those terms.
3494 
3495 RooArgSet* RooAbsPdf::getAllConstraints(const RooArgSet& observables, RooArgSet& constrainedParams, Bool_t stripDisconnected) const
3496 {
3497  RooArgSet* ret = new RooArgSet("AllConstraints") ;
3498 
3499  std::unique_ptr<RooArgSet> comps(getComponents());
3500  for (const auto arg : *comps) {
3501  auto pdf = dynamic_cast<const RooAbsPdf*>(arg) ;
3502  if (pdf && !ret->find(pdf->GetName())) {
3503  std::unique_ptr<RooArgSet> compRet(pdf->getConstraints(observables,constrainedParams,stripDisconnected));
3504  if (compRet) {
3505  ret->add(*compRet,kFALSE) ;
3506  }
3507  }
3508  }
3509 
3510  return ret ;
3511 }
3512 
3513 
3514 ////////////////////////////////////////////////////////////////////////////////
3515 /// Returns the default numeric MC generator configuration for all RooAbsReals
3516 
3518 {
3519  return &RooNumGenConfig::defaultConfig() ;
3520 }
3521 
3522 
3523 ////////////////////////////////////////////////////////////////////////////////
3524 /// Returns the specialized integrator configuration for _this_ RooAbsReal.
3525 /// If this object has no specialized configuration, a null pointer is returned
3526 
3528 {
3529  return _specGeneratorConfig ;
3530 }
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 /// unless createOnTheFly is kTRUE in which case a clone of the default integrator
3538 /// configuration is created, installed as specialized configuration, and returned
3539 
3541 {
3542  if (!_specGeneratorConfig && createOnTheFly) {
3544  }
3545  return _specGeneratorConfig ;
3546 }
3547 
3548 
3549 
3550 ////////////////////////////////////////////////////////////////////////////////
3551 /// Return the numeric MC generator configuration used for this object. If
3552 /// a specialized configuration was associated with this object, that configuration
3553 /// is returned, otherwise the default configuration for all RooAbsReals is returned
3554 
3556 {
3557  const RooNumGenConfig* config = specialGeneratorConfig() ;
3558  if (config) return config ;
3559  return defaultGeneratorConfig() ;
3560 }
3561 
3562 
3563 
3564 ////////////////////////////////////////////////////////////////////////////////
3565 /// Set the given configuration as default numeric MC generator
3566 /// configuration for this object
3567 
3569 {
3570  if (_specGeneratorConfig) {
3571  delete _specGeneratorConfig ;
3572  }
3573  _specGeneratorConfig = new RooNumGenConfig(config) ;
3574 }
3575 
3576 
3577 
3578 ////////////////////////////////////////////////////////////////////////////////
3579 /// Remove the specialized numeric MC generator configuration associated
3580 /// with this object
3581 
3583 {
3584  if (_specGeneratorConfig) {
3585  delete _specGeneratorConfig ;
3586  }
3587  _specGeneratorConfig = 0 ;
3588 }
3589 
3590 
3591 
3592 ////////////////////////////////////////////////////////////////////////////////
3593 
3595 {
3596  delete _genContext ;
3597 }
3598 
3599 
3600 ////////////////////////////////////////////////////////////////////////////////
3601 
3602 RooAbsPdf::GenSpec::GenSpec(RooAbsGenContext* context, const RooArgSet& whatVars, RooDataSet* protoData, Int_t nGen,
3603  Bool_t extended, Bool_t randProto, Bool_t resampleProto, TString dsetName, Bool_t init) :
3604  _genContext(context), _whatVars(whatVars), _protoData(protoData), _nGen(nGen), _extended(extended),
3605  _randProto(randProto), _resampleProto(resampleProto), _dsetName(dsetName), _init(init)
3606 {
3607 }
3608 
3609 
3610 
3611 ////////////////////////////////////////////////////////////////////////////////
3612 
3613 void RooAbsPdf::setNormRange(const char* rangeName)
3614 {
3615  if (rangeName) {
3616  _normRange = rangeName ;
3617  } else {
3618  _normRange.Clear() ;
3619  }
3620 
3621  if (_norm) {
3622  _normMgr.sterilize() ;
3623  _norm = 0 ;
3624  }
3625 }
3626 
3627 
3628 ////////////////////////////////////////////////////////////////////////////////
3629 
3630 void RooAbsPdf::setNormRangeOverride(const char* rangeName)
3631 {
3632  if (rangeName) {
3633  _normRangeOverride = rangeName ;
3634  } else {
3636  }
3637 
3638  if (_norm) {
3639  _normMgr.sterilize() ;
3640  _norm = 0 ;
3641  }
3642 }
RooAbsArg::Clone
virtual TObject * Clone(const char *newname=0) const
Make a clone of an object using the Streamer facility.
Definition: RooAbsArg.h:85
RooAbsReal::analyticalIntegral
virtual Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
Definition: RooAbsReal.cxx:415
RooAbsRealLValue::getRange
std::pair< double, double > getRange(const char *name=0) const
Get low and high bound of the variable.
Definition: RooAbsRealLValue.h:87
RooAbsPdf::createScanCdf
RooAbsReal * createScanCdf(const RooArgSet &iset, const RooArgSet &nset, Int_t numScanBins, Int_t intOrder)
Definition: RooAbsPdf.cxx:3478
l
auto * l
Definition: textangle.C:4
RooAbsPdf::_normSet
RooArgSet * _normSet
Normalization integral (owned by _normMgr)
Definition: RooAbsPdf.h:321
RooCacheManager::setObj
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=0)
Definition: RooCacheManager.h:49
m
auto * m
Definition: textangle.C:8
RooBinnedGenContext.h
RooAbsReal::NumEvent
@ NumEvent
Definition: RooAbsReal.h:253
RooAbsPdf::CacheElem
friend class CacheElem
Definition: RooAbsPdf.h:333
RooAbsArg::ADirty
@ ADirty
Definition: RooAbsArg.h:491
RooAbsPdf::_normRange
TString _normRange
MC generator configuration specific for this object.
Definition: RooAbsPdf.h:354
RooWorkspace.h
RooCmdArg
Definition: RooCmdArg.h:27
RooAbsPdf::genContext
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE) const
Interface function to create a generator context from a p.d.f.
Definition: RooAbsPdf.cxx:2005
first
Definition: first.py:1
RooHelpers.h
RooFit::Minimization
@ Minimization
Definition: RooGlobalFunc.h:67
ymax
float ymax
Definition: THbookFile.cxx:95
RooAbsArg::operMode
OperMode operMode() const
Definition: RooAbsArg.h:492
RooAbsPdf::generateSimGlobal
virtual RooDataSet * generateSimGlobal(const RooArgSet &whatVars, Int_t nEvents)
Special generator interface for generation of 'global observables' – for RooStats tools.
Definition: RooAbsPdf.cxx:2671
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
RooCmdConfig.h
e
#define e(i)
Definition: RSha256.hxx:121
RooMinuit.h
RooAbsReal::setEvalErrorLoggingMode
static void setEvalErrorLoggingMode(ErrorLoggingMode m)
Set evaluation error logging mode.
Definition: RooAbsReal.cxx:4838
RooMsgService.h
RooAbsPdf::traceEvalPdf
Bool_t traceEvalPdf(Double_t value) const
Check that passed value is positive and not 'not-a-number'.
Definition: RooAbsPdf.cxx:428
ccoutD
#define ccoutD(a)
Definition: RooMsgService.h:37
RooAbsCollection::first
RooAbsArg * first() const
Definition: RooAbsCollection.h:176
RooPlot::updateNormVars
void updateNormVars(const RooArgSet &vars)
Install the given set of observables are reference normalization variables for this frame.
Definition: RooPlot.cxx:380
RooAbsPdf::autoGenContext
virtual RooAbsGenContext * autoGenContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE, Bool_t autoBinned=kTRUE, const char *binnedTag="") const
Definition: RooAbsPdf.cxx:2014
RooAbsReal::logEvalError
void logEvalError(const char *message, const char *serverValueString=0) const
Log evaluation error message.
Definition: RooAbsReal.cxx:3728
RooAbsData::isNonPoissonWeighted
virtual Bool_t isNonPoissonWeighted() const
Definition: RooAbsData.h:114
RooAbsData
Definition: RooAbsData.h:46
RooNumIntConfig.h
RooAbsPdf::setNormRangeOverride
void setNormRangeOverride(const char *rangeName)
Definition: RooAbsPdf.cxx:3630
RooAbsPdf::generateEvent
virtual void generateEvent(Int_t code)
Interface for generation of an event using the algorithm corresponding to the specified code.
Definition: RooAbsPdf.cxx:2435
RooFit.h
RooFit::InputArguments
@ InputArguments
Definition: RooGlobalFunc.h:68
RooDataHist::set
void set(Double_t weight, Double_t wgtErr=-1)
Set the weight and weight error of the bin enclosing the current (i.e.
Definition: RooDataHist.cxx:1332
RooAbsArg::getComponents
RooArgSet * getComponents() const
Create a RooArgSet with all components (branch nodes) of the expression tree headed by this object.
Definition: RooAbsArg.cxx:679
RooCacheManager::getObj
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
Definition: RooCacheManager.h:44
RooAbsPdf::getLogValBatch
RooSpan< const double > getLogValBatch(std::size_t begin, std::size_t batchSize, const RooArgSet *normSet=nullptr) const
Compute the log-likelihoods for all events in the requested batch.
Definition: RooAbsPdf.cxx:740
RooAbsPdf::extendMode
virtual ExtendMode extendMode() const
Definition: RooAbsPdf.h:230
RooFit::PrintLevel
RooCmdArg PrintLevel(Int_t code)
Definition: RooGlobalFunc.cxx:189
RooArgSet.h
RooAbsReal::isBinnedDistribution
virtual Bool_t isBinnedDistribution(const RooArgSet &) const
Definition: RooAbsReal.h:313
RooRealVar::format
TString * format(const RooCmdArg &formatArg) const
Format contents of RooRealVar for pretty printing on RooPlot parameter boxes.
Definition: RooRealVar.cxx:827
TString::Data
const char * Data() const
Definition: TString.h:369
RooAbsData::isWeighted
virtual Bool_t isWeighted() const
Definition: RooAbsData.h:110
RooAbsPdf::CanBeExtended
@ CanBeExtended
Definition: RooAbsPdf.h:229
F
#define F(x, y, z)
RooAbsReal::createIntegral
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:561
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
Form
char * Form(const char *fmt,...)
TNamed::GetTitle
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:54
RooRealIntegral::numIntRealVars
const RooArgSet & numIntRealVars() const
Definition: RooRealIntegral.h:53
RooAbsArg::Print
virtual void Print(Option_t *options=0) const
Print the object to the defaultPrintStream().
Definition: RooAbsArg.h:320
RooRandom::integer
static UInt_t integer(UInt_t max, TRandom *generator=randomGenerator())
Return an integer uniformly distributed from [0,n-1].
Definition: RooRandom.cxx:101
RooXYChi2Var.h
xmax
float xmax
Definition: THbookFile.cxx:95
RooAbsArg::_serverList
RefCountList_t _serverList
Definition: RooAbsArg.h:587
RooNumCdf
Definition: RooNumCdf.h:17
RooAbsReal::CollectErrors
@ CollectErrors
Definition: RooAbsReal.h:298
RooPlot::getFitRangeNEvt
Double_t getFitRangeNEvt() const
Return the number of events in the fit range.
Definition: RooPlot.h:141
coutE
#define coutE(a)
Definition: RooMsgService.h:33
RooAbsPdf::binnedGenContext
virtual RooAbsGenContext * binnedGenContext(const RooArgSet &vars, Bool_t verbose=kFALSE) const
Return a binned generator context.
Definition: RooAbsPdf.cxx:1995
RooCachedReal::setCacheSource
void setCacheSource(Bool_t flag)
Definition: RooCachedReal.h:53
coutW
#define coutW(a)
Definition: RooMsgService.h:32
output
static void output(int code)
Definition: gifencode.c:226
RooAbsPdf::createCdf
RooAbsReal * createCdf(const RooArgSet &iset, const RooArgSet &nset=RooArgSet())
Create a cumulative distribution function of this p.d.f in terms of the observables listed in iset.
Definition: RooAbsPdf.cxx:3400
RooArgList
Definition: RooArgList.h:21
RooGenContext
Definition: RooGenContext.h:30
RooFit::WeightVar
RooCmdArg WeightVar(const char *name, Bool_t reinterpretAsWeight=kFALSE)
Definition: RooGlobalFunc.cxx:123
RooAbsData::weight
virtual Double_t weight() const =0
BatchHelpers::init
EvaluateInfo init(std::vector< RooRealProxy > parameters, std::vector< ArrayWrapper * > wrappers, std::vector< double * > arrays, size_t begin, size_t batchSize)
RooFit::Hesse
RooCmdArg Hesse(Bool_t flag=kTRUE)
Definition: RooGlobalFunc.cxx:193
RooAbsReal::plotSanityChecks
Bool_t plotSanityChecks(RooPlot *frame) const
Utility function for plotOn(), perform general sanity check on frame to ensure safe plotting operatio...
Definition: RooAbsReal.cxx:3075
RooAbsReal::getVal
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
RooDataHist::get
virtual const RooArgSet * get() const
Definition: RooDataHist.h:78
log
double log(double)
RooAbsGenContext::generate
virtual RooDataSet * generate(Double_t nEvents=0, Bool_t skipInit=kFALSE, Bool_t extendedMode=kFALSE)
Generate the specified number of events with nEvents>0 and and return a dataset containing the genera...
Definition: RooAbsGenContext.cxx:152
Int_t
int Int_t
Definition: RtypesCore.h:45
RooAbsPdf::getValV
virtual Double_t getValV(const RooArgSet *set=0) const
Return current value, normalized by integrating over the observables in nset.
Definition: RooAbsPdf.cxx:278
RooAbsPdf::printMultiline
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Print multi line detailed information of this RooAbsPdf.
Definition: RooAbsPdf.cxx:1978
RooChi2Var
Definition: RooChi2Var.h:25
box
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
RooAbsPdf::RooAbsPdf
RooAbsPdf()
Default constructor.
Definition: RooAbsPdf.cxx:202
TRandom::Uniform
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition: TRandom.cxx:635
RooFit::Normalization
RooCmdArg Normalization(Double_t scaleFactor)
Definition: RooGlobalFunc.cxx:51
RooFit::MPSplit
MPSplit
Definition: RooGlobalFunc.h:70
RooCmdArg::setInt
void setInt(Int_t idx, Int_t value)
Definition: RooCmdArg.h:66
TNamed::fName
TString fName
Definition: TNamed.h:38
RooAbsCollection::find
RooAbsArg * find(const char *name) const
Find object with given name in list.
Definition: RooAbsCollection.cxx:813
RooAbsPdf::specialGeneratorConfig
RooNumGenConfig * specialGeneratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
Definition: RooAbsPdf.cxx:3527
TGeant4Unit::pc
static constexpr double pc
Definition: TGeant4SystemOfUnits.h:136
TString::Contains
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
RooCurve.h
RooDataHist::weight
virtual Double_t weight() const
Definition: RooDataHist.h:105
RooAbsArg::setOperMode
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Change cache operation mode to given mode.
Definition: RooAbsArg.cxx:1720
_rf_fast_log
double _rf_fast_log(double x)
Definition: RooVDTHeaders.h:51
RooAbsPdf::CacheElem::_norm
RooAbsReal * _norm
Definition: RooAbsPdf.h:329
RooAbsPdf::GenSpec
Definition: RooAbsPdf.h:70
RooAbsPdf::getGenerator
virtual Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, Bool_t staticInitOK=kTRUE) const
Load generatedVars with the subset of directVars that we can generate events for, and return a code t...
Definition: RooAbsPdf.cxx:2413
TString::Length
Ssiz_t Length() const
Definition: TString.h:410
RooAbsPdf::CacheElem
Normalization set with for above integral.
Definition: RooAbsPdf.h:323
coutI
#define coutI(a)
Definition: RooMsgService.h:30
TClass.h
TList.h
indent
static void indent(ostringstream &buf, int indent_level)
Definition: TClingCallFunc.cxx:87
RooObjCacheManager::sterilize
void sterilize()
Clear the cache payload but retain slot mapping w.r.t to normalization and integration sets.
Definition: RooObjCacheManager.cxx:159
RooPrintable::kAddress
@ kAddress
Definition: RooPrintable.h:33
RooArgSet::add
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
BatchHelpers::BatchData::kReady
@ kReady
Definition: BatchData.h:36
RooAbsPdf::defaultGeneratorConfig
static RooNumGenConfig * defaultGeneratorConfig()
Returns the default numeric MC generator configuration for all RooAbsReals.
Definition: RooAbsPdf.cxx:3517
RooAbsReal
Definition: RooAbsReal.h:61
TMatrixTSym
Definition: TMatrixDSymfwd.h:22
RooDataSet::SetName
void SetName(const char *name) override
Change the name of this dataset into the given name.
Definition: RooDataSet.cxx:1990
RooArgList::at
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Definition: RooArgList.h:88
RooAbsPdf::initGenerator
virtual void initGenerator(Int_t code)
Interface for one-time initialization to setup the generator for the specified code.
Definition: RooAbsPdf.cxx:2423
RooAbsPdf::_normMgr
RooObjCacheManager _normMgr
Definition: RooAbsPdf.h:331
RooNameSet::select
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:185
RooAbsPdf::chi2FitTo
virtual RooFitResult * chi2FitTo(RooDataHist &data, const RooLinkedList &cmdList)
Calls RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
Definition: RooAbsPdf.cxx:1812
TString
Definition: TString.h:136
RooLinkedList::FindObject
TObject * FindObject(const char *name) const
Return pointer to obejct with given name.
Definition: RooLinkedList.cxx:539
RooRealVar::setRange
void setRange(const char *name, Double_t min, Double_t max)
Set a fit or plotting range.
Definition: RooRealVar.cxx:496
RooWorkspace::set
const RooArgSet * set(const char *name)
Return pointer to previously defined named set with given nmame If no such set is found a null pointe...
Definition: RooWorkspace.cxx:977
RooAbsPdf::_traceCount
Int_t _traceCount
Definition: RooAbsPdf.h:347
TObject::InheritsFrom
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
RooAbsPdf::createChi2
virtual RooAbsReal * createChi2(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())
Create a from a histogram and this function.
Definition: RooAbsPdf.cxx:1857
RooDataSet.h
TString::Clear
void Clear()
Clear string without changing its capacity.
Definition: TString.cxx:1176
RooAbsPdf::isDirectGenSafe
virtual Bool_t isDirectGenSafe(const RooAbsArg &arg) const
Check if given observable can be safely generated using the pdfs internal generator mechanism (if tha...
Definition: RooAbsPdf.cxx:2448
RooNLLVar.h
RooFit::NumIntegration
@ NumIntegration
Definition: RooGlobalFunc.h:69
RooAbsArg::branchNodeServerList
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:488
RooAbsPdf::GenSpec::GenSpec
GenSpec()
Definition: RooAbsPdf.h:73
RooAbsPdf::plotOn
virtual RooPlot * plotOn(RooPlot *frame, 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 RooCmdArg &arg9=RooCmdArg::none(), const RooCmdArg &arg10=RooCmdArg::none()) const
Helper calling plotOn(RooPlot*, RooLinkedList&) const.
Definition: RooAbsPdf.h:118
bool
CholeskyDecomp.h
TIterator
Definition: TIterator.h:30
RooFitResult
Definition: RooFitResult.h:40
RooAbsReal::ScaleType
ScaleType
Definition: RooAbsReal.h:253
RooChi2Var.h
RooInt
Definition: RooInt.h:22
TPaveText.h
RooAbsReal::PlotOpt::scaleFactor
Double_t scaleFactor
Definition: RooAbsReal.h:470
TMatrixDSym.h
RooConstraintSum.h
RooProjectedPdf.h
RooAbsPdf::verboseEval
static int verboseEval()
Return global level of verbosity for p.d.f. evaluations.
Definition: RooAbsPdf.cxx:3323
RooAbsGenContext::setProtoDataOrder
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
Definition: RooAbsGenContext.cxx:348
RooSpan::size
constexpr std::span< T >::index_type size() const noexcept
Definition: RooSpan.h:136
RooAbsPdf::setTraceCounter
void setTraceCounter(Int_t value, Bool_t allNodes=kFALSE)
Reset trace counter to given value, limiting the number of future trace messages for this pdf to 'val...
Definition: RooAbsPdf.cxx:633
RooRealIntegral
Definition: RooRealIntegral.h:34
RooCmdArg::setString
void setString(Int_t idx, const char *value)
Definition: RooCmdArg.h:72
RooAbsPdf::getNormObj
virtual const RooAbsReal * getNormObj(const RooArgSet *set, const RooArgSet *iset, const TNamed *rangeName=0) const
Return pointer to RooAbsReal object that implements calculation of integral over observables iset in ...
Definition: RooAbsPdf.cxx:487
RooAbsPdf::setGeneratorConfig
void setGeneratorConfig()
Remove the specialized numeric MC generator configuration associated with this object.
Definition: RooAbsPdf.cxx:3582
RooCmdConfig
Definition: RooCmdConfig.h:27
RooAbsPdf::_errorCount
Int_t _errorCount
Definition: RooAbsPdf.h:343
RooAbsPdf::extendedTerm
virtual Double_t extendedTerm(Double_t observedEvents, const RooArgSet *nset=0) const
Return the extended likelihood term ( ) of this PDF for the given number of observed events.
Definition: RooAbsPdf.cxx:777
RooAbsArg::getParameters
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:546
RooPlot::addObject
void addObject(TObject *obj, Option_t *drawOptions="", Bool_t invisible=kFALSE)
Add a generic object to this plot.
Definition: RooPlot.cxx:422
TObject::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
RooPlot::getFitRangeBinW
Double_t getFitRangeBinW() const
Return the bin width that is being used to normalise the PDF.
Definition: RooPlot.h:144
RooAbsCollection::selectByName
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 ...
Definition: RooAbsCollection.cxx:723
ccoutI
#define ccoutI(a)
Definition: RooMsgService.h:38
RooAbsPdf::MustBeExtended
@ MustBeExtended
Definition: RooAbsPdf.h:229
BatchHelpers::BatchData::kgetLogVal
@ kgetLogVal
Definition: BatchData.h:37
RooDataSet::add
virtual void add(const RooArgSet &row, Double_t weight=1.0, Double_t weightError=0) override
Add a data point, with its coordinates specified in the 'data' argset, to the data set.
Definition: RooDataSet.cxx:1164
RooAbsArg::setStringAttribute
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
Definition: RooAbsArg.cxx:291
RooAbsPdf::~RooAbsPdf
virtual ~RooAbsPdf()
Destructor.
Definition: RooAbsPdf.cxx:260
RooParamBinning.h
RooAbsReal::PlotOpt
Definition: RooAbsReal.h:464
RooAbsPdf::setNormRange
void setNormRange(const char *rangeName)
Definition: RooAbsPdf.cxx:3613
ROOT::Math::fabs
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
Definition: UnaryOperators.h:131
RooDataHist
Definition: RooDataHist.h:39
RooCachedReal.h
RooPrintable::kName
@ kName
Definition: RooPrintable.h:33
RooAbsPdf::_rawValue
Double_t _rawValue
Definition: RooAbsPdf.h:319
Option_t
const typedef char Option_t
Definition: RtypesCore.h:66
RooAbsPdf::CanNotBeExtended
@ CanNotBeExtended
Definition: RooAbsPdf.h:229
RooAbsPdf::getNorm
Double_t getNorm(const RooArgSet &nset) const
Get normalisation term needed to normalise the raw values returned by getVal().
Definition: RooAbsPdf.h:208
RooCustomizer.h
RooNumCdf.h
RooAbsPdf::GenSpec::~GenSpec
virtual ~GenSpec()
Definition: RooAbsPdf.cxx:3594
RooDerivative.h
RooAbsPdf::getValBatch
RooSpan< const double > getValBatch(std::size_t begin, std::size_t batchSize, const RooArgSet *normSet=nullptr) const final
Compute batch of values for given range, and normalise by integrating over the observables in nset.
Definition: RooAbsPdf.cxx:345
xmin
float xmin
Definition: THbookFile.cxx:95
RooAbsPdf::paramOn
virtual RooPlot * paramOn(RooPlot *frame, 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())
Add a box with parameter values (and errors) to the specified frame.
Definition: RooAbsPdf.cxx:3152
RooAbsPdf.h
BatchHelpers::BatchData::markDirty
void markDirty()
Mark all batches dirty. This will trigger recomputations.
Definition: BatchData.h:57
RooCachedReal
Definition: RooCachedReal.h:20
RooAbsGenContext::isValid
Bool_t isValid() const
Definition: RooAbsGenContext.h:34
TMath::IsNaN
Bool_t IsNaN(Double_t x)
Definition: TMath.h:881
RooAbsReal::integralNameSuffix
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:808
RooAbsArg::isValueDirty
Bool_t isValueDirty() const
Definition: RooAbsArg.h:429
RooAbsArg::_operMode
OperMode _operMode
Mark batches as dirty (only meaningful for RooAbsReal).
Definition: RooAbsArg.h:663
RooDataHist::sumEntries
virtual Double_t sumEntries() const
Definition: RooDataHist.cxx:1703
TNamed
Definition: TNamed.h:29
RooAbsPdf::prepareMultiGen
GenSpec * prepareMultiGen(const RooArgSet &whatVars, 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())
Prepare GenSpec configuration object for efficient generation of multiple datasets from identical spe...
Definition: RooAbsPdf.cxx:2177
RooFit::Generation
@ Generation
Definition: RooGlobalFunc.h:67
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TString::Append
TString & Append(const char *cs)
Definition: TString.h:564
RooBinnedGenContext
Definition: RooBinnedGenContext.h:30
RooAbsPdf::analyticalIntegralWN
Double_t analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=0) const
Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further informatio...
Definition: RooAbsPdf.cxx:408
RooAbsArg::clearValueAndShapeDirty
void clearValueAndShapeDirty() const
Definition: RooAbsArg.h:549
RooRandom.h
RooFit::Fitting
@ Fitting
Definition: RooGlobalFunc.h:67
RooAbsPdf::createNLL
virtual RooAbsReal * createNLL(RooAbsData &data, const RooLinkedList &cmdList)
Construct representation of -log(L) of PDFwith given dataset.
Definition: RooAbsPdf.cxx:917
RooAbsReal::derivative
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.
Definition: RooAbsReal.cxx:4252
RooAbsData::get
virtual const RooArgSet * get() const
Definition: RooAbsData.h:89
RooAbsReal::getTitle
TString getTitle(Bool_t appendUnit=kFALSE) const
Return this variable's title string.
Definition: RooAbsReal.cxx:253
RooAbsPdf::getGeneratorConfig
const RooNumGenConfig * getGeneratorConfig() const
Return the numeric MC generator configuration used for this object.
Definition: RooAbsPdf.cxx:3555
RooAbsCollection::selectCommon
RooAbsCollection * selectCommon(const RooAbsCollection &refColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
Definition: RooAbsCollection.cxx:700
RooFit::Plotting
@ Plotting
Definition: RooGlobalFunc.h:67
RooNLLVar
Definition: RooNLLVar.h:27
RooVDTHeaders.h
RooLinkedList
Definition: RooLinkedList.h:35
RooPlot.h
RooAbsCollection::createIterator
TIterator * createIterator(Bool_t dir=kIterForward) const
TIterator-style iteration over contained elements.
Definition: RooAbsCollection.h:118
RooAbsReal::evaluate
virtual Double_t evaluate() const =0
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
RooAbsPdf::_normRangeOverride
static TString _normRangeOverride
Definition: RooAbsPdf.h:355
RooAbsReal::fillDataHist
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.
Definition: RooAbsReal.cxx:1229
RooAbsReal::chi2FitDriver
RooFitResult * chi2FitDriver(RooAbsReal &fcn, RooLinkedList &cmdList)
Internal driver function for chi2 fits.
Definition: RooAbsReal.cxx:4609
RooWorkspace::defineSetInternal
Bool_t defineSetInternal(const char *name, const RooArgSet &aset)
Definition: RooWorkspace.cxx:891
RooAbsReal::PlotOpt::stype
ScaleType stype
Definition: RooAbsReal.h:471
RooAbsReal::createIntRI
RooAbsReal * createIntRI(const RooArgSet &iset, const RooArgSet &nset=RooArgSet())
Utility function for createRunningIntegral.
Definition: RooAbsReal.cxx:4082
RooAbsPdf::CacheElem::~CacheElem
virtual ~CacheElem()
Destructor of normalization cache element.
Definition: RooAbsPdf.cxx:3344
RooAbsArg::RooProjectedPdf
friend class RooProjectedPdf
Definition: RooAbsArg.h:586
RooPrintable::kArgs
@ kArgs
Definition: RooPrintable.h:33
RooRealProxy.h
RooAddition
Definition: RooAddition.h:27
RooPlot
Definition: RooPlot.h:44
RooAbsArg::RooArgSet
friend class RooArgSet
Definition: RooAbsArg.h:579
RooAbsGenContext
Definition: RooAbsGenContext.h:26
RooAbsArg::setProxyNormSet
void setProxyNormSet(const RooArgSet *nset)
Forward a change in the cached normalization argset to all the registered proxies.
Definition: RooAbsArg.cxx:1254
RooNumGenConfig::defaultConfig
static RooNumGenConfig & defaultConfig()
Return reference to instance of default numeric integrator configuration object.
Definition: RooNumGenConfig.cxx:48
RooAbsPdf::getAllConstraints
virtual RooArgSet * getAllConstraints(const RooArgSet &observables, RooArgSet &constrainedParams, Bool_t stripDisconnected=kTRUE) const
This helper function finds and collects all constraints terms of all component p.d....
Definition: RooAbsPdf.cxx:3495
RooAbsCollection::add
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
Definition: RooAbsCollection.cxx:437
RooAddition.h
RooGenContext.h
RooAbsReal::getIntegratorConfig
const RooNumIntConfig * getIntegratorConfig() const
Return the numeric integration configuration used for this object.
Definition: RooAbsReal.cxx:3568
RooAbsArg::getStringAttribute
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
Definition: RooAbsArg.cxx:304
RooAbsData::numEntries
virtual Int_t numEntries() const
Definition: RooAbsData.cxx:307
RooCategory.h
RooLinkedList::Add
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:62
RooPrintable::kValue
@ kValue
Definition: RooPrintable.h:33
sqrt
double sqrt(double)
RooAbsReal::_value
Double_t _value
Definition: RooAbsReal.h:450
RooAbsReal::enableOffsetting
virtual void enableOffsetting(Bool_t)
Definition: RooAbsReal.h:343
RooAbsArg::constOptimizeTestStatistic
virtual void constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt=kTRUE)
Interface function signaling a request to perform constant term optimization.
Definition: RooAbsArg.cxx:1707
oocoutW
#define oocoutW(o, a)
Definition: RooMsgService.h:47
RooAbsReal::plotOnCompSelect
void plotOnCompSelect(RooArgSet *selNodes) const
Helper function for plotting of composite p.d.fs.
Definition: RooAbsReal.cxx:1550
RooRealVar.h
RooDataHist::SetName
void SetName(const char *name)
Change the name of the RooDataHist.
Definition: RooDataHist.cxx:1866
RooAbsPdf::logBatchComputationErrors
void logBatchComputationErrors(RooSpan< const double > &outputs, std::size_t begin) const
Scan through outputs and fix+log all nans and negative values.
Definition: RooAbsPdf.cxx:717
RooAbsPdf::CacheElem::operModeHook
void operModeHook(RooAbsArg::OperMode)
Dummy implementation.
Definition: RooAbsPdf.cxx:3333
TRandom::Integer
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition: TRandom.cxx:349
RooFitResult.h
TIterator::Next
virtual TObject * Next()=0
RooAbsReal::_batchData
BatchHelpers::BatchData _batchData
Definition: RooAbsReal.h:451
RooAbsCachedReal::setInterpolationOrder
void setInterpolationOrder(Int_t order)
Set interpolation order of RooHistFunct representing cache histogram.
Definition: RooAbsCachedReal.cxx:291
ROOT::Math::CholeskyDecompGenDim
class to compute the Cholesky decomposition of a matrix
Definition: CholeskyDecomp.h:310
RooAbsReal::plotOn
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.
Definition: RooAbsReal.cxx:1714
ymin
float ymin
Definition: THbookFile.cxx:95
RooGlobalFunc.h
RooHelpers::tokenise
std::vector< std::string > tokenise(const std::string &str, const std::string &delims, bool returnEmptyToken=true)
Tokenise the string by splitting at the characters in delims.
Definition: RooHelpers.cxx:74
RooAbsArg::Activate
@ Activate
Definition: RooAbsArg.h:392
TIterator::Reset
virtual void Reset()=0
RooAbsReal::Raw
@ Raw
Definition: RooAbsReal.h:253
RooFit::SupNormSet
RooCmdArg SupNormSet(const RooArgSet &nset)
Definition: RooGlobalFunc.cxx:327
RooAbsPdf::printValue
virtual void printValue(std::ostream &os) const
Print value of p.d.f, also print normalization integral that was last used, if any.
Definition: RooAbsPdf.cxx:1962
BatchHelpers::BatchData::setStatus
bool setStatus(std::size_t begin, std::size_t size, Status_t stat, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified)
Set the status of a batch with the given properties.
Definition: BatchData.cxx:70
RooFit::Tracing
@ Tracing
Definition: RooGlobalFunc.h:68
RooAbsPdf::_negCount
Int_t _negCount
Definition: RooAbsPdf.h:348
RooNameSet
Definition: RooNameSet.h:24
RooAbsArg::OperMode
OperMode
Definition: RooAbsArg.h:491
RooAbsRealLValue::hasRange
virtual Bool_t hasRange(const char *name) const
Check if variable has a binning with given name.
Definition: RooAbsRealLValue.h:96
RooAbsPdf::_selectComp
Bool_t _selectComp
Definition: RooAbsPdf.h:350
Double_t
double Double_t
Definition: RtypesCore.h:59
RooAbsArg::RooDataSet
friend class RooDataSet
Definition: RooAbsArg.h:627
RooNumGenConfig
Definition: RooNumGenConfig.h:25
RooPlot::getNormVars
const RooArgSet * getNormVars() const
Definition: RooPlot.h:148
RooAbsArg::getObservables
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Return the observables of this pdf given a set of observables.
Definition: RooAbsArg.h:294
RooAbsArg::addOwnedComponents
Bool_t addOwnedComponents(const RooArgSet &comps)
Take ownership of the contents of 'comps'.
Definition: RooAbsArg.cxx:2109
RooAbsPdf::createProjection
virtual RooAbsPdf * createProjection(const RooArgSet &iset)
Return a p.d.f that represent a projection of this p.d.f integrated over given observables.
Definition: RooAbsPdf.cxx:3362
RooAbsReal::evaluateBatch
virtual RooSpan< double > evaluateBatch(std::size_t begin, std::size_t maxSize) const
Evaluate function for a batch of input data points.
Definition: RooAbsReal.cxx:4872
RooDataHist::numEntries
virtual Int_t numEntries() const
Return the number of bins.
Definition: RooDataHist.cxx:1694
RooMinimizer.h
RooAbsPdf::_norm
RooAbsReal * _norm
Definition: RooAbsPdf.h:320
TRandom::Poisson
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:391
RooAbsPdf::_specGeneratorConfig
RooNumGenConfig * _specGeneratorConfig
Definition: RooAbsPdf.h:352
RooInt.h
RooAbsPdf::generate
RooDataSet * generate(const RooArgSet &whatVars, Int_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none())
See RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,...
Definition: RooAbsPdf.h:55
TObject
Definition: TObject.h:37
RooNameSet::content
const char * content() const
Definition: RooNameSet.h:50
RooNumGenConfig.h
RooNameReg::str
static const char * str(const TNamed *ptr)
Return C++ string corresponding to given TNamed pointer.
Definition: RooNameReg.cxx:103
RooAbsPdf::_verboseEval
static Int_t _verboseEval
Definition: RooAbsPdf.h:314
RooFit::NormRange
RooCmdArg NormRange(const char *rangeNameList)
Definition: RooGlobalFunc.cxx:54
RooFit::Range
RooCmdArg Range(const char *rangeName, Bool_t adjustNorm=kTRUE)
Definition: RooGlobalFunc.cxx:52
name
char name[80]
Definition: TGX11.cxx:110
RooMinuit
Definition: RooMinuit.h:39
RooAbsArg::dependsOn
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:732
RooPrintable::kTitle
@ kTitle
Definition: RooPrintable.h:33
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:52
RooNameSet::setNameList
void setNameList(const char *givenList)
Definition: RooNameSet.cxx:142
RooXYChi2Var
Definition: RooXYChi2Var.h:29
RooAbsReal::printMultiline
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Structure printing.
Definition: RooAbsReal.cxx:476
RooPrintable::printStream
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,...
Definition: RooPrintable.cxx:75
genreflex::verbose
bool verbose
Definition: rootcling_impl.cxx:133
RooPrintable::kSingleLine
@ kSingleLine
Definition: RooPrintable.h:34
RooFit::Caching
@ Caching
Definition: RooGlobalFunc.h:68
RooDataSet
Definition: RooDataSet.h:33
BatchHelpers::BatchData::kgetVal
@ kgetVal
Definition: BatchData.h:37
RooAbsPdf::generateBinned
virtual RooDataHist * generateBinned(const RooArgSet &whatVars, Double_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none()) const
As RooAbsPdf::generateBinned(const RooArgSet&, const RooCmdArg&,const RooCmdArg&, const RooCmdArg&,...
Definition: RooAbsPdf.h:104
TPaveText
Definition: TPaveText.h:21
RooAbsArg
Definition: RooAbsArg.h:73
TMatrixTSym::Similarity
TMatrixTSym< Element > & Similarity(const TMatrixT< Element > &n)
RooRealIntegral.h
RooRandom::randomGenerator
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition: RooRandom.cxx:53
RooAbsGenContext::setExpectedData
virtual void setExpectedData(Bool_t)
Definition: RooAbsGenContext.h:66
RooAbsCollection::Print
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
Definition: RooAbsCollection.h:199
RooAbsPdf
Definition: RooAbsPdf.h:40
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:53
RooAbsPdf::selfNormalized
virtual Bool_t selfNormalized() const
Shows if a PDF is self-normalized, which means that no attempt is made to add a normalization term.
Definition: RooAbsPdf.h:224
RooAbsArg::getVariables
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:1911
RooAbsReal::Relative
@ Relative
Definition: RooAbsReal.h:253
RooAbsArg::findServer
RooAbsArg * findServer(const char *name) const
Return server of this with name name. Returns nullptr if not found.
Definition: RooAbsArg.h:203
BatchHelpers::BatchData::getBatch
RooSpan< const double > getBatch(std::size_t begin, std::size_t maxSize, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified) const
Retrieve an existing batch.
Definition: BatchData.cxx:92
RooRealVar::setBins
void setBins(Int_t nBins, const char *name=0)
Create a uniform binning under name 'name' for this variable.
Definition: RooRealVar.cxx:383
RooAbsArg::_myws
RooWorkspace * _myws
Prevent 'AlwaysDirty' mode for this node.
Definition: RooAbsArg.h:681
RooAbsPdf::syncNormalization
virtual Bool_t syncNormalization(const RooArgSet *dset, Bool_t adjustProxies=kTRUE) const
Verify that the normalization integral cached with this PDF is valid for given set of normalization o...
Definition: RooAbsPdf.cxx:522
RooConstraintSum
Definition: RooConstraintSum.h:27
RooAbsReal::PrintErrors
@ PrintErrors
Definition: RooAbsReal.h:298
launcher.spec
spec
Definition: launcher.py:29
TMatrixD.h
RooAbsCategoryLValue
Definition: RooAbsCategoryLValue.h:25
RooAbsPdf::getLogVal
virtual Double_t getLogVal(const RooArgSet *set=0) const
Return the log of the current value with given normalization An error message is printed if the argum...
Definition: RooAbsPdf.cxx:659
Class
void Class()
Definition: Class.C:29
RooAbsArg::_allBatchesDirty
bool _allBatchesDirty
Definition: RooAbsArg.h:661
TString::ToLower
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
RooRealVar
Definition: RooRealVar.h:35
RooFit::Eval
@ Eval
Definition: RooGlobalFunc.h:68
BatchHelpers::BatchData::status
Status_t status(std::size_t begin, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified) const
Return the status of the batch starting at begin.
Definition: BatchData.cxx:42
cxcoutI
#define cxcoutI(a)
Definition: RooMsgService.h:85
RooAbsCollection::selectByAttrib
RooAbsCollection * selectByAttrib(const char *name, Bool_t value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
Definition: RooAbsCollection.cxx:677
RooMinimizer
Definition: RooMinimizer.h:40
RooNameReg.h
RooAbsPdf::resetErrorCounters
virtual void resetErrorCounters(Int_t resetValue=10)
Reset error counter to given value, limiting the number of future error messages for this pdf to 'res...
Definition: RooAbsPdf.cxx:621
RooAbsArg::isConstant
Bool_t isConstant() const
Check if the "Constant" attribute is set.
Definition: RooAbsArg.h:360
RooPlot::getPlotVar
RooAbsRealLValue * getPlotVar() const
Definition: RooPlot.h:139
RooArgProxy.h
RooAbsPdf::randomizeProtoOrder
Int_t * randomizeProtoOrder(Int_t nProto, Int_t nGen, Bool_t resample=kFALSE) const
Return lookup table with randomized access order for prototype events, given nProto prototype data ev...
Definition: RooAbsPdf.cxx:2369
BatchHelpers::BatchData::makeWritableBatchUnInit
RooSpan< double > makeWritableBatchUnInit(std::size_t begin, std::size_t batchSize, const RooArgSet *const normSet=nullptr, Tag_t ownerTag=kUnspecified)
Make a batch and return a span pointing to the pdf-local memory.
Definition: BatchData.cxx:130
RooAbsPdf::canBeExtended
Bool_t canBeExtended() const
Definition: RooAbsPdf.h:236
RooAbsCollection::getSize
Int_t getSize() const
Definition: RooAbsCollection.h:171
RooSpan
A simple container to hold a batch of data values.
Definition: RooSpan.h:33
TMath.h
RooArgSet
Definition: RooArgSet.h:28
RooFitResult::covarianceMatrix
const TMatrixDSym & covarianceMatrix() const
Return covariance matrix.
Definition: RooFitResult.cxx:1108
cxcoutD
#define cxcoutD(a)
Definition: RooMsgService.h:81
BatchHelpers::BatchData::kDirty
@ kDirty
Definition: BatchData.h:36
RooAbsReal::RelativeExpected
@ RelativeExpected
Definition: RooAbsReal.h:253
int
RooAbsCollection::contentsString
std::string contentsString() const
Return comma separated list of contained object names as STL string.
Definition: RooAbsCollection.cxx:854
RooAbsArg::getAttribute
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:282
RooAbsPdf::expectedEvents
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
RooAbsPdf::fitTo
virtual RooFitResult * fitTo(RooAbsData &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())
Fit PDF to given dataset.
Definition: RooAbsPdf.cxx:1261