Logo ROOT  
Reference Guide
RooRealSumPdf.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 RooRealSumPdf
19  \ingroup Roofitcore
20 
21 
22 The class RooRealSumPdf implements a PDF constructed from a sum of functions:
23 \f[
24  \mathrm{PDF}(x) = \frac{ \sum_{i=1}^{n-1} \mathrm{coef}_i * \mathrm{func}_i(x) + \left[ 1 - \sum_{i=1}^{n-1} \mathrm{coef}_i \right] * \mathrm{func}_n(x) }
25  {\sum_{i=1}^{n-1} \mathrm{coef}_i * \int \mathrm{func}_i(x)dx + \left[ 1 - \sum_{i=1}^{n-1} \mathrm{coef}_i \right] * \int \mathrm{func}_n(x) dx }
26 \f]
27 
28 where \f$\mathrm{coef}_i\f$ and \f$\mathrm{func}_i\f$ are RooAbsReal objects, and \f$ x \f$ is the collection of dependents.
29 In the present version \f$\mathrm{coef}_i\f$ may not depend on \f$ x \f$, but this limitation could be removed should the need arise.
30 
31 If the number of coefficients is one less than the number of functions, the PDF is assumed to be normalised. Due to this additional constraint,
32 \f$\mathrm{coef}_n\f$ is computed from the other coefficients.
33 
34 ### Extending the PDF
35 If an \f$ n^\mathrm{th} \f$ coefficient is provided, the PDF **can** be used as an extended PDF, *i.e.* the total number of events will be measured in addition
36 to the fractions of the various functions. **This requires setting the last argument of the constructor to `true`.**
37 \note For the RooAddPdf, the extension happens automatically.
38 
39 ### Difference to RooAddPdf / RooRealSumFunc
40 - RooAddPdf is a PDF of PDFs, *i.e.* its components need to be normalised and non-negative.
41 - RooRealSumPdf is a PDF of functions, *i.e.*, its components can be negative, but their sum cannot be. The normalisation
42  is computed automatically, unless the PDF is extended (see above).
43 - RooRealSumFunc is a sum of functions. It is neither normalised, nor need it be positive.
44 
45 */
46 
47 #include "RooRealSumPdf.h"
48 
49 #include "RooRealIntegral.h"
50 #include "RooRealProxy.h"
51 #include "RooRealVar.h"
52 #include "RooMsgService.h"
53 #include "RooNaNPacker.h"
54 #include "RunContext.h"
55 
56 #include <TError.h>
57 
58 #include <algorithm>
59 #include <memory>
60 #include <stdexcept>
61 
62 using namespace std;
63 
65 
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 /// Default constructor
70 /// coverity[UNINIT_CTOR]
71 
73 {
74  _extended = kFALSE ;
75  _doFloor = kFALSE ;
76 }
77 
78 
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 /// Constructor with name and title
82 
83 RooRealSumPdf::RooRealSumPdf(const char *name, const char *title) :
84  RooAbsPdf(name,title),
85  _normIntMgr(this,10),
86  _funcList("!funcList","List of functions",this),
87  _coefList("!coefList","List of coefficients",this),
88  _extended(kFALSE),
89  _doFloor(kFALSE)
90 {
91 
92 }
93 
94 
95 
96 ////////////////////////////////////////////////////////////////////////////////
97 /// Construct p.d.f consisting of \f$ \mathrm{coef}_1 * \mathrm{func}_1 + (1-\mathrm{coef}_1) * \mathrm{func}_2 \f$.
98 /// The input coefficients and functions are allowed to be negative
99 /// but the resulting sum is not, which is enforced at runtime.
100 
101 RooRealSumPdf::RooRealSumPdf(const char *name, const char *title,
102  RooAbsReal& func1, RooAbsReal& func2, RooAbsReal& coef1) :
103  RooAbsPdf(name,title),
104  _normIntMgr(this,10),
105  _funcList("!funcList","List of functions",this),
106  _coefList("!coefList","List of coefficients",this),
107  _extended(kFALSE),
108  _doFloor(kFALSE)
109 {
110  // Special constructor with two functions and one coefficient
111 
112  _funcList.add(func1) ;
113  _funcList.add(func2) ;
114  _coefList.add(coef1) ;
115 
116 }
117 
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// Constructor for a PDF from a list of functions and coefficients.
121 /// It implements
122 /// \f[
123 /// \sum_i \mathrm{coef}_i \cdot \mathrm{func}_i,
124 /// \f]
125 /// if \f$ N_\mathrm{coef} = N_\mathrm{func} \f$. With `extended=true`, the coefficients can take any values. With `extended=false`,
126 /// there is the danger of getting a degenerate minimisation problem because a PDF has to be normalised, which needs one degree
127 /// of freedom less.
128 ///
129 /// A plain (normalised) PDF can therefore be implemented with one less coefficient. RooFit then computes
130 /// \f[
131 /// \sum_i^{N-1} \mathrm{coef}_i \cdot \mathrm{func}_i + (1 - \sum_i \mathrm{coef}_i ) \cdot \mathrm{func}_N,
132 /// \f]
133 /// if \f$ N_\mathrm{coef} = N_\mathrm{func} - 1 \f$.
134 ///
135 /// All coefficients and functions are allowed to be negative
136 /// but the sum (*i.e.* the PDF) is not, which is enforced at runtime.
137 ///
138 /// \param name Name of the PDF
139 /// \param title Title (for plotting)
140 /// \param inFuncList List of functions to sum
141 /// \param inCoefList List of coefficients
142 /// \param extended Interpret as extended PDF (requires equal number of functions and coefficients)
143 
144 RooRealSumPdf::RooRealSumPdf(const char *name, const char *title,
145  const RooArgList& inFuncList, const RooArgList& inCoefList, Bool_t extended) :
146  RooAbsPdf(name,title),
147  _normIntMgr(this,10),
148  _funcList("!funcList","List of functions",this),
149  _coefList("!coefList","List of coefficients",this),
150  _extended(extended),
151  _doFloor(kFALSE)
152 {
153  if (!(inFuncList.getSize()==inCoefList.getSize()+1 || inFuncList.getSize()==inCoefList.getSize())) {
154  coutE(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName()
155  << ") number of pdfs and coefficients inconsistent, must have Nfunc=Ncoef or Nfunc=Ncoef+1" << endl ;
156  throw std::invalid_argument("RooRealSumPdf: Number of PDFs and coefficients is inconsistent.");
157  }
158 
159  // Constructor with N functions and N or N-1 coefs
160  for (unsigned int i = 0; i < inCoefList.size(); ++i) {
161  const auto& func = inFuncList[i];
162  const auto& coef = inCoefList[i];
163 
164  if (!dynamic_cast<const RooAbsReal*>(&coef)) {
165  coutW(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") coefficient " << coef.GetName() << " is not of type RooAbsReal, ignored" << endl ;
166  continue ;
167  }
168  if (!dynamic_cast<const RooAbsReal*>(&func)) {
169  coutW(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") func " << func.GetName() << " is not of type RooAbsReal, ignored" << endl ;
170  continue ;
171  }
172  _funcList.add(func) ;
173  _coefList.add(coef) ;
174  }
175 
176  if (inFuncList.size() == inCoefList.size() + 1) {
177  const auto& func = inFuncList[inFuncList.size()-1];
178  if (!dynamic_cast<const RooAbsReal*>(&func)) {
179  coutE(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") last func " << func.GetName() << " is not of type RooAbsReal, fatal error" << endl ;
180  throw std::invalid_argument("RooRealSumPdf: Function passed as is not of type RooAbsReal.");
181  }
182  _funcList.add(func);
183  }
184 
185 }
186 
187 
188 
189 
190 ////////////////////////////////////////////////////////////////////////////////
191 /// Copy constructor
192 
193 RooRealSumPdf::RooRealSumPdf(const RooRealSumPdf& other, const char* name) :
194  RooAbsPdf(other,name),
195  _normIntMgr(other._normIntMgr,this),
196  _funcList("!funcList",this,other._funcList),
197  _coefList("!coefList",this,other._coefList),
198  _extended(other._extended),
199  _doFloor(other._doFloor)
200 {
201 
202 }
203 
204 
205 
206 ////////////////////////////////////////////////////////////////////////////////
207 /// Destructor
208 
210 {
211 
212 }
213 
214 
215 
216 
217 
218 ////////////////////////////////////////////////////////////////////////////////
219 
221 {
223 }
224 
225 
226 
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 /// Calculate the current value
230 
232 {
233  // Do running sum of coef/func pairs, calculate lastCoef.
234  double value = 0;
235  double sumCoeff = 0.;
236  for (unsigned int i = 0; i < _funcList.size(); ++i) {
237  const auto func = static_cast<RooAbsReal*>(&_funcList[i]);
238  const auto coef = static_cast<RooAbsReal*>(i < _coefList.size() ? &_coefList[i] : nullptr);
239  const double coefVal = coef != nullptr ? coef->getVal() : (1. - sumCoeff);
240 
241  // Warn about degeneration of last coefficient
242  if (coef == nullptr && (coefVal < 0 || coefVal > 1.)) {
243  if (!_haveWarned) {
244  coutW(Eval) << "RooRealSumPdf::evaluate(" << GetName()
245  << ") WARNING: sum of FUNC coefficients not in range [0-1], value="
246  << sumCoeff << ". This means that the PDF is not properly normalised. If the PDF was meant to be extended, provide as many coefficients as functions." << endl ;
247  _haveWarned = true;
248  }
249  // Signal that we are in an undefined region:
250  value = RooNaNPacker::packFloatIntoNaN(100.f * (coefVal < 0. ? -coefVal : coefVal - 1.));
251  }
252 
253  if (func->isSelectedComp()) {
254  value += func->getVal() * coefVal;
255  }
256 
257  sumCoeff += coefVal;
258  }
259 
260  // Introduce floor if so requested
261  if (value<0 && (_doFloor || _doFloorGlobal)) {
262  value = 0 ;
263  }
264 
265  return value ;
266 }
267 
268 
269 ////////////////////////////////////////////////////////////////////////////////
270 /// Calculate the value for all values of the observable in `evalData`.
272  // Do running sum of coef/func pairs, calculate lastCoef.
273  RooSpan<double> values;
274  double sumCoeff = 0.;
275  for (unsigned int i = 0; i < _funcList.size(); ++i) {
276  const auto func = static_cast<RooAbsReal*>(&_funcList[i]);
277  const auto coef = static_cast<RooAbsReal*>(i < _coefList.size() ? &_coefList[i] : nullptr);
278  const double coefVal = coef != nullptr ? coef->getVal() : (1. - sumCoeff);
279 
280  if (func->isSelectedComp()) {
281  auto funcValues = func->getValues(evalData, nullptr); // No normSet here, because we are summing functions!
282  if (values.empty() || (values.size() == 1 && funcValues.size() > 1)) {
283  const double init = values.empty() ? 0. : values[0];
284  values = evalData.makeBatch(this, funcValues.size());
285  for (unsigned int j = 0; j < values.size(); ++j) {
286  values[j] = init + funcValues[j] * coefVal;
287  }
288  } else {
289  assert(values.size() == funcValues.size());
290  for (unsigned int j = 0; j < values.size(); ++j) {
291  values[j] += funcValues[j] * coefVal;
292  }
293  }
294  }
295 
296  // Warn about degeneration of last coefficient
297  if (coef == nullptr && (coefVal < 0 || coefVal > 1.)) {
298  if (!_haveWarned) {
299  coutW(Eval) << "RooRealSumPdf::evaluateSpan(" << GetName()
300  << ") WARNING: sum of FUNC coefficients not in range [0-1], value="
301  << sumCoeff << ". This means that the PDF is not properly normalised. If the PDF was meant to be extended, provide as many coefficients as functions." << endl ;
302  _haveWarned = true;
303  }
304  // Signal that we are in an undefined region by handing back one NaN.
305  values[0] = RooNaNPacker::packFloatIntoNaN(100.f * (coefVal < 0. ? -coefVal : coefVal - 1.));
306  }
307 
308  sumCoeff += coefVal;
309  }
310 
311  // Introduce floor if so requested
312  if (_doFloor || _doFloorGlobal) {
313  for (unsigned int j = 0; j < values.size(); ++j) {
314  values[j] += std::max(0., values[j]);
315  }
316  }
317 
318  return values;
319 }
320 
321 
322 ////////////////////////////////////////////////////////////////////////////////
323 /// Check if FUNC is valid for given normalization set.
324 /// Coefficient and FUNC must be non-overlapping, but func-coefficient
325 /// pairs may overlap each other.
326 ///
327 /// In the present implementation, coefficients may not be observables or derive
328 /// from observables.
329 
331 {
332  Bool_t ret(kFALSE) ;
333 
334  for (unsigned int i=0; i < _coefList.size(); ++i) {
335  const auto& coef = _coefList[i];
336  const auto& func = _funcList[i];
337 
338  if (func.observableOverlaps(nset, coef)) {
339  coutE(InputArguments) << "RooRealSumPdf::checkObservables(" << GetName() << "): ERROR: coefficient " << coef.GetName()
340  << " and FUNC " << func.GetName() << " have one or more observables in common" << endl ;
341  ret = kTRUE ;
342  }
343  if (coef.dependsOn(*nset)) {
344  coutE(InputArguments) << "RooRealPdf::checkObservables(" << GetName() << "): ERROR coefficient " << coef.GetName()
345  << " depends on one or more of the following observables" ; nset->Print("1") ;
346  ret = kTRUE ;
347  }
348  }
349 
350  return ret ;
351 }
352 
353 
354 
355 
356 ////////////////////////////////////////////////////////////////////////////////
357 /// Advertise that all integrals can be handled internally.
358 
360  const RooArgSet* normSet2, const char* rangeName) const
361 {
362  // Handle trivial no-integration scenario
363  if (allVars.getSize()==0) return 0 ;
364  if (_forceNumInt) return 0 ;
365 
366  // Select subset of allVars that are actual dependents
367  analVars.add(allVars) ;
368  RooArgSet* normSet = normSet2 ? getObservables(normSet2) : 0 ;
369 
370 
371  // Check if this configuration was created before
372  Int_t sterileIdx(-1) ;
373  CacheElem* cache = (CacheElem*) _normIntMgr.getObj(normSet,&analVars,&sterileIdx,RooNameReg::ptr(rangeName)) ;
374  if (cache) {
375  //cout << "RooRealSumPdf("<<this<<")::getAnalyticalIntegralWN:"<<GetName()<<"("<<allVars<<","<<analVars<<","<<(normSet2?*normSet2:RooArgSet())<<","<<(rangeName?rangeName:"<none>") << " -> " << _normIntMgr.lastIndex()+1 << " (cached)" << endl;
376  return _normIntMgr.lastIndex()+1 ;
377  }
378 
379  // Create new cache element
380  cache = new CacheElem ;
381 
382  // Make list of function projection and normalization integrals
383  for (const auto elm : _funcList) {
384  const auto func = static_cast<RooAbsReal*>(elm);
385 
386  RooAbsReal* funcInt = func->createIntegral(analVars,rangeName) ;
387  if(funcInt->InheritsFrom(RooRealIntegral::Class())) ((RooRealIntegral*)funcInt)->setAllowComponentSelection(true);
388  cache->_funcIntList.addOwned(*funcInt) ;
389  if (normSet && normSet->getSize()>0) {
390  RooAbsReal* funcNorm = func->createIntegral(*normSet) ;
391  cache->_funcNormList.addOwned(*funcNorm) ;
392  }
393  }
394 
395  // Store cache element
396  Int_t code = _normIntMgr.setObj(normSet,&analVars,(RooAbsCacheElement*)cache,RooNameReg::ptr(rangeName)) ;
397 
398  if (normSet) {
399  delete normSet ;
400  }
401 
402  //cout << "RooRealSumPdf("<<this<<")::getAnalyticalIntegralWN:"<<GetName()<<"("<<allVars<<","<<analVars<<","<<(normSet2?*normSet2:RooArgSet())<<","<<(rangeName?rangeName:"<none>") << " -> " << code+1 << endl;
403  return code+1 ;
404 }
405 
406 
407 
408 
409 ////////////////////////////////////////////////////////////////////////////////
410 /// Implement analytical integrations by deferring integration of component
411 /// functions to integrators of components.
412 
413 Double_t RooRealSumPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet2, const char* rangeName) const
414 {
415  // Handle trivial passthrough scenario
416  if (code==0) return getVal(normSet2) ;
417 
418 
419  // WVE needs adaptation for rangeName feature
420  CacheElem* cache = (CacheElem*) _normIntMgr.getObjByIndex(code-1) ;
421  if (cache==0) { // revive the (sterilized) cache
422  //cout << "RooRealSumPdf("<<this<<")::analyticalIntegralWN:"<<GetName()<<"("<<code<<","<<(normSet2?*normSet2:RooArgSet())<<","<<(rangeName?rangeName:"<none>") << ": reviving cache "<< endl;
423  std::unique_ptr<RooArgSet> vars( getParameters(RooArgSet()) );
424  RooArgSet iset = _normIntMgr.selectFromSet2(*vars, code-1);
425  RooArgSet nset = _normIntMgr.selectFromSet1(*vars, code-1);
426  RooArgSet dummy;
427  Int_t code2 = getAnalyticalIntegralWN(iset,dummy,&nset,rangeName);
428  R__ASSERT(code==code2); // must have revived the right (sterilized) slot...
429  cache = (CacheElem*) _normIntMgr.getObjByIndex(code-1) ;
430  R__ASSERT(cache!=0);
431  }
432 
433  Double_t value(0) ;
434 
435  // N funcs, N-1 coefficients
436  Double_t lastCoef(1) ;
437  auto funcIt = _funcList.begin();
438  auto funcIntIt = cache->_funcIntList.begin();
439  for (const auto coefArg : _coefList) {
440  assert(funcIt != _funcList.end());
441  const auto coef = static_cast<const RooAbsReal*>(coefArg);
442  const auto func = static_cast<const RooAbsReal*>(*funcIt++);
443  const auto funcInt = static_cast<RooAbsReal*>(*funcIntIt++);
444 
445  Double_t coefVal = coef->getVal(normSet2) ;
446  if (coefVal) {
447  assert(func);
448  if (normSet2 ==0 || func->isSelectedComp()) {
449  assert(funcInt);
450  value += funcInt->getVal()*coefVal ;
451  }
452  lastCoef -= coef->getVal(normSet2) ;
453  }
454  }
455 
456  if (!haveLastCoef()) {
457  // Add last func with correct coefficient
458  const auto func = static_cast<const RooAbsReal*>(*funcIt);
459  const auto funcInt = static_cast<RooAbsReal*>(*funcIntIt);
460  assert(func);
461 
462  if (normSet2 ==0 || func->isSelectedComp()) {
463  assert(funcInt);
464  value += funcInt->getVal()*lastCoef ;
465  }
466 
467  // Warn about coefficient degeneration
468  if (!_haveWarned && (lastCoef<0 || lastCoef>1)) {
469  coutW(Eval) << "RooRealSumPdf::evaluate(" << GetName()
470  << " WARNING: sum of FUNC coefficients not in range [0-1], value="
471  << 1-lastCoef << endl ;
472  }
473  }
474 
475  Double_t normVal(1) ;
476  if (normSet2 && normSet2->getSize()>0) {
477  normVal = 0 ;
478 
479  // N funcs, N-1 coefficients
480  auto funcNormIter = cache->_funcNormList.begin();
481  for (const auto coefAsArg : _coefList) {
482  auto coef = static_cast<RooAbsReal*>(coefAsArg);
483  auto funcNorm = static_cast<RooAbsReal*>(*funcNormIter++);
484 
485  Double_t coefVal = coef->getVal(normSet2);
486  if (coefVal) {
487  assert(funcNorm);
488  normVal += funcNorm->getVal()*coefVal ;
489  }
490  }
491 
492  // Add last func with correct coefficient
493  if (!haveLastCoef()) {
494  auto funcNorm = static_cast<RooAbsReal*>(*funcNormIter);
495  assert(funcNorm);
496 
497  normVal += funcNorm->getVal()*lastCoef;
498  }
499  }
500 
501  return value / normVal;
502 }
503 
504 
505 ////////////////////////////////////////////////////////////////////////////////
506 
508 {
509  Double_t n = getNorm(nset) ;
510  if (n<0) {
511  logEvalError("Expected number of events is negative") ;
512  }
513  return n ;
514 }
515 
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 
519 std::list<Double_t>* RooRealSumPdf::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
520 {
521  list<Double_t>* sumBinB = 0 ;
522  Bool_t needClean(kFALSE) ;
523 
524  // Loop over components pdf
525  for (const auto elm : _funcList) {
526  auto func = static_cast<RooAbsReal*>(elm);
527 
528  list<Double_t>* funcBinB = func->binBoundaries(obs,xlo,xhi) ;
529 
530  // Process hint
531  if (funcBinB) {
532  if (!sumBinB) {
533  // If this is the first hint, then just save it
534  sumBinB = funcBinB ;
535  } else {
536 
537  list<Double_t>* newSumBinB = new list<Double_t>(sumBinB->size()+funcBinB->size()) ;
538 
539  // Merge hints into temporary array
540  merge(funcBinB->begin(),funcBinB->end(),sumBinB->begin(),sumBinB->end(),newSumBinB->begin()) ;
541 
542  // Copy merged array without duplicates to new sumBinBArrau
543  delete sumBinB ;
544  delete funcBinB ;
545  sumBinB = newSumBinB ;
546  needClean = kTRUE ;
547  }
548  }
549  }
550 
551  // Remove consecutive duplicates
552  if (needClean) {
553  list<Double_t>::iterator new_end = unique(sumBinB->begin(),sumBinB->end()) ;
554  sumBinB->erase(new_end,sumBinB->end()) ;
555  }
556 
557  return sumBinB ;
558 }
559 
560 
561 
562 /// Check if all components that depend on `obs` are binned.
564 {
565  for (const auto elm : _funcList) {
566  auto func = static_cast<RooAbsReal*>(elm);
567 
568  if (func->dependsOn(obs) && !func->isBinnedDistribution(obs)) {
569  return kFALSE ;
570  }
571  }
572 
573  return kTRUE ;
574 }
575 
576 
577 
578 
579 
580 ////////////////////////////////////////////////////////////////////////////////
581 
582 std::list<Double_t>* RooRealSumPdf::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
583 {
584  list<Double_t>* sumHint = 0 ;
585  Bool_t needClean(kFALSE) ;
586 
587  // Loop over components pdf
588  for (const auto elm : _funcList) {
589  auto func = static_cast<RooAbsReal*>(elm);
590 
591  list<Double_t>* funcHint = func->plotSamplingHint(obs,xlo,xhi) ;
592 
593  // Process hint
594  if (funcHint) {
595  if (!sumHint) {
596 
597  // If this is the first hint, then just save it
598  sumHint = funcHint ;
599 
600  } else {
601 
602  list<Double_t>* newSumHint = new list<Double_t>(sumHint->size()+funcHint->size()) ;
603 
604  // Merge hints into temporary array
605  merge(funcHint->begin(),funcHint->end(),sumHint->begin(),sumHint->end(),newSumHint->begin()) ;
606 
607  // Copy merged array without duplicates to new sumHintArrau
608  delete sumHint ;
609  sumHint = newSumHint ;
610  needClean = kTRUE ;
611  }
612  }
613  }
614 
615  // Remove consecutive duplicates
616  if (needClean) {
617  list<Double_t>::iterator new_end = unique(sumHint->begin(),sumHint->end()) ;
618  sumHint->erase(new_end,sumHint->end()) ;
619  }
620 
621  return sumHint ;
622 }
623 
624 
625 
626 
627 ////////////////////////////////////////////////////////////////////////////////
628 /// Label OK'ed components of a RooRealSumPdf with cache-and-track
629 
631 {
632  for (const auto sarg : _funcList) {
633  if (sarg->canNodeBeCached()==Always) {
634  trackNodes.add(*sarg) ;
635  //cout << "tracking node RealSumPdf component " << sarg->IsA()->GetName() << "::" << sarg->GetName() << endl ;
636  }
637  }
638 }
639 
640 
641 
642 ////////////////////////////////////////////////////////////////////////////////
643 /// Customized printing of arguments of a RooRealSumPdf to more intuitively reflect the contents of the
644 /// product operator construction
645 
646 void RooRealSumPdf::printMetaArgs(ostream& os) const
647 {
648 
649  Bool_t first(kTRUE) ;
650 
651  if (_coefList.getSize()!=0) {
652  auto funcIter = _funcList.begin();
653 
654  for (const auto coef : _coefList) {
655  if (!first) {
656  os << " + " ;
657  } else {
658  first = kFALSE ;
659  }
660  const auto func = *(funcIter++);
661  os << coef->GetName() << " * " << func->GetName();
662  }
663 
664  if (funcIter != _funcList.end()) {
665  os << " + [%] * " << (*funcIter)->GetName() ;
666  }
667  } else {
668 
669  for (const auto func : _funcList) {
670  if (!first) {
671  os << " + " ;
672  } else {
673  first = kFALSE ;
674  }
675  os << func->GetName() ;
676  }
677  }
678 
679  os << " " ;
680 }
RooCacheManager::setObj
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=0)
Definition: RooCacheManager.h:50
n
const Int_t n
Definition: legend1.C:16
RooAbsPdf::CacheElem
friend class CacheElem
Definition: RooAbsPdf.h:336
first
Definition: first.py:1
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:100
RooBatchCompute::RunContext::makeBatch
RooSpan< double > makeBatch(const RooAbsReal *owner, std::size_t size)
Create a writable batch.
Definition: RunContext.cxx:87
RooMsgService.h
RooAbsReal::plotSamplingHint
virtual std::list< Double_t > * plotSamplingHint(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi) const
Interface for returning an optional hint for initial sampling points when constructing a curve projec...
Definition: RooAbsReal.cxx:3824
RooNameReg::ptr
static const TNamed * ptr(const char *stringPtr)
Return a unique TNamed pointer for given C++ string.
Definition: RooNameReg.cxx:93
RooAbsReal::logEvalError
void logEvalError(const char *message, const char *serverValueString=0) const
Log evaluation error message.
Definition: RooAbsReal.cxx:3718
RooRealSumPdf::_doFloor
Bool_t _doFloor
Definition: RooRealSumPdf.h:87
RooFit::InputArguments
@ InputArguments
Definition: RooGlobalFunc.h:61
RooAbsArg::Always
@ Always
Definition: RooAbsArg.h:389
RooAbsArg::getParameters
RooArgSet * getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
Definition: RooAbsArg.cxx:578
RooCacheManager::getObj
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
Definition: RooCacheManager.h:45
RooNaNPacker::packFloatIntoNaN
static double packFloatIntoNaN(float payload)
Pack float into mantissa of a NaN.
Definition: RooNaNPacker.h:109
RooAbsPdf::CanBeExtended
@ CanBeExtended
Definition: RooAbsPdf.h:230
RooAbsReal::createIntegral
RooAbsReal * createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none()) const
Create an object that represents the integral of the function over one or more observables listed in ...
Definition: RooAbsReal.cxx:548
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
RooRealSumPdf::_extended
Bool_t _extended
Definition: RooRealSumPdf.h:85
coutE
#define coutE(a)
Definition: RooMsgService.h:33
RooAbsReal::binBoundaries
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi) const
Retrieve bin boundaries if this distribution is binned in obs.
Definition: RooAbsReal.cxx:3813
RooRealSumPdf::RooRealSumPdf
RooRealSumPdf()
Default constructor coverity[UNINIT_CTOR].
Definition: RooRealSumPdf.cxx:72
coutW
#define coutW(a)
Definition: RooMsgService.h:32
RooArgList
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:21
RooAbsReal::getVal
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:91
RooRealSumPdf::getAnalyticalIntegralWN
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &numVars, const RooArgSet *normSet, const char *rangeName=0) const
Advertise that all integrals can be handled internally.
Definition: RooRealSumPdf.cxx:359
RooRealSumPdf::setCacheAndTrackHints
virtual void setCacheAndTrackHints(RooArgSet &)
Label OK'ed components of a RooRealSumPdf with cache-and-track.
Definition: RooRealSumPdf.cxx:630
RooAbsReal::_forceNumInt
Bool_t _forceNumInt
Definition: RooAbsReal.h:480
RooRealSumPdf::extendMode
virtual ExtendMode extendMode() const
Returns ability of PDF to provide extended likelihood terms.
Definition: RooRealSumPdf.cxx:220
RooRealSumPdf::CacheElem
Definition: RooRealSumPdf.h:72
RooAbsReal
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:61
RooRealSumPdf::isBinnedDistribution
Bool_t isBinnedDistribution(const RooArgSet &obs) const
Check if all components that depend on obs are binned.
Definition: RooRealSumPdf.cxx:563
RooCacheManager::selectFromSet2
RooArgSet selectFromSet2(RooArgSet const &argSet, int index) const
Create RooArgSet contatining the objects that are both in the cached set 2.
Definition: RooCacheManager.h:333
RooRealSumPdf::CacheElem::_funcIntList
RooArgList _funcIntList
Definition: RooRealSumPdf.h:77
RooAbsCacheElement
RooAbsCacheElement is the abstract base class for objects to be stored in RooAbsCache cache manager o...
Definition: RooAbsCacheElement.h:26
RooRealSumPdf::evaluateSpan
RooSpan< double > evaluateSpan(RooBatchCompute::RunContext &evalData, const RooArgSet *normSet) const
Calculate the value for all values of the observable in evalData.
Definition: RooRealSumPdf.cxx:271
Bool_t
bool Bool_t
Definition: RtypesCore.h:63
TObject::InheritsFrom
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
bool
RooRealSumPdf::plotSamplingHint
virtual std::list< Double_t > * plotSamplingHint(RooAbsRealLValue &, Double_t, Double_t) const
Interface for returning an optional hint for initial sampling points when constructing a curve projec...
Definition: RooRealSumPdf.cxx:582
RooSpan::size
constexpr std::span< T >::index_type size() const noexcept
Definition: RooSpan.h:121
RooRealIntegral
RooRealIntegral performs hybrid numerical/analytical integrals of RooAbsReal objects.
Definition: RooRealIntegral.h:34
RooRealSumPdf::_normIntMgr
RooObjCacheManager _normIntMgr
Definition: RooRealSumPdf.h:80
RooAbsPdf::ExtendMode
ExtendMode
Definition: RooAbsPdf.h:230
RooRealSumPdf::_coefList
RooListProxy _coefList
Definition: RooRealSumPdf.h:84
RooCacheManager::getObjByIndex
T * getObjByIndex(Int_t index) const
Retrieve payload object by slot index.
Definition: RooCacheManager.h:310
RooAbsPdf::CanNotBeExtended
@ CanNotBeExtended
Definition: RooAbsPdf.h:230
RooAbsPdf::getNorm
Double_t getNorm(const RooArgSet &nset) const
Get normalisation term needed to normalise the raw values returned by getVal().
Definition: RooAbsPdf.h:209
RooRealSumPdf::expectedEvents
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return expected number of events for extended likelihood calculation, which is the sum of all coeffic...
Definition: RooRealSumPdf.cxx:507
RooNaNPacker.h
RooRealSumPdf::_haveWarned
bool _haveWarned
Definition: RooRealSumPdf.h:88
Double_t
RooSpan::empty
constexpr bool empty() const noexcept
Definition: RooSpan.h:125
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:101
RooRealSumPdf::_funcList
RooListProxy _funcList
Definition: RooRealSumPdf.h:83
RooRealProxy.h
RooAbsArg::RooArgSet
friend class RooArgSet
Definition: RooAbsArg.h:599
RooAbsCollection::add
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
Definition: RooAbsCollection.cxx:455
RooAbsCollection::size
Storage_t::size_type size() const
Definition: RooAbsCollection.h:214
RooRealSumPdf::haveLastCoef
bool haveLastCoef() const
Definition: RooRealSumPdf.h:93
RooRealSumPdf::printMetaArgs
void printMetaArgs(std::ostream &os) const
Customized printing of arguments of a RooRealSumPdf to more intuitively reflect the contents of the p...
Definition: RooRealSumPdf.cxx:646
RooRealVar.h
RooRealSumPdf::_doFloorGlobal
static Bool_t _doFloorGlobal
Definition: RooRealSumPdf.h:89
RooAbsCollection::end
const_iterator end() const
Definition: RooAbsCollection.h:202
RooAbsCollection::addOwned
virtual Bool_t addOwned(RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
Definition: RooAbsCollection.cxx:403
RooRealSumPdf::analyticalIntegralWN
Double_t analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=0) const
Implement analytical integrations by deferring integration of component functions to integrators of c...
Definition: RooRealSumPdf.cxx:413
RooAbsCollection::begin
const_iterator begin() const
Definition: RooAbsCollection.h:198
RooAbsArg::getObservables
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Given a set of possible observables, return the observables that this PDF depends on.
Definition: RooAbsArg.h:295
R__ASSERT
#define R__ASSERT(e)
Definition: TError.h:118
RooRealSumPdf::checkObservables
virtual Bool_t checkObservables(const RooArgSet *nset) const
Check if FUNC is valid for given normalization set.
Definition: RooRealSumPdf.cxx:330
name
char name[80]
Definition: TGX11.cxx:110
RunContext.h
RooCacheManager::lastIndex
Int_t lastIndex() const
Definition: RooCacheManager.h:66
RooRealSumPdf::binBoundaries
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &, Double_t, Double_t) const
Retrieve bin boundaries if this distribution is binned in obs.
Definition: RooRealSumPdf.cxx:519
RooListProxy::add
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE) override
Reimplementation of standard RooArgList::add()
Definition: RooListProxy.cxx:104
RooRealIntegral.h
RooAbsCollection::Print
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
Definition: RooAbsCollection.h:259
RooAbsPdf
Definition: RooAbsPdf.h:41
RooRealSumPdf::CacheElem::_funcNormList
RooArgList _funcNormList
Definition: RooRealSumPdf.h:78
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
RooRealSumPdf.h
Class
void Class()
Definition: Class.C:29
RooFit::Eval
@ Eval
Definition: RooGlobalFunc.h:61
RooRealSumPdf::~RooRealSumPdf
virtual ~RooRealSumPdf()
Destructor.
Definition: RooRealSumPdf.cxx:209
RooAbsRealLValue
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
Definition: RooAbsRealLValue.h:31
RooRealSumPdf
The class RooRealSumPdf implements a PDF constructed from a sum of functions:
Definition: RooRealSumPdf.h:24
RooRealSumPdf::evaluate
Double_t evaluate() const
Calculate the current value.
Definition: RooRealSumPdf.cxx:231
RooBatchCompute::RunContext
This struct enables passing computation data around between elements of a computation graph.
Definition: RunContext.h:31
RooCacheManager::selectFromSet1
RooArgSet selectFromSet1(RooArgSet const &argSet, int index) const
Create RooArgSet contatining the objects that are both in the cached set 1.
Definition: RooCacheManager.h:324
RooAbsCollection::getSize
Int_t getSize() const
Definition: RooAbsCollection.h:231
RooSpan
A simple container to hold a batch of data values.
Definition: RooSpan.h:34
RooArgSet
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:33
int
TError.h