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