Logo ROOT   6.16/01
Reference Guide
RooAddPdf.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 RooAddPdf
19 \ingroup Roofitcore
20
21
22RooAddPdf is an efficient implementation of a sum of PDFs of the form
23
24\f[
25 \sum_{i=1}^{n} c_i * \mathrm{PDF}_i
26\f]
27
28or
29\f[
30 c_1*\mathrm{PDF}_1 + c_2*\mathrm{PDF}_2 + ... + (1-\sum_{i=1}^{n-1}c_i)*\mathrm{PDF}_n
31\f]
32
33The first form is for extended likelihood fits, where the
34expected number of events is \f$ \sum_i c_i \f$. The coefficients \f$ c_i \f$
35can either be explicitly provided, or, if all components support
36extended likelihood fits, they can be calculated the contribution
37of each PDF to the total number of expected events.
38
39In the second form, the sum of the coefficients is required to be one or less,
40and the coefficient of the last PDF is calculated from that condition.
41
42It is also possible to parameterize the coefficients recursively
43
44\f[
45c_1*\mathrm{PDF}_1 + (1-c_1)(c_2*\mathrm{PDF}_2 + (1-c_2)*(c_3*\mathrm{PDF}_3 + ...))
46\f]
47
48In this form the sum of the coefficients is always less than 1.0
49for all possible values of the individual coefficients between 0 and 1.
50
51RooAddPdf relies on each component PDF to be normalized and will perform
52no normalization other than calculating the proper last coefficient \f$ c_n \f$, if requested.
53An (enforced) condition for this assumption is that each \f$ \mathrm{PDF}_i \f$ is independent
54of each \f$ c_i \f$.
55
56*/
57
58
59#include "RooFit.h"
60#include "RooMsgService.h"
61
62#include "TIterator.h"
63#include "TIterator.h"
64#include "TList.h"
65#include "RooAddPdf.h"
66#include "RooDataSet.h"
67#include "RooRealProxy.h"
68#include "RooPlot.h"
69#include "RooRealVar.h"
70#include "RooAddGenContext.h"
71#include "RooRealConstant.h"
72#include "RooNameReg.h"
73#include "RooMsgService.h"
75#include "RooGlobalFunc.h"
76#include "RooRealIntegral.h"
77#include "RooTrace.h"
78
79#include "Riostream.h"
80#include <algorithm>
81
82
83using namespace std;
84
86;
87
88
89////////////////////////////////////////////////////////////////////////////////
90/// Default constructor used for persistence
91
93 _refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
94 _refCoefRangeName(0),
95 _codeReg(10),
96 _snormList(0),
97 _recursive(kFALSE)
98{
101
102 _coefCache = new Double_t[100] ;
105}
106
107
108
109////////////////////////////////////////////////////////////////////////////////
110/// Dummy constructor
111
112RooAddPdf::RooAddPdf(const char *name, const char *title) :
113 RooAbsPdf(name,title),
114 _refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
115 _refCoefRangeName(0),
116 _projectCoefs(kFALSE),
117 _projCacheMgr(this,10),
118 _codeReg(10),
119 _pdfList("!pdfs","List of PDFs",this),
120 _coefList("!coefficients","List of coefficients",this),
121 _snormList(0),
122 _haveLastCoef(kFALSE),
123 _allExtendable(kFALSE),
124 _recursive(kFALSE)
125{
128
129 _coefCache = new Double_t[100] ;
132}
133
134
135
136////////////////////////////////////////////////////////////////////////////////
137/// Constructor with two PDFs and one coefficient
138
139RooAddPdf::RooAddPdf(const char *name, const char *title,
140 RooAbsPdf& pdf1, RooAbsPdf& pdf2, RooAbsReal& coef1) :
141 RooAbsPdf(name,title),
142 _refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
143 _refCoefRangeName(0),
144 _projectCoefs(kFALSE),
145 _projCacheMgr(this,10),
146 _codeReg(10),
147 _pdfList("!pdfs","List of PDFs",this),
148 _coefList("!coefficients","List of coefficients",this),
149 _haveLastCoef(kFALSE),
150 _allExtendable(kFALSE),
151 _recursive(kFALSE)
152{
155
156 _pdfList.add(pdf1) ;
157 _pdfList.add(pdf2) ;
158 _coefList.add(coef1) ;
159
163}
164
165
166
167////////////////////////////////////////////////////////////////////////////////
168/// Generic constructor from list of PDFs and list of coefficients.
169/// Each pdf list element (i) is paired with coefficient list element (i).
170/// The number of coefficients must be either equal to the number of PDFs,
171/// in which case extended MLL fitting is enabled, or be one less.
172///
173/// All PDFs must inherit from RooAbsPdf. All coefficients must inherit from RooAbsReal
174///
175/// If the recursiveFraction flag is true, the coefficients are interpreted as recursive
176/// coefficients as explained in the class description.
177
178RooAddPdf::RooAddPdf(const char *name, const char *title, const RooArgList& inPdfList, const RooArgList& inCoefList, Bool_t recursiveFractions) :
179 RooAbsPdf(name,title),
180 _refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
181 _refCoefRangeName(0),
182 _projectCoefs(kFALSE),
183 _projCacheMgr(this,10),
184 _codeReg(10),
185 _pdfList("!pdfs","List of PDFs",this),
186 _coefList("!coefficients","List of coefficients",this),
187 _haveLastCoef(kFALSE),
188 _allExtendable(kFALSE),
189 _recursive(kFALSE)
190{
191 if (inPdfList.getSize()>inCoefList.getSize()+1 || inPdfList.getSize()<inCoefList.getSize()) {
192 coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName()
193 << ") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1" << endl ;
194 assert(0) ;
195 }
196
197 if (recursiveFractions && inPdfList.getSize()!=inCoefList.getSize()+1) {
198 coutW(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName()
199 << ") WARNING inconsistent input: recursive fractions options can only be used if Npdf=Ncoef+1, ignoring recursive fraction setting" << endl ;
200 }
201
202
205
206 // Constructor with N PDFs and N or N-1 coefs
207 TIterator* pdfIter = inPdfList.createIterator() ;
208 TIterator* coefIter = inCoefList.createIterator() ;
209 RooAbsPdf* pdf ;
210 RooAbsReal* coef ;
211
212 RooArgList partinCoefList ;
213
215
216 while((coef = (RooAbsPdf*)coefIter->Next())) {
217 pdf = (RooAbsPdf*) pdfIter->Next() ;
218 if (!pdf) {
219 coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName()
220 << ") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1" << endl ;
221 assert(0) ;
222 }
223 if (!dynamic_cast<RooAbsReal*>(coef)) {
224 coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") coefficient " << coef->GetName() << " is not of type RooAbsReal, ignored" << endl ;
225 continue ;
226 }
227 if (!dynamic_cast<RooAbsReal*>(pdf)) {
228 coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not of type RooAbsPdf, ignored" << endl ;
229 continue ;
230 }
231 _pdfList.add(*pdf) ;
232
233 // Process recursive fraction mode separately
234 if (recursiveFractions) {
235 partinCoefList.add(*coef) ;
236 if (first) {
237
238 // The first fraction is the first plain fraction
239 first = kFALSE ;
240 _coefList.add(*coef) ;
241
242 } else {
243
244 // The i-th recursive fraction = (1-f1)*(1-f2)*...(fi) and is calculated from the list (f1,...,fi) by RooRecursiveFraction)
245 RooAbsReal* rfrac = new RooRecursiveFraction(Form("%s_recursive_fraction_%s",GetName(),pdf->GetName()),"Recursive Fraction",partinCoefList) ;
246 addOwnedComponents(*rfrac) ;
247 _coefList.add(*rfrac) ;
248
249 }
250
251 } else {
252 _coefList.add(*coef) ;
253 }
254 }
255
256 pdf = (RooAbsPdf*) pdfIter->Next() ;
257 if (pdf) {
258 if (!dynamic_cast<RooAbsReal*>(pdf)) {
259 coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") last pdf " << coef->GetName() << " is not of type RooAbsPdf, fatal error" << endl ;
260 assert(0) ;
261 }
262 _pdfList.add(*pdf) ;
263
264 // Process recursive fractions mode
265 if (recursiveFractions) {
266
267 // The last recursive fraction = (1-f1)*(1-f2)*...(1-fN) and is calculated from the list (f1,...,fN,1) by RooRecursiveFraction)
268 partinCoefList.add(RooFit::RooConst(1)) ;
269 RooAbsReal* rfrac = new RooRecursiveFraction(Form("%s_recursive_fraction_%s",GetName(),pdf->GetName()),"Recursive Fraction",partinCoefList) ;
270 addOwnedComponents(*rfrac) ;
271 _coefList.add(*rfrac) ;
272
273 // In recursive mode we always have Ncoef=Npdf
275 }
276
277 } else {
279 }
280
281 delete pdfIter ;
282 delete coefIter ;
283
286 _recursive = recursiveFractions ;
287
289}
290
291
292
293////////////////////////////////////////////////////////////////////////////////
294/// Generic constructor from list of extended PDFs. There are no coefficients as the expected
295/// number of events from each components determine the relative weight of the PDFs.
296///
297/// All PDFs must inherit from RooAbsPdf.
298
299RooAddPdf::RooAddPdf(const char *name, const char *title, const RooArgList& inPdfList) :
300 RooAbsPdf(name,title),
301 _refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
302 _refCoefRangeName(0),
303 _projectCoefs(kFALSE),
304 _projCacheMgr(this,10),
305 _pdfList("!pdfs","List of PDFs",this),
306 _coefList("!coefficients","List of coefficients",this),
307 _haveLastCoef(kFALSE),
308 _allExtendable(kTRUE),
309 _recursive(kFALSE)
310{
313
314 // Constructor with N PDFs
315 TIterator* pdfIter = inPdfList.createIterator() ;
316 RooAbsPdf* pdf ;
317 while((pdf = (RooAbsPdf*) pdfIter->Next())) {
318
319 if (!dynamic_cast<RooAbsReal*>(pdf)) {
320 coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not of type RooAbsPdf, ignored" << endl ;
321 continue ;
322 }
323 if (!pdf->canBeExtended()) {
324 coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not extendable, ignored" << endl ;
325 continue ;
326 }
327 _pdfList.add(*pdf) ;
328 }
329
330 delete pdfIter ;
331
335}
336
337
338
339
340////////////////////////////////////////////////////////////////////////////////
341/// Copy constructor
342
343RooAddPdf::RooAddPdf(const RooAddPdf& other, const char* name) :
344 RooAbsPdf(other,name),
345 _refCoefNorm("!refCoefNorm",this,other._refCoefNorm),
346 _refCoefRangeName((TNamed*)other._refCoefRangeName),
347 _projectCoefs(other._projectCoefs),
348 _projCacheMgr(other._projCacheMgr,this),
349 _codeReg(other._codeReg),
350 _pdfList("!pdfs",this,other._pdfList),
351 _coefList("!coefficients",this,other._coefList),
352 _haveLastCoef(other._haveLastCoef),
353 _allExtendable(other._allExtendable),
354 _recursive(other._recursive)
355{
361}
362
363
364
365////////////////////////////////////////////////////////////////////////////////
366/// Destructor
367
369{
370 delete _pdfIter ;
371 delete _coefIter ;
372
373 if (_coefCache) delete[] _coefCache ;
375}
376
377
378
379////////////////////////////////////////////////////////////////////////////////
380/// By default the interpretation of the fraction coefficients is
381/// performed in the contextual choice of observables. This makes the
382/// shape of the p.d.f explicitly dependent on the choice of
383/// observables. This method instructs RooAddPdf to freeze the
384/// interpretation of the coefficients to be done in the given set of
385/// observables. If frozen, fractions are automatically transformed
386/// from the reference normalization set to the contextual normalization
387/// set by ratios of integrals
388
390{
391 if (refCoefNorm.getSize()==0) {
393 return ;
394 }
396
398 _refCoefNorm.add(refCoefNorm) ;
399
401}
402
403
404
405////////////////////////////////////////////////////////////////////////////////
406/// By default the interpretation of the fraction coefficients is
407/// performed in the default range. This make the shape of a RooAddPdf
408/// explicitly dependent on the range of the observables. To allow
409/// a range independent definition of the fraction this function
410/// instructs RooAddPdf to freeze its interpretation in the given
411/// named range. If the current normalization range is different
412/// from the reference range, the appropriate fraction coefficients
413/// are automically calculation from the reference fractions using
414/// ratios if integrals
415
416void RooAddPdf::fixCoefRange(const char* rangeName)
417{
420}
421
422
423
424////////////////////////////////////////////////////////////////////////////////
425/// Retrieve cache element with for calculation of p.d.f value with normalization set nset and integrated over iset
426/// in range 'rangeName'. If cache element does not exist, create and fill it on the fly. The cache contains
427/// suplemental normalization terms (in case not all added p.d.f.s have the same observables), projection
428/// integrals to calculated transformed fraction coefficients when a frozen reference frame is provided
429/// and projection integrals for similar transformations when a frozen reference range is provided.
430
431RooAddPdf::CacheElem* RooAddPdf::getProjCache(const RooArgSet* nset, const RooArgSet* iset, const char* rangeName) const
432{
433
434 // Check if cache already exists
435 CacheElem* cache = (CacheElem*) _projCacheMgr.getObj(nset,iset,0,rangeName) ;
436 if (cache) {
437 return cache ;
438 }
439
440 //Create new cache
441 cache = new CacheElem ;
442
443 // *** PART 1 : Create supplemental normalization list ***
444
445 // Retrieve the combined set of dependents of this PDF ;
446 RooArgSet *fullDepList = getObservables(nset) ;
447 if (iset) {
448 fullDepList->remove(*iset,kTRUE,kTRUE) ;
449 }
450
451 // Fill with dummy unit RRVs for now
452 _pdfIter->Reset() ;
453 _coefIter->Reset() ;
454 RooAbsPdf* pdf ;
455 RooAbsReal* coef ;
456 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
457 coef=(RooAbsPdf*)_coefIter->Next() ;
458
459 // Start with full list of dependents
460 RooArgSet supNSet(*fullDepList) ;
461
462 // Remove PDF dependents
463 RooArgSet* pdfDeps = pdf->getObservables(nset) ;
464 if (pdfDeps) {
465 supNSet.remove(*pdfDeps,kTRUE,kTRUE) ;
466 delete pdfDeps ;
467 }
468
469 // Remove coef dependents
470 RooArgSet* coefDeps = coef ? coef->getObservables(nset) : 0 ;
471 if (coefDeps) {
472 supNSet.remove(*coefDeps,kTRUE,kTRUE) ;
473 delete coefDeps ;
474 }
475
476 RooAbsReal* snorm ;
477 TString name(GetName()) ;
478 name.Append("_") ;
479 name.Append(pdf->GetName()) ;
480 name.Append("_SupNorm") ;
481 cache->_needSupNorm = kFALSE ;
482 if (supNSet.getSize()>0) {
483 snorm = new RooRealIntegral(name,"Supplemental normalization integral",RooRealConstant::value(1.0),supNSet) ;
484 cxcoutD(Caching) << "RooAddPdf " << GetName() << " making supplemental normalization set " << supNSet << " for pdf component " << pdf->GetName() << endl ;
485 cache->_needSupNorm = kTRUE ;
486 } else {
487 snorm = new RooRealVar(name,"Unit Supplemental normalization integral",1.0) ;
488 }
489 cache->_suppNormList.addOwned(*snorm) ;
490 }
491
492 delete fullDepList ;
493
494 if (_verboseEval>1) {
495 cxcoutD(Caching) << "RooAddPdf::syncSuppNormList(" << GetName() << ") synching supplemental normalization list for norm" << (nset?*nset:RooArgSet()) << endl ;
496 if dologD(Caching) {
497 cache->_suppNormList.Print("v") ;
498 }
499 }
500
501
502 // *** PART 2 : Create projection coefficients ***
503
504// cout << " this = " << this << " (" << GetName() << ")" << endl ;
505// cout << "projectCoefs = " << (_projectCoefs?"T":"F") << endl ;
506// cout << "_normRange.Length() = " << _normRange.Length() << endl ;
507
508 // If no projections required stop here
509 if (!_projectCoefs && !rangeName) {
510 _projCacheMgr.setObj(nset,iset,cache,RooNameReg::ptr(rangeName)) ;
511// cout << " no projection required" << endl ;
512 return cache ;
513 }
514
515
516// cout << "calculating projection" << endl ;
517
518 // Reduce iset/nset to actual dependents of this PDF
519 RooArgSet* nset2 = nset ? getObservables(nset) : new RooArgSet() ;
520 cxcoutD(Caching) << "RooAddPdf(" << GetName() << ")::getPC nset = " << (nset?*nset:RooArgSet()) << " nset2 = " << *nset2 << endl ;
521
522 if (nset2->getSize()==0 && _refCoefNorm.getSize()!=0) {
523 //cout << "WVE: evaluating RooAddPdf without normalization, but have reference normalization for coefficient definition" << endl ;
524
525 nset2->add(_refCoefNorm) ;
526 if (_refCoefRangeName) {
528 }
529 }
530
531
532 // Check if requested transformation is not identity
533 if (!nset2->equals(_refCoefNorm) || _refCoefRangeName !=0 || rangeName !=0 || _normRange.Length()>0) {
534
535 cxcoutD(Caching) << "ALEX: RooAddPdf::syncCoefProjList(" << GetName() << ") projecting coefficients from "
536 << *nset2 << (rangeName?":":"") << (rangeName?rangeName:"")
537 << " to " << ((_refCoefNorm.getSize()>0)?_refCoefNorm:*nset2) << (_refCoefRangeName?":":"") << (_refCoefRangeName?RooNameReg::str(_refCoefRangeName):"") << endl ;
538
539 // Recalculate projection integrals of PDFs
540 _pdfIter->Reset() ;
541 RooAbsPdf* thePdf ;
542
543 while((thePdf=(RooAbsPdf*)_pdfIter->Next())) {
544
545 // Calculate projection integral
546 RooAbsReal* pdfProj ;
547 if (!nset2->equals(_refCoefNorm)) {
548 pdfProj = thePdf->createIntegral(*nset2,_refCoefNorm,_normRange.Length()>0?_normRange.Data():0) ;
549 pdfProj->setOperMode(operMode()) ;
550 cxcoutD(Caching) << "RooAddPdf(" << GetName() << ")::getPC nset2(" << *nset2 << ")!=_refCoefNorm(" << _refCoefNorm << ") --> pdfProj = " << pdfProj->GetName() << endl ;
551 } else {
552 TString name(GetName()) ;
553 name.Append("_") ;
554 name.Append(thePdf->GetName()) ;
555 name.Append("_ProjectNorm") ;
556 pdfProj = new RooRealVar(name,"Unit Projection normalization integral",1.0) ;
557 cxcoutD(Caching) << "RooAddPdf(" << GetName() << ")::getPC nset2(" << *nset2 << ")==_refCoefNorm(" << _refCoefNorm << ") --> pdfProj = " << pdfProj->GetName() << endl ;
558 }
559
560 cache->_projList.addOwned(*pdfProj) ;
561 cxcoutD(Caching) << " RooAddPdf::syncCoefProjList(" << GetName() << ") PP = " << pdfProj->GetName() << endl ;
562
563 // Calculation optional supplemental normalization term
564 RooArgSet supNormSet(_refCoefNorm) ;
565 RooArgSet* deps = thePdf->getParameters(RooArgSet()) ;
566 supNormSet.remove(*deps,kTRUE,kTRUE) ;
567 delete deps ;
568
569 RooAbsReal* snorm ;
570 TString name(GetName()) ;
571 name.Append("_") ;
572 name.Append(thePdf->GetName()) ;
573 name.Append("_ProjSupNorm") ;
574 if (supNormSet.getSize()>0 && !nset2->equals(_refCoefNorm) ) {
575 snorm = new RooRealIntegral(name,"Projection Supplemental normalization integral",
576 RooRealConstant::value(1.0),supNormSet) ;
577 } else {
578 snorm = new RooRealVar(name,"Unit Projection Supplemental normalization integral",1.0) ;
579 }
580 cxcoutD(Caching) << " RooAddPdf::syncCoefProjList(" << GetName() << ") SN = " << snorm->GetName() << endl ;
581 cache->_suppProjList.addOwned(*snorm) ;
582
583 // Calculate reference range adjusted projection integral
584 RooAbsReal* rangeProj1 ;
585
586 // cout << "ALEX >>>> RooAddPdf(" << GetName() << ")::getPC _refCoefRangeName WVE = "
587// <<(_refCoefRangeName?":":"") << (_refCoefRangeName?RooNameReg::str(_refCoefRangeName):"")
588// <<" _refCoefRangeName AK = " << (_refCoefRangeName?_refCoefRangeName->GetName():"")
589// << " && _refCoefNorm" << _refCoefNorm << " with size = _refCoefNorm.getSize() " << _refCoefNorm.getSize() << endl ;
590
591 // Check if _refCoefRangeName is identical to default range for all observables,
592 // If so, substitute by unit integral
593
594 // ----------
595 RooArgSet* tmpObs = thePdf->getObservables(_refCoefNorm) ;
596 RooAbsArg* obsArg ;
597 TIterator* iter = tmpObs->createIterator() ;
598 Bool_t allIdent = kTRUE ;
599 while((obsArg=(RooAbsArg*)iter->Next())) {
600 RooRealVar* rvarg = dynamic_cast<RooRealVar*>(obsArg) ;
601 if (rvarg) {
602 if (rvarg->getMin(RooNameReg::str(_refCoefRangeName))!=rvarg->getMin() ||
603 rvarg->getMax(RooNameReg::str(_refCoefRangeName))!=rvarg->getMax()) {
604 allIdent=kFALSE ;
605 }
606 }
607 }
608 delete iter ;
609 delete tmpObs ;
610 // -------------
611
612 if (_refCoefRangeName && _refCoefNorm.getSize()>0 && !allIdent) {
613
614
615 RooArgSet* tmp = thePdf->getObservables(_refCoefNorm) ;
616 rangeProj1 = thePdf->createIntegral(*tmp,*tmp,RooNameReg::str(_refCoefRangeName)) ;
617
618 //rangeProj1->setOperMode(operMode()) ;
619
620 delete tmp ;
621 } else {
622
623 TString theName(GetName()) ;
624 theName.Append("_") ;
625 theName.Append(thePdf->GetName()) ;
626 theName.Append("_RangeNorm1") ;
627 rangeProj1 = new RooRealVar(theName,"Unit range normalization integral",1.0) ;
628
629 }
630 cxcoutD(Caching) << " RooAddPdf::syncCoefProjList(" << GetName() << ") R1 = " << rangeProj1->GetName() << endl ;
631 cache->_refRangeProjList.addOwned(*rangeProj1) ;
632
633
634 // Calculate range adjusted projection integral
635 RooAbsReal* rangeProj2 ;
636 cxcoutD(Caching) << "RooAddPdf::syncCoefProjList(" << GetName() << ") rangename = " << (rangeName?rangeName:"<null>")
637 << " nset = " << (nset?*nset:RooArgSet()) << endl ;
638 if (rangeName && _refCoefNorm.getSize()>0) {
639
640 rangeProj2 = thePdf->createIntegral(_refCoefNorm,_refCoefNorm,rangeName) ;
641 //rangeProj2->setOperMode(operMode()) ;
642
643 } else if (_normRange.Length()>0) {
644
645 RooArgSet* tmp = thePdf->getObservables(_refCoefNorm) ;
646 rangeProj2 = thePdf->createIntegral(*tmp,*tmp,_normRange.Data()) ;
647 delete tmp ;
648
649 } else {
650
651 TString theName(GetName()) ;
652 theName.Append("_") ;
653 theName.Append(thePdf->GetName()) ;
654 theName.Append("_RangeNorm2") ;
655 rangeProj2 = new RooRealVar(theName,"Unit range normalization integral",1.0) ;
656
657 }
658 cxcoutD(Caching) << " RooAddPdf::syncCoefProjList(" << GetName() << ") R2 = " << rangeProj2->GetName() << endl ;
659 cache->_rangeProjList.addOwned(*rangeProj2) ;
660
661 }
662
663 }
664
665 delete nset2 ;
666
667 _projCacheMgr.setObj(nset,iset,cache,RooNameReg::ptr(rangeName)) ;
668
669 return cache ;
670}
671
672
673////////////////////////////////////////////////////////////////////////////////
674/// Update the coefficient values in the given cache element: calculate new remainder
675/// fraction, normalize fractions obtained from extended ML terms to unity and
676/// multiply these the various range and dimensional corrections needed in the
677/// current use context
678
679void RooAddPdf::updateCoefficients(CacheElem& cache, const RooArgSet* nset) const
680{
681 // cxcoutD(ChangeTracking) << "RooAddPdf::updateCoefficients(" << GetName() << ") update coefficients" << endl ;
682
683 Int_t i ;
684
685 // Straight coefficients
686 if (_allExtendable) {
687
688 // coef[i] = expectedEvents[i] / SUM(expectedEvents)
689 Double_t coefSum(0) ;
690 RooFIter it=_pdfList.fwdIterator() ; i=0 ;
691 RooAbsPdf* pdf ;
692 while((pdf=(RooAbsPdf*)it.next())) {
694 coefSum += _coefCache[i] ;
695 i++ ;
696 }
697
698 if (coefSum==0.) {
699 coutW(Eval) << "RooAddPdf::updateCoefCache(" << GetName() << ") WARNING: total number of expected events is 0" << endl ;
700 } else {
701 Int_t siz = _pdfList.getSize() ;
702 for (i=0 ; i<siz ; i++) {
703 _coefCache[i] /= coefSum ;
704 }
705 }
706
707 } else {
708 if (_haveLastCoef) {
709
710 // coef[i] = coef[i] / SUM(coef)
711 Double_t coefSum(0) ;
712 RooFIter it=_coefList.fwdIterator() ; i=0 ;
713 RooAbsReal* coef ;
714 while((coef=(RooAbsReal*)it.next())) {
715 _coefCache[i] = coef->getVal(nset) ;
716 coefSum += _coefCache[i] ;
717 i++ ;
718 }
719 if (coefSum==0.) {
720 coutW(Eval) << "RooAddPdf::updateCoefCache(" << GetName() << ") WARNING: sum of coefficients is zero 0" << endl ;
721 } else {
722 Int_t siz = _coefList.getSize() ;
723 for (i=0 ; i<siz ; i++) {
724 _coefCache[i] /= coefSum ;
725 }
726 }
727 } else {
728
729 // coef[i] = coef[i] ; coef[n] = 1-SUM(coef[0...n-1])
730 Double_t lastCoef(1) ;
731 RooFIter it=_coefList.fwdIterator() ; i=0 ;
732 RooAbsReal* coef ;
733 while((coef=(RooAbsReal*)it.next())) {
734 _coefCache[i] = coef->getVal(nset) ;
735 //cxcoutD(Caching) << "SYNC: orig coef[" << i << "] = " << _coefCache[i] << endl ;
736 lastCoef -= _coefCache[i] ;
737 i++ ;
738 }
739 _coefCache[_coefList.getSize()] = lastCoef ;
740 //cxcoutD(Caching) << "SYNC: orig coef[" << _coefList.getSize() << "] = " << _coefCache[_coefList.getSize()] << endl ;
741
742
743 // Warn about coefficient degeneration
744 if ((lastCoef<-1e-05 || (lastCoef-1)>1e-5) && _coefErrCount-->0) {
745 coutW(Eval) << "RooAddPdf::updateCoefCache(" << GetName()
746 << " WARNING: sum of PDF coefficients not in range [0-1], value="
747 << 1-lastCoef ;
748 if (_coefErrCount==0) {
749 coutW(Eval) << " (no more will be printed)" ;
750 }
751 coutW(Eval) << endl ;
752 }
753 }
754 }
755
756
757
758// cout << "XXXX" << GetName() << "updateCoefs _projectCoefs = " << (_projectCoefs?"T":"F") << " cache._projList.getSize()= " << cache._projList.getSize() << endl ;
759
760 // Stop here if not projection is required or needed
761 if ((!_projectCoefs && _normRange.Length()==0) || cache._projList.getSize()==0) {
762 //if (cache._projList.getSize()==0) {
763// cout << GetName() << " SYNC no projection required rangeName = " << (_normRange.Length()>0?_normRange.Data():"<none>") << endl ;
764 return ;
765 }
766
767// cout << "XXXX" << GetName() << " updateCoefs, applying correction" << endl ;
768// cout << "PROJLIST = " << endl ;
769// cache._projList.Print("v") ;
770
771
772 // Adjust coefficients for given projection
773 Double_t coefSum(0) ;
774 for (i=0 ; i<_pdfList.getSize() ; i++) {
777
778 RooAbsReal* pp = ((RooAbsReal*)cache._projList.at(i)) ;
779 RooAbsReal* sn = ((RooAbsReal*)cache._suppProjList.at(i)) ;
780 RooAbsReal* r1 = ((RooAbsReal*)cache._refRangeProjList.at(i)) ;
781 RooAbsReal* r2 = ((RooAbsReal*)cache._rangeProjList.at(i)) ;
782
783 Double_t proj = pp->getVal()/sn->getVal()*(r2->getVal()/r1->getVal()) ;
784
785// cxcoutD(Caching) << "ALEX: RooAddPdf::updateCoef(" << GetName() << ") with nset = " << (nset?*nset:RooArgSet()) << "for pdf component #" << i << " = " << _pdfList.at(i)->GetName() << endl
786// << "ALEX: pp = " << pp->GetName() << " = " << pp->getVal() << endl
787// << "ALEX: sn = " << sn->GetName() << " = " << sn->getVal() << endl
788// << "ALEX: r1 = " << r1->GetName() << " = " << r1->getVal() << endl
789// << "ALEX: r2 = " << r2->GetName() << " = " << r2->getVal() << endl
790// << "ALEX: proj = (" << pp->getVal() << "/" << sn->getVal() << ")*(" << r2->getVal() << "/" << r1->getVal() << ") = " << proj << endl ;
791
793
794 _coefCache[i] *= proj ;
795 coefSum += _coefCache[i] ;
796 }
797
798 for (i=0 ; i<_pdfList.getSize() ; i++) {
799 _coefCache[i] /= coefSum ;
800 // _coefCache[i] *= rfrac ;
801// cout << "POST-SYNC coef[" << i << "] = " << _coefCache[i] << endl ;
802 cxcoutD(Caching) << " ALEX: POST-SYNC coef[" << i << "] = " << _coefCache[i]
803 << " ( _coefCache[i]/coefSum = " << _coefCache[i]*coefSum << "/" << coefSum << " ) "<< endl ;
804 }
805
806
807
808}
809
810
811
812////////////////////////////////////////////////////////////////////////////////
813/// Calculate and return the current value
814
816{
817 const RooArgSet* nset = _normSet ;
818 //cxcoutD(Caching) << "RooAddPdf::evaluate(" << GetName() << ") calling getProjCache with nset = " << nset << " = " << (nset?*nset:RooArgSet()) << endl ;
819
820 if (nset==0 || nset->getSize()==0) {
821 if (_refCoefNorm.getSize()!=0) {
822 nset = &_refCoefNorm ;
823 }
824 }
825
826 CacheElem* cache = getProjCache(nset) ;
827 updateCoefficients(*cache,nset) ;
828
829 // Do running sum of coef/pdf pairs, calculate lastCoef.
830 RooAbsPdf* pdf ;
831 Double_t value(0) ;
832 Int_t i(0) ;
834
835 if (cache->_needSupNorm) {
836
837 Double_t snormVal ;
838 while((pdf = (RooAbsPdf*)pi.next())) {
839 snormVal = ((RooAbsReal*)cache->_suppNormList.at(i))->getVal() ;
840 Double_t pdfVal = pdf->getVal(nset) ;
841 if (pdf->isSelectedComp()) {
842 value += pdfVal*_coefCache[i]/snormVal ;
843 }
844 i++ ;
845 }
846 } else {
847
848 while((pdf = (RooAbsPdf*)pi.next())) {
849 Double_t pdfVal = pdf->getVal(nset) ;
850
851 if (pdf->isSelectedComp()) {
852 value += pdfVal*_coefCache[i] ;
853 }
854 i++ ;
855 }
856
857 }
858
859 return value ;
860}
861
862
863////////////////////////////////////////////////////////////////////////////////
864/// Reset error counter to given value, limiting the number
865/// of future error messages for this pdf to 'resetValue'
866
868{
870 _coefErrCount = resetValue ;
871}
872
873
874
875////////////////////////////////////////////////////////////////////////////////
876/// Check if PDF is valid for given normalization set.
877/// Coeffient and PDF must be non-overlapping, but pdf-coefficient
878/// pairs may overlap each other
879
881{
882 Bool_t ret(kFALSE) ;
883
884 _pdfIter->Reset() ;
885 _coefIter->Reset() ;
886 RooAbsReal* coef ;
887 RooAbsReal* pdf ;
888 while((coef=(RooAbsReal*)_coefIter->Next())) {
889 pdf = (RooAbsReal*)_pdfIter->Next() ;
890 if (pdf->observableOverlaps(nset,*coef)) {
891 coutE(InputArguments) << "RooAddPdf::checkObservables(" << GetName() << "): ERROR: coefficient " << coef->GetName()
892 << " and PDF " << pdf->GetName() << " have one or more dependents in common" << endl ;
893 ret = kTRUE ;
894 }
895 }
896
897 return ret ;
898}
899
900
901////////////////////////////////////////////////////////////////////////////////
902/// Determine which part (if any) of given integral can be performed analytically.
903/// If any analytical integration is possible, return integration scenario code
904///
905/// RooAddPdf queries each component PDF for its analytical integration capability of the requested
906/// set ('allVars'). It finds the largest common set of variables that can be integrated
907/// by all components. If such a set exists, it reconfirms that each component is capable of
908/// analytically integrating the common set, and combines the components individual integration
909/// codes into a single integration code valid for RooAddPdf.
910
912 const RooArgSet* normSet, const char* rangeName) const
913{
914
915 RooArgSet* allDepVars = getObservables(allVars) ;
916 RooArgSet allAnalVars(*allDepVars) ;
917 delete allDepVars ;
918
919 TIterator* avIter = allVars.createIterator() ;
920
921 Int_t n(0) ;
922
923 // First iteration, determine what each component can integrate analytically
924 _pdfIter->Reset() ;
925 RooAbsPdf* pdf ;
926 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
927 RooArgSet subAnalVars ;
928 pdf->getAnalyticalIntegralWN(allVars,subAnalVars,normSet,rangeName) ;
929
930 // Observables that cannot be integrated analytically by this component are dropped from the common list
931 avIter->Reset() ;
932 RooAbsArg* arg ;
933 while((arg=(RooAbsArg*)avIter->Next())) {
934 if (!subAnalVars.find(arg->GetName()) && pdf->dependsOn(*arg)) {
935 allAnalVars.remove(*arg,kTRUE,kTRUE) ;
936 }
937 }
938 n++ ;
939 }
940
941 // If no observables can be integrated analytically, return code 0 here
942 if (allAnalVars.getSize()==0) {
943 delete avIter ;
944 return 0 ;
945 }
946
947
948 // Now retrieve codes for integration over common set of analytically integrable observables for each component
949 _pdfIter->Reset() ;
950 n=0 ;
951 std::vector<Int_t> subCode(_pdfList.getSize());
952 Bool_t allOK(kTRUE) ;
953 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
954 RooArgSet subAnalVars ;
955 RooArgSet* allAnalVars2 = pdf->getObservables(allAnalVars) ;
956 subCode[n] = pdf->getAnalyticalIntegralWN(*allAnalVars2,subAnalVars,normSet,rangeName) ;
957 if (subCode[n]==0 && allAnalVars2->getSize()>0) {
958 coutE(InputArguments) << "RooAddPdf::getAnalyticalIntegral(" << GetName() << ") WARNING: component PDF " << pdf->GetName()
959 << " advertises inconsistent set of integrals (e.g. (X,Y) but not X or Y individually."
960 << " Distributed analytical integration disabled. Please fix PDF" << endl ;
961 allOK = kFALSE ;
962 }
963 delete allAnalVars2 ;
964 n++ ;
965 }
966 if (!allOK) {
967 delete avIter ;
968 return 0 ;
969 }
970
971 // Mare all analytically integrated observables as such
972 analVars.add(allAnalVars) ;
973
974 // Store set of variables analytically integrated
975 RooArgSet* intSet = new RooArgSet(allAnalVars) ;
976 Int_t masterCode = _codeReg.store(subCode,intSet)+1 ;
977
978 delete avIter ;
979
980 return masterCode ;
981}
982
983
984
985////////////////////////////////////////////////////////////////////////////////
986/// Return analytical integral defined by given scenario code
987
988Double_t RooAddPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
989{
990 // WVE needs adaptation to handle new rangeName feature
991 if (code==0) {
992 return getVal(normSet) ;
993 }
994
995 // Retrieve analytical integration subCodes and set of observabels integrated over
996 RooArgSet* intSet ;
997 const std::vector<Int_t>& subCode = _codeReg.retrieve(code-1,intSet) ;
998 if (subCode.empty()) {
999 coutE(InputArguments) << "RooAddPdf::analyticalIntegral(" << GetName() << "): ERROR unrecognized integration code, " << code << endl ;
1000 assert(0) ;
1001 }
1002
1003 cxcoutD(Caching) << "RooAddPdf::aiWN(" << GetName() << ") calling getProjCache with nset = " << (normSet?*normSet:RooArgSet()) << endl ;
1004
1005 if ((normSet==0 || normSet->getSize()==0) && _refCoefNorm.getSize()>0) {
1006// cout << "WVE integration of RooAddPdf without normalization, but have reference set, using ref set for normalization" << endl ;
1007 normSet = &_refCoefNorm ;
1008 }
1009
1010 CacheElem* cache = getProjCache(normSet,intSet,0) ; // WVE rangename here?
1011 updateCoefficients(*cache,normSet) ;
1012
1013 // Calculate the current value of this object
1014 Double_t value(0) ;
1015
1016 // Do running sum of coef/pdf pairs, calculate lastCoef.
1017 _pdfIter->Reset() ;
1018 _coefIter->Reset() ;
1019 RooAbsPdf* pdf ;
1020 Double_t snormVal ;
1021 Int_t i(0) ;
1022
1023 //cout << "ROP::aIWN updateCoefCache with rangeName = " << (rangeName?rangeName:"<null>") << endl ;
1024 RooArgList* snormSet = (cache->_suppNormList.getSize()>0) ? &cache->_suppNormList : 0 ;
1025 while((pdf = (RooAbsPdf*)_pdfIter->Next())) {
1026 if (_coefCache[i]) {
1027 snormVal = snormSet ? ((RooAbsReal*) cache->_suppNormList.at(i))->getVal() : 1.0 ;
1028
1029 // WVE swap this?
1030 Double_t val = pdf->analyticalIntegralWN(subCode[i],normSet,rangeName) ;
1031 if (pdf->isSelectedComp()) {
1032
1033 value += val*_coefCache[i]/snormVal ;
1034 }
1035 }
1036 i++ ;
1037 }
1038
1039 return value ;
1040}
1041
1042
1043
1044////////////////////////////////////////////////////////////////////////////////
1045/// Return the number of expected events, which is either the sum of all coefficients
1046/// or the sum of the components extended terms, multiplied with the fraction that
1047/// is in the current range w.r.t the reference range
1048
1050{
1051 Double_t expectedTotal(0.0);
1052
1053 cxcoutD(Caching) << "RooAddPdf::expectedEvents(" << GetName() << ") calling getProjCache with nset = " << (nset?*nset:RooArgSet()) << endl ;
1054 CacheElem* cache = getProjCache(nset) ;
1055 updateCoefficients(*cache,nset) ;
1056
1057 if (cache->_rangeProjList.getSize()>0) {
1058
1059 RooFIter iter1 = cache->_refRangeProjList.fwdIterator() ;
1060 RooFIter iter2 = cache->_rangeProjList.fwdIterator() ;
1061 RooFIter iter3 = _pdfList.fwdIterator() ;
1062
1063 if (_allExtendable) {
1064
1065 RooAbsPdf* pdf ;
1066 while ((pdf=(RooAbsPdf*)iter3.next())) {
1067 RooAbsReal* r1 = (RooAbsReal*)iter1.next() ;
1068 RooAbsReal* r2 = (RooAbsReal*)iter2.next() ;
1069 expectedTotal += (r2->getVal()/r1->getVal()) * pdf->expectedEvents(nset) ;
1070 }
1071
1072 } else {
1073
1074 RooFIter citer = _coefList.fwdIterator() ;
1075 RooAbsReal* coef ;
1076 while((coef=(RooAbsReal*)citer.next())) {
1077 Double_t ncomp = coef->getVal(nset) ;
1078 RooAbsReal* r1 = (RooAbsReal*)iter1.next() ;
1079 RooAbsReal* r2 = (RooAbsReal*)iter2.next() ;
1080 expectedTotal += (r2->getVal()/r1->getVal()) * ncomp ;
1081 }
1082
1083 }
1084
1085
1086
1087 } else {
1088
1089 if (_allExtendable) {
1090
1091 RooFIter iter = _pdfList.fwdIterator() ;
1092 RooAbsPdf* pdf ;
1093 while((pdf=(RooAbsPdf*)iter.next())) {
1094 expectedTotal += pdf->expectedEvents(nset) ;
1095 }
1096
1097 } else {
1098
1099 RooFIter citer = _coefList.fwdIterator() ;
1100 RooAbsReal* coef ;
1101 while((coef=(RooAbsReal*)citer.next())) {
1102 Double_t ncomp = coef->getVal(nset) ;
1103 expectedTotal += ncomp ;
1104 }
1105
1106 }
1107
1108 }
1109 return expectedTotal ;
1110}
1111
1112
1113
1114////////////////////////////////////////////////////////////////////////////////
1115/// Interface function used by test statistics to freeze choice of observables
1116/// for interpretation of fraction coefficients
1117
1119{
1120
1121 if (!force && _refCoefNorm.getSize()!=0) {
1122 return ;
1123 }
1124
1125 if (!depSet) {
1127 return ;
1128 }
1129
1130 RooArgSet* myDepSet = getObservables(depSet) ;
1131 fixCoefNormalization(*myDepSet) ;
1132 delete myDepSet ;
1133}
1134
1135
1136
1137////////////////////////////////////////////////////////////////////////////////
1138/// Interface function used by test statistics to freeze choice of range
1139/// for interpretation of fraction coefficients
1140
1141void RooAddPdf::selectNormalizationRange(const char* rangeName, Bool_t force)
1142{
1143 if (!force && _refCoefRangeName) {
1144 return ;
1145 }
1146
1147 fixCoefRange(rangeName) ;
1148}
1149
1150
1151
1152////////////////////////////////////////////////////////////////////////////////
1153/// Return specialized context to efficiently generate toy events from RooAddPdfs
1154/// return RooAbsPdf::genContext(vars,prototype,auxProto,verbose) ; // WVE DEBUG
1155
1157 const RooArgSet* auxProto, Bool_t verbose) const
1158{
1159 return new RooAddGenContext(*this,vars,prototype,auxProto,verbose) ;
1160}
1161
1162
1163
1164////////////////////////////////////////////////////////////////////////////////
1165/// List all RooAbsArg derived contents in this cache element
1166
1168{
1169 RooArgList allNodes;
1170 allNodes.add(_projList) ;
1171 allNodes.add(_suppProjList) ;
1172 allNodes.add(_refRangeProjList) ;
1173 allNodes.add(_rangeProjList) ;
1174
1175 return allNodes ;
1176}
1177
1178
1179
1180////////////////////////////////////////////////////////////////////////////////
1181/// Loop over components for plot sampling hints and merge them if there are multiple
1182
1183std::list<Double_t>* RooAddPdf::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
1184{
1185 list<Double_t>* sumHint = 0 ;
1186
1187 _pdfIter->Reset() ;
1188 RooAbsPdf* pdf ;
1189 Bool_t needClean(kFALSE) ;
1190
1191 // Loop over components pdf
1192 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
1193
1194 list<Double_t>* pdfHint = pdf->plotSamplingHint(obs,xlo,xhi) ;
1195
1196 // Process hint
1197 if (pdfHint) {
1198 if (!sumHint) {
1199
1200 // If this is the first hint, then just save it
1201 sumHint = pdfHint ;
1202
1203 } else {
1204
1205 list<Double_t>* newSumHint = new list<Double_t>(sumHint->size()+pdfHint->size()) ;
1206
1207 // Merge hints into temporary array
1208 merge(pdfHint->begin(),pdfHint->end(),sumHint->begin(),sumHint->end(),newSumHint->begin()) ;
1209
1210 // Copy merged array without duplicates to new sumHintArrau
1211 delete sumHint ;
1212 sumHint = newSumHint ;
1213 needClean = kTRUE ;
1214
1215 }
1216 }
1217 }
1218 if (needClean) {
1219 list<Double_t>::iterator new_end = unique(sumHint->begin(),sumHint->end()) ;
1220 sumHint->erase(new_end,sumHint->end()) ;
1221 }
1222
1223 return sumHint ;
1224}
1225
1226
1227////////////////////////////////////////////////////////////////////////////////
1228/// Loop over components for plot sampling hints and merge them if there are multiple
1229
1230std::list<Double_t>* RooAddPdf::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
1231{
1232 list<Double_t>* sumBinB = 0 ;
1233 Bool_t needClean(kFALSE) ;
1234
1235 _pdfIter->Reset() ;
1236 RooAbsPdf* pdf ;
1237 // Loop over components pdf
1238 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
1239
1240 list<Double_t>* pdfBinB = pdf->binBoundaries(obs,xlo,xhi) ;
1241
1242 // Process hint
1243 if (pdfBinB) {
1244 if (!sumBinB) {
1245
1246 // If this is the first hint, then just save it
1247 sumBinB = pdfBinB ;
1248
1249 } else {
1250
1251 list<Double_t>* newSumBinB = new list<Double_t>(sumBinB->size()+pdfBinB->size()) ;
1252
1253 // Merge hints into temporary array
1254 merge(pdfBinB->begin(),pdfBinB->end(),sumBinB->begin(),sumBinB->end(),newSumBinB->begin()) ;
1255
1256 // Copy merged array without duplicates to new sumBinBArrau
1257 delete sumBinB ;
1258 delete pdfBinB ;
1259 sumBinB = newSumBinB ;
1260 needClean = kTRUE ;
1261 }
1262 }
1263 }
1264
1265 // Remove consecutive duplicates
1266 if (needClean) {
1267 list<Double_t>::iterator new_end = unique(sumBinB->begin(),sumBinB->end()) ;
1268 sumBinB->erase(new_end,sumBinB->end()) ;
1269 }
1270
1271 return sumBinB ;
1272}
1273
1274
1275////////////////////////////////////////////////////////////////////////////////
1276/// If all components that depend on obs are binned that so is the product
1277
1279{
1280 _pdfIter->Reset() ;
1281 RooAbsPdf* pdf ;
1282 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
1283 if (pdf->dependsOn(obs) && !pdf->isBinnedDistribution(obs)) {
1284 return kFALSE ;
1285 }
1286 }
1287
1288 return kTRUE ;
1289}
1290
1291
1292////////////////////////////////////////////////////////////////////////////////
1293/// Label OK'ed components of a RooAddPdf with cache-and-track
1294
1296{
1297 RooFIter aiter = pdfList().fwdIterator() ;
1298 RooAbsArg* aarg ;
1299 while ((aarg=aiter.next())) {
1300 if (aarg->canNodeBeCached()==Always) {
1301 trackNodes.add(*aarg) ;
1302 //cout << "tracking node RooAddPdf component " << aarg->IsA()->GetName() << "::" << aarg->GetName() << endl ;
1303 }
1304 }
1305}
1306
1307
1308
1309////////////////////////////////////////////////////////////////////////////////
1310/// Customized printing of arguments of a RooAddPdf to more intuitively reflect the contents of the
1311/// product operator construction
1312
1313void RooAddPdf::printMetaArgs(ostream& os) const
1314{
1315 _pdfIter->Reset() ;
1316 _coefIter->Reset() ;
1317
1318 Bool_t first(kTRUE) ;
1319
1320 RooAbsArg* coef, *pdf ;
1321 if (_coefList.getSize()!=0) {
1322 while((coef=(RooAbsArg*)_coefIter->Next())) {
1323 if (!first) {
1324 os << " + " ;
1325 } else {
1326 first = kFALSE ;
1327 }
1328 pdf=(RooAbsArg*)_pdfIter->Next() ;
1329 os << coef->GetName() << " * " << pdf->GetName() ;
1330 }
1331 pdf = (RooAbsArg*) _pdfIter->Next() ;
1332 if (pdf) {
1333 os << " + [%] * " << pdf->GetName() ;
1334 }
1335 } else {
1336
1337 while((pdf=(RooAbsArg*)_pdfIter->Next())) {
1338 if (!first) {
1339 os << " + " ;
1340 } else {
1341 first = kFALSE ;
1342 }
1343 os << pdf->GetName() ;
1344 }
1345 }
1346
1347 os << " " ;
1348}
#define e(i)
Definition: RSha256.hxx:103
#define cxcoutD(a)
Definition: RooMsgService.h:79
#define coutW(a)
Definition: RooMsgService.h:33
#define dologD(a)
Definition: RooMsgService.h:63
#define coutE(a)
Definition: RooMsgService.h:34
#define TRACE_DESTROY
Definition: RooTrace.h:23
#define TRACE_CREATE
Definition: RooTrace.h:22
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
char * Form(const char *fmt,...)
const std::vector< Int_t > & retrieve(Int_t masterCode) const
Retrieve the array of integer codes associated with the given master code.
Int_t store(const std::vector< Int_t > &codeList, RooArgSet *set1=0, RooArgSet *set2=0, RooArgSet *set3=0, RooArgSet *set4=0)
Store given arrays of integer codes, and up to four RooArgSets in the registry (each setX pointer may...
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Definition: RooAbsArg.h:194
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:736
virtual CacheMode canNodeBeCached() const
Definition: RooAbsArg.h:317
friend class RooArgSet
Definition: RooAbsArg.h:471
RooArgSet * getParameters(const RooAbsData *data, Bool_t stripDisconnected=kTRUE) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
Definition: RooAbsArg.cxx:533
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Change cache operation mode to given mode.
Definition: RooAbsArg.cxx:1746
Bool_t addOwnedComponents(const RooArgSet &comps)
Take ownership of the contents of 'comps'.
Definition: RooAbsArg.cxx:2274
OperMode operMode() const
Definition: RooAbsArg.h:399
Bool_t observableOverlaps(const RooAbsData *dset, const RooAbsArg &testArg) const
Test if any of the dependents of the arg tree (as determined by getObservables) overlaps with those o...
Definition: RooAbsArg.cxx:809
Int_t getSize() const
virtual Bool_t addOwned(RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
RooFIter fwdIterator() const
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
Bool_t equals(const RooAbsCollection &otherColl) const
Check if this and other collection have identically named contents.
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
TIterator * createIterator(Bool_t dir=kIterForward) const
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
friend class CacheElem
Definition: RooAbsPdf.h:328
virtual void resetErrorCounters(Int_t resetValue=10)
Reset error counter to given value, limiting the number of future error messages for this pdf to 'res...
Definition: RooAbsPdf.cxx:569
TString _normRange
MC generator configuration specific for this object.
Definition: RooAbsPdf.h:353
Bool_t canBeExtended() const
Definition: RooAbsPdf.h:230
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:322
friend class RooRealIntegral
Definition: RooAbsPdf.h:308
Int_t _errorCount
Definition: RooAbsPdf.h:338
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:2855
RooArgSet * _normSet
Normalization integral (owned by _normMgr)
Definition: RooAbsPdf.h:316
static Int_t _verboseEval
Definition: RooAbsPdf.h:309
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
virtual Double_t getMax(const char *name=0) const
virtual Double_t getMin(const char *name=0) const
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=0) const
Variant of getAnalyticalIntegral that is also passed the normalization set that should be applied to ...
Definition: RooAbsReal.cxx:319
Bool_t isSelectedComp() const
If true, the current pdf is a selected component (for use in plotting)
virtual std::list< Double_t > * plotSamplingHint(RooAbsRealLValue &, Double_t, Double_t) const
Definition: RooAbsReal.h:280
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &, Double_t, Double_t) const
Definition: RooAbsReal.h:279
static void globalSelectComp(Bool_t flag)
Global switch controlling the activation of the selectComp() functionality.
Double_t getVal(const RooArgSet *set=0) const
Evaluate object. Returns either cached value or triggers a recalculation.
Definition: RooAbsReal.h:64
static Bool_t _globalSelectComp
Component selection flag for RooAbsPdf::plotCompOn.
Definition: RooAbsReal.h:482
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:502
virtual Bool_t isBinnedDistribution(const RooArgSet &) const
Definition: RooAbsReal.h:278
Transiet cache with transformed values of coefficients.
Definition: RooAddPdf.h:106
virtual RooArgList containedArgs(Action)
List all RooAbsArg derived contents in this cache element.
Definition: RooAddPdf.cxx:1167
RooArgList _rangeProjList
Definition: RooAddPdf.h:116
RooArgList _refRangeProjList
Definition: RooAddPdf.h:115
RooArgList _projList
Definition: RooAddPdf.h:113
RooArgList _suppNormList
Definition: RooAddPdf.h:108
RooArgList _suppProjList
Definition: RooAddPdf.h:114
RooAddPdf is an efficient implementation of a sum of PDFs of the form.
Definition: RooAddPdf.h:29
RooListProxy _coefList
Definition: RooAddPdf.h:134
virtual void resetErrorCounters(Int_t resetValue=10)
Reset error counter to given value, limiting the number of future error messages for this pdf to 'res...
Definition: RooAddPdf.cxx:867
Double_t * _coefCache
Definition: RooAddPdf.h:103
Bool_t _recursive
Definition: RooAddPdf.h:141
friend class RooAddGenContext
Definition: RooAddPdf.h:126
virtual void setCacheAndTrackHints(RooArgSet &)
Label OK'ed components of a RooAddPdf with cache-and-track.
Definition: RooAddPdf.cxx:1295
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return the number of expected events, which is either the sum of all coefficients or the sum of the c...
Definition: RooAddPdf.cxx:1049
RooAICRegistry _codeReg
Definition: RooAddPdf.h:131
Bool_t isBinnedDistribution(const RooArgSet &obs) const
If all components that depend on obs are binned that so is the product.
Definition: RooAddPdf.cxx:1278
Int_t _coefErrCount
Definition: RooAddPdf.h:143
Bool_t _allExtendable
Definition: RooAddPdf.h:140
virtual void selectNormalizationRange(const char *rangeName=0, Bool_t force=kFALSE)
Interface function used by test statistics to freeze choice of range for interpretation of fraction c...
Definition: RooAddPdf.cxx:1141
Double_t evaluate() const
Calculate and return the current value.
Definition: RooAddPdf.cxx:815
void updateCoefficients(CacheElem &cache, const RooArgSet *nset) const
Update the coefficient values in the given cache element: calculate new remainder fraction,...
Definition: RooAddPdf.cxx:679
virtual ~RooAddPdf()
Destructor.
Definition: RooAddPdf.cxx:368
CacheElem * getProjCache(const RooArgSet *nset, const RooArgSet *iset=0, const char *rangeName=0) const
Retrieve cache element with for calculation of p.d.f value with normalization set nset and integrated...
Definition: RooAddPdf.cxx:431
TIterator * _pdfIter
List of supplemental normalization factors.
Definition: RooAddPdf.h:136
TIterator * _coefIter
Iterator over PDF list.
Definition: RooAddPdf.h:137
RooObjCacheManager _projCacheMgr
Definition: RooAddPdf.h:121
void printMetaArgs(std::ostream &os) const
Customized printing of arguments of a RooAddPdf to more intuitively reflect the contents of the produ...
Definition: RooAddPdf.cxx:1313
RooAddPdf()
Default constructor used for persistence.
Definition: RooAddPdf.cxx:92
virtual std::list< Double_t > * plotSamplingHint(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi) const
Loop over components for plot sampling hints and merge them if there are multiple.
Definition: RooAddPdf.cxx:1183
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &, Double_t, Double_t) const
Loop over components for plot sampling hints and merge them if there are multiple.
Definition: RooAddPdf.cxx:1230
void fixCoefNormalization(const RooArgSet &refCoefNorm)
By default the interpretation of the fraction coefficients is performed in the contextual choice of o...
Definition: RooAddPdf.cxx:389
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE) const
Return specialized context to efficiently generate toy events from RooAddPdfs return RooAbsPdf::genCo...
Definition: RooAddPdf.cxx:1156
RooSetProxy _refCoefNorm
Definition: RooAddPdf.h:99
Double_t analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=0) const
Return analytical integral defined by given scenario code.
Definition: RooAddPdf.cxx:988
virtual void selectNormalization(const RooArgSet *depSet=0, Bool_t force=kFALSE)
Interface function used by test statistics to freeze choice of observables for interpretation of frac...
Definition: RooAddPdf.cxx:1118
void fixCoefRange(const char *rangeName)
By default the interpretation of the fraction coefficients is performed in the default range.
Definition: RooAddPdf.cxx:416
RooListProxy _pdfList
Registry of component analytical integration codes.
Definition: RooAddPdf.h:133
TNamed * _refCoefRangeName
Definition: RooAddPdf.h:100
const RooArgList & pdfList() const
Definition: RooAddPdf.h:68
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &numVars, const RooArgSet *normSet, const char *rangeName=0) const
Determine which part (if any) of given integral can be performed analytically.
Definition: RooAddPdf.cxx:911
Bool_t _projectCoefs
Definition: RooAddPdf.h:102
Bool_t _haveLastCoef
Iterator over coefficient list.
Definition: RooAddPdf.h:139
virtual Bool_t checkObservables(const RooArgSet *nset) const
Check if PDF is valid for given normalization set.
Definition: RooAddPdf.cxx:880
RooAbsArg * at(Int_t idx) const
Definition: RooArgList.h:84
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
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
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=0)
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:31
RooAbsArg * next()
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Reimplementation of standard RooArgList::add()
static const char * str(const TNamed *ptr)
Return C++ string corresponding to given TNamed pointer.
Definition: RooNameReg.cxx:135
static const TNamed * ptr(const char *stringPtr)
Return a unique TNamed pointer for given C++ string.
Definition: RooNameReg.cxx:125
static RooConstVar & value(Double_t value)
Return a constant value object with given value.
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:36
Class RooRecursiveFraction is a RooAbsReal implementation that calculates the plain fraction of sum o...
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Overloaded RooArgSet::add() method inserts 'var' into set and registers 'var' as server to owner with...
virtual void removeAll()
Remove all argument inset using remove(const RooAbsArg&).
Iterator abstract base class.
Definition: TIterator.h:30
virtual void Reset()=0
virtual TObject * Next()=0
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
const Int_t n
Definition: legend1.C:16
@ InputArguments
Definition: RooGlobalFunc.h:58
RooConstVar & RooConst(Double_t val)
static constexpr double pi
Definition: first.py:1
STL namespace.