98 RooAddPdf::RooAddPdf() :
99 _refCoefNorm(
"!refCoefNorm",
"Reference coefficient normalization set",this,kFALSE,kFALSE),
100 _refCoefRangeName(0),
105 _coefErrCount = _errorCount ;
114 RooAddPdf::RooAddPdf(
const char *name,
const char *title) :
115 RooAbsPdf(name,title),
116 _refCoefNorm(
"!refCoefNorm",
"Reference coefficient normalization set",this,kFALSE,kFALSE),
117 _refCoefRangeName(0),
118 _projectCoefs(kFALSE),
119 _projCacheMgr(this,10),
121 _pdfList(
"!pdfs",
"List of PDFs",this),
122 _coefList(
"!coefficients",
"List of coefficients",this),
124 _haveLastCoef(kFALSE),
125 _allExtendable(kFALSE),
128 _coefErrCount = _errorCount ;
137 RooAddPdf::RooAddPdf(
const char *name,
const char *title,
138 RooAbsPdf& pdf1, RooAbsPdf& pdf2, RooAbsReal& coef1) :
139 RooAbsPdf(name,title),
140 _refCoefNorm(
"!refCoefNorm",
"Reference coefficient normalization set",this,kFALSE,kFALSE),
141 _refCoefRangeName(0),
142 _projectCoefs(kFALSE),
143 _projCacheMgr(this,10),
145 _pdfList(
"!pdfs",
"List of PDFs",this),
146 _coefList(
"!coefficients",
"List of coefficients",this),
147 _haveLastCoef(kFALSE),
148 _allExtendable(kFALSE),
153 _coefList.add(coef1) ;
155 _coefCache.resize(_pdfList.size());
156 _coefErrCount = _errorCount ;
173 RooAddPdf::RooAddPdf(
const char *name,
const char *title,
const RooArgList& inPdfList,
const RooArgList& inCoefList, Bool_t recursiveFractions) :
174 RooAbsPdf(name,title),
175 _refCoefNorm(
"!refCoefNorm",
"Reference coefficient normalization set",this,kFALSE,kFALSE),
176 _refCoefRangeName(0),
177 _projectCoefs(kFALSE),
178 _projCacheMgr(this,10),
180 _pdfList(
"!pdfs",
"List of PDFs",this),
181 _coefList(
"!coefficients",
"List of coefficients",this),
182 _haveLastCoef(kFALSE),
183 _allExtendable(kFALSE),
186 if (inPdfList.getSize()>inCoefList.getSize()+1 || inPdfList.getSize()<inCoefList.getSize()) {
187 coutE(InputArguments) <<
"RooAddPdf::RooAddPdf(" << GetName()
188 <<
") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1" << endl ;
192 if (recursiveFractions && inPdfList.getSize()!=inCoefList.getSize()+1) {
193 coutW(InputArguments) <<
"RooAddPdf::RooAddPdf(" << GetName()
194 <<
") WARNING inconsistent input: recursive fractions options can only be used if Npdf=Ncoef+1, ignoring recursive fraction setting" << endl ;
198 RooArgList partinCoefList ;
200 Bool_t first(kTRUE) ;
202 for (
auto i = 0u; i < inCoefList.size(); ++i) {
203 auto coef =
dynamic_cast<RooAbsReal*
>(inCoefList.at(i));
204 auto pdf =
dynamic_cast<RooAbsPdf*
>(inPdfList.at(i));
205 if (inPdfList.at(i) ==
nullptr) {
206 coutE(InputArguments) <<
"RooAddPdf::RooAddPdf(" << GetName()
207 <<
") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1" << endl ;
211 coutE(InputArguments) <<
"RooAddPdf::RooAddPdf(" << GetName() <<
") coefficient " << (coef ? coef->GetName() :
"") <<
" is not of type RooAbsReal, ignored" << endl ;
215 coutE(InputArguments) <<
"RooAddPdf::RooAddPdf(" << GetName() <<
") pdf " << (pdf ? pdf->GetName() :
"") <<
" is not of type RooAbsPdf, ignored" << endl ;
221 if (recursiveFractions) {
222 partinCoefList.add(*coef) ;
227 _coefList.add(*coef) ;
232 RooAbsReal* rfrac =
new RooRecursiveFraction(Form(
"%s_recursive_fraction_%s",GetName(),pdf->GetName()),
"Recursive Fraction",partinCoefList) ;
233 addOwnedComponents(*rfrac) ;
234 _coefList.add(*rfrac) ;
239 _coefList.add(*coef) ;
243 if (inPdfList.size() == inCoefList.size() + 1) {
244 auto pdf =
dynamic_cast<RooAbsPdf*
>(inPdfList.at(inCoefList.size()));
247 coutF(InputArguments) <<
"RooAddPdf::RooAddPdf(" << GetName() <<
") last pdf " << pdf->GetName() <<
" is not of type RooAbsPdf, fatal error" << endl ;
248 throw std::invalid_argument(
"Last argument for RooAddPdf is not a PDF.");
253 if (recursiveFractions) {
256 partinCoefList.add(RooFit::RooConst(1)) ;
257 RooAbsReal* rfrac =
new RooRecursiveFraction(Form(
"%s_recursive_fraction_%s",GetName(),pdf->GetName()),
"Recursive Fraction",partinCoefList) ;
258 addOwnedComponents(*rfrac) ;
259 _coefList.add(*rfrac) ;
262 _haveLastCoef=kTRUE ;
266 _haveLastCoef=kTRUE ;
270 _coefCache.resize(_pdfList.size());
271 _coefErrCount = _errorCount ;
272 _recursive = recursiveFractions ;
285 RooAddPdf::RooAddPdf(
const char *name,
const char *title,
const RooArgList& inPdfList) :
286 RooAbsPdf(name,title),
287 _refCoefNorm(
"!refCoefNorm",
"Reference coefficient normalization set",this,kFALSE,kFALSE),
288 _refCoefRangeName(0),
289 _projectCoefs(kFALSE),
290 _projCacheMgr(this,10),
291 _pdfList(
"!pdfs",
"List of PDFs",this),
292 _coefList(
"!coefficients",
"List of coefficients",this),
293 _haveLastCoef(kFALSE),
294 _allExtendable(kTRUE),
298 for (
const auto pdfArg : inPdfList) {
299 auto pdf =
dynamic_cast<const RooAbsPdf*
>(pdfArg);
302 coutE(InputArguments) <<
"RooAddPdf::RooAddPdf(" << GetName() <<
") pdf " << (pdf ? pdf->GetName() :
"") <<
" is not of type RooAbsPdf, ignored" << endl ;
305 if (!pdf->canBeExtended()) {
306 coutE(InputArguments) <<
"RooAddPdf::RooAddPdf(" << GetName() <<
") pdf " << pdf->GetName() <<
" is not extendable, ignored" << endl ;
312 _coefCache.resize(_pdfList.size());
313 _coefErrCount = _errorCount ;
323 RooAddPdf::RooAddPdf(
const RooAddPdf& other,
const char* name) :
324 RooAbsPdf(other,name),
325 _refCoefNorm(
"!refCoefNorm",this,other._refCoefNorm),
326 _refCoefRangeName((TNamed*)other._refCoefRangeName),
327 _projectCoefs(other._projectCoefs),
328 _projCacheMgr(other._projCacheMgr,this),
329 _codeReg(other._codeReg),
330 _pdfList(
"!pdfs",this,other._pdfList),
331 _coefList(
"!coefficients",this,other._coefList),
332 _haveLastCoef(other._haveLastCoef),
333 _allExtendable(other._allExtendable),
334 _recursive(other._recursive)
336 _coefCache.resize(_pdfList.size());
337 _coefErrCount = _errorCount ;
346 RooAddPdf::~RooAddPdf()
363 void RooAddPdf::fixCoefNormalization(
const RooArgSet& refCoefNorm)
365 if (refCoefNorm.getSize()==0) {
366 _projectCoefs = kFALSE ;
369 _projectCoefs = kTRUE ;
371 _refCoefNorm.removeAll() ;
372 _refCoefNorm.add(refCoefNorm) ;
374 _projCacheMgr.reset() ;
390 void RooAddPdf::fixCoefRange(
const char* rangeName)
392 _refCoefRangeName = (TNamed*)RooNameReg::ptr(rangeName) ;
393 if (_refCoefRangeName) _projectCoefs = kTRUE ;
409 RooAddPdf::CacheElem* RooAddPdf::getProjCache(
const RooArgSet* nset,
const RooArgSet* iset,
const char* rangeName)
const
413 CacheElem* cache = (CacheElem*) _projCacheMgr.getObj(nset,iset,0,rangeName) ;
419 cache =
new CacheElem ;
424 RooArgSet *fullDepList = getObservables(nset) ;
426 fullDepList->remove(*iset,kTRUE,kTRUE) ;
430 for (
int i = 0; i < _pdfList.getSize(); ++i) {
431 auto pdf =
static_cast<const RooAbsPdf *
>(_pdfList.at(i));
432 auto coef =
static_cast<const RooAbsReal*
>(_coefList.at(i));
435 RooArgSet supNSet(*fullDepList) ;
438 RooArgSet* pdfDeps = pdf->getObservables(nset) ;
440 supNSet.remove(*pdfDeps,kTRUE,kTRUE) ;
445 RooArgSet* coefDeps = coef ? coef->getObservables(nset) : 0 ;
447 supNSet.remove(*coefDeps,kTRUE,kTRUE) ;
452 TString name(GetName()) ;
454 name.Append(pdf->GetName()) ;
455 name.Append(
"_SupNorm") ;
456 cache->_needSupNorm = kFALSE ;
457 if (supNSet.getSize()>0) {
458 snorm =
new RooRealIntegral(name,
"Supplemental normalization integral",RooRealConstant::value(1.0),supNSet) ;
459 cxcoutD(Caching) <<
"RooAddPdf " << GetName() <<
" making supplemental normalization set " << supNSet <<
" for pdf component " << pdf->GetName() << endl ;
460 cache->_needSupNorm = kTRUE ;
462 snorm =
new RooRealVar(name,
"Unit Supplemental normalization integral",1.0) ;
464 cache->_suppNormList.addOwned(*snorm) ;
469 if (_verboseEval>1) {
470 cxcoutD(Caching) <<
"RooAddPdf::syncSuppNormList(" << GetName() <<
") synching supplemental normalization list for norm" << (nset?*nset:RooArgSet()) << endl ;
472 cache->_suppNormList.Print(
"v") ;
484 if (!_projectCoefs && !rangeName) {
485 _projCacheMgr.setObj(nset,iset,cache,RooNameReg::ptr(rangeName)) ;
494 RooArgSet* nset2 = nset ? getObservables(nset) : new RooArgSet() ;
495 cxcoutD(Caching) <<
"RooAddPdf(" << GetName() <<
")::getPC nset = " << (nset?*nset:RooArgSet()) <<
" nset2 = " << *nset2 << endl ;
497 if (nset2->getSize()==0 && _refCoefNorm.getSize()!=0) {
500 nset2->add(_refCoefNorm) ;
501 if (_refCoefRangeName) {
502 rangeName = RooNameReg::str(_refCoefRangeName) ;
508 if (!nset2->equals(_refCoefNorm) || _refCoefRangeName !=0 || rangeName !=0 || _normRange.Length()>0) {
510 cxcoutD(Caching) <<
"ALEX: RooAddPdf::syncCoefProjList(" << GetName() <<
") projecting coefficients from "
511 << *nset2 << (rangeName?
":":
"") << (rangeName?rangeName:
"")
512 <<
" to " << ((_refCoefNorm.getSize()>0)?_refCoefNorm:*nset2) << (_refCoefRangeName?
":":
"") << (_refCoefRangeName?RooNameReg::str(_refCoefRangeName):
"") << endl ;
515 for (
auto arg : _pdfList) {
516 auto thePdf =
static_cast<const RooAbsPdf*
>(arg);
519 RooAbsReal* pdfProj ;
520 if (!nset2->equals(_refCoefNorm)) {
521 pdfProj = thePdf->createIntegral(*nset2,_refCoefNorm,_normRange.Length()>0?_normRange.Data():0) ;
522 pdfProj->setOperMode(operMode()) ;
523 cxcoutD(Caching) <<
"RooAddPdf(" << GetName() <<
")::getPC nset2(" << *nset2 <<
")!=_refCoefNorm(" << _refCoefNorm <<
") --> pdfProj = " << pdfProj->GetName() << endl ;
525 TString name(GetName()) ;
527 name.Append(thePdf->GetName()) ;
528 name.Append(
"_ProjectNorm") ;
529 pdfProj =
new RooRealVar(name,
"Unit Projection normalization integral",1.0) ;
530 cxcoutD(Caching) <<
"RooAddPdf(" << GetName() <<
")::getPC nset2(" << *nset2 <<
")==_refCoefNorm(" << _refCoefNorm <<
") --> pdfProj = " << pdfProj->GetName() << endl ;
533 cache->_projList.addOwned(*pdfProj) ;
534 cxcoutD(Caching) <<
" RooAddPdf::syncCoefProjList(" << GetName() <<
") PP = " << pdfProj->GetName() << endl ;
537 RooArgSet supNormSet(_refCoefNorm) ;
538 RooArgSet* deps = thePdf->getParameters(RooArgSet()) ;
539 supNormSet.remove(*deps,kTRUE,kTRUE) ;
543 TString name(GetName()) ;
545 name.Append(thePdf->GetName()) ;
546 name.Append(
"_ProjSupNorm") ;
547 if (supNormSet.getSize()>0 && !nset2->equals(_refCoefNorm) ) {
548 snorm =
new RooRealIntegral(name,
"Projection Supplemental normalization integral",
549 RooRealConstant::value(1.0),supNormSet) ;
551 snorm =
new RooRealVar(name,
"Unit Projection Supplemental normalization integral",1.0) ;
553 cxcoutD(Caching) <<
" RooAddPdf::syncCoefProjList(" << GetName() <<
") SN = " << snorm->GetName() << endl ;
554 cache->_suppProjList.addOwned(*snorm) ;
557 RooAbsReal* rangeProj1 ;
568 RooArgSet* tmpObs = thePdf->getObservables(_refCoefNorm) ;
570 TIterator* iter = tmpObs->createIterator() ;
571 Bool_t allIdent = kTRUE ;
572 while((obsArg=(RooAbsArg*)iter->Next())) {
573 RooRealVar* rvarg =
dynamic_cast<RooRealVar*
>(obsArg) ;
575 if (rvarg->getMin(RooNameReg::str(_refCoefRangeName))!=rvarg->getMin() ||
576 rvarg->getMax(RooNameReg::str(_refCoefRangeName))!=rvarg->getMax()) {
585 if (_refCoefRangeName && _refCoefNorm.getSize()>0 && !allIdent) {
588 RooArgSet* tmp = thePdf->getObservables(_refCoefNorm) ;
589 rangeProj1 = thePdf->createIntegral(*tmp,*tmp,RooNameReg::str(_refCoefRangeName)) ;
596 TString theName(GetName()) ;
597 theName.Append(
"_") ;
598 theName.Append(thePdf->GetName()) ;
599 theName.Append(
"_RangeNorm1") ;
600 rangeProj1 =
new RooRealVar(theName,
"Unit range normalization integral",1.0) ;
603 cxcoutD(Caching) <<
" RooAddPdf::syncCoefProjList(" << GetName() <<
") R1 = " << rangeProj1->GetName() << endl ;
604 cache->_refRangeProjList.addOwned(*rangeProj1) ;
608 RooAbsReal* rangeProj2 ;
609 cxcoutD(Caching) <<
"RooAddPdf::syncCoefProjList(" << GetName() <<
") rangename = " << (rangeName?rangeName:
"<null>")
610 <<
" nset = " << (nset?*nset:RooArgSet()) << endl ;
611 if (rangeName && _refCoefNorm.getSize()>0) {
613 rangeProj2 = thePdf->createIntegral(_refCoefNorm,_refCoefNorm,rangeName) ;
616 }
else if (_normRange.Length()>0) {
618 RooArgSet* tmp = thePdf->getObservables(_refCoefNorm) ;
619 rangeProj2 = thePdf->createIntegral(*tmp,*tmp,_normRange.Data()) ;
624 TString theName(GetName()) ;
625 theName.Append(
"_") ;
626 theName.Append(thePdf->GetName()) ;
627 theName.Append(
"_RangeNorm2") ;
628 rangeProj2 =
new RooRealVar(theName,
"Unit range normalization integral",1.0) ;
631 cxcoutD(Caching) <<
" RooAddPdf::syncCoefProjList(" << GetName() <<
") R2 = " << rangeProj2->GetName() << endl ;
632 cache->_rangeProjList.addOwned(*rangeProj2) ;
640 _projCacheMgr.setObj(nset,iset,cache,RooNameReg::ptr(rangeName)) ;
652 void RooAddPdf::updateCoefficients(CacheElem& cache,
const RooArgSet* nset)
const
655 auto& myCoefCache =
const_cast<std::vector<double>&
>(_coefCache);
656 myCoefCache.resize(_haveLastCoef ? _coefList.size() : _pdfList.size(), 0.);
659 if (_allExtendable) {
662 Double_t coefSum(0) ;
664 for (
auto arg : _pdfList) {
665 auto pdf =
static_cast<RooAbsPdf*
>(arg);
666 myCoefCache[i] = pdf->expectedEvents(_refCoefNorm.getSize()>0?&_refCoefNorm:nset) ;
667 coefSum += myCoefCache[i] ;
672 coutW(Eval) <<
"RooAddPdf::updateCoefCache(" << GetName() <<
") WARNING: total number of expected events is 0" << endl ;
674 for (
int j=0; j < _pdfList.getSize(); j++) {
675 myCoefCache[j] /= coefSum ;
683 Double_t coefSum(0) ;
685 for (
auto coefArg : _coefList) {
686 auto coef =
static_cast<RooAbsReal*
>(coefArg);
687 myCoefCache[i] = coef->getVal(nset) ;
688 coefSum += myCoefCache[i++];
691 coutW(Eval) <<
"RooAddPdf::updateCoefCache(" << GetName() <<
") WARNING: sum of coefficients is zero 0" << endl ;
693 for (
int j=0; j < _coefList.getSize(); j++) {
694 myCoefCache[j] /= coefSum;
700 Double_t lastCoef(1) ;
702 for (
auto coefArg : _coefList) {
703 auto coef =
static_cast<RooAbsReal*
>(coefArg);
704 myCoefCache[i] = coef->getVal(nset) ;
706 lastCoef -= myCoefCache[i++];
708 myCoefCache[_coefList.getSize()] = lastCoef ;
713 if ((lastCoef<-1e-05 || (lastCoef-1)>1e-5) && _coefErrCount-->0) {
714 coutW(Eval) <<
"RooAddPdf::updateCoefCache(" << GetName()
715 <<
" WARNING: sum of PDF coefficients not in range [0-1], value="
717 if (_coefErrCount==0) {
718 coutW(Eval) <<
" (no more will be printed)" ;
720 coutW(Eval) << endl ;
730 if ((!_projectCoefs && _normRange.Length()==0) || cache._projList.getSize()==0) {
742 Double_t coefSum(0) ;
744 RooAbsReal::GlobalSelectComponentRAII compRAII(
true);
746 for (
int i = 0; i < _pdfList.getSize(); i++) {
748 RooAbsReal* pp = ((RooAbsReal*)cache._projList.at(i)) ;
749 RooAbsReal* sn = ((RooAbsReal*)cache._suppProjList.at(i)) ;
750 RooAbsReal* r1 = ((RooAbsReal*)cache._refRangeProjList.at(i)) ;
751 RooAbsReal* r2 = ((RooAbsReal*)cache._rangeProjList.at(i)) ;
753 Double_t proj = pp->getVal()/sn->getVal()*(r2->getVal()/r1->getVal()) ;
762 myCoefCache[i] *= proj ;
763 coefSum += myCoefCache[i] ;
768 if ((RooMsgService::_debugCount>0) && RooMsgService::instance().isActive(
this,RooFit::Caching,RooFit::DEBUG)) {
769 for (
int i=0; i < _pdfList.getSize(); ++i) {
770 ccoutD(Caching) <<
" ALEX: POST-SYNC coef[" << i <<
"] = " << myCoefCache[i]
771 <<
" ( _coefCache[i]/coefSum = " << myCoefCache[i]*coefSum <<
"/" << coefSum <<
" ) "<< endl ;
776 coutE(Eval) <<
"RooAddPdf::updateCoefCache(" << GetName() <<
") sum of coefficients is zero." << endl ;
779 for (
int i=0; i < _pdfList.getSize(); i++) {
780 myCoefCache[i] /= coefSum ;
787 std::pair<const RooArgSet*, RooAddPdf::CacheElem*> RooAddPdf::getNormAndCache()
const {
788 const RooArgSet* nset = _normSet ;
791 if (nset==0 || nset->getSize()==0) {
792 if (_refCoefNorm.getSize()!=0) {
793 nset = &_refCoefNorm ;
797 CacheElem* cache = getProjCache(nset) ;
798 updateCoefficients(*cache,nset) ;
800 return {nset, cache};
807 Double_t RooAddPdf::evaluate()
const
809 auto normAndCache = getNormAndCache();
810 const RooArgSet* nset = normAndCache.first;
811 CacheElem* cache = normAndCache.second;
817 for (
unsigned int i=0; i < _pdfList.size(); ++i) {
818 const auto& pdf =
static_cast<RooAbsPdf&
>(_pdfList[i]);
819 double snormVal = 1.;
820 if (cache->_needSupNorm) {
821 snormVal = ((RooAbsReal*)cache->_suppNormList.at(i))->getVal();
824 Double_t pdfVal = pdf.getVal(nset);
825 if (pdf.isSelectedComp()) {
826 value += pdfVal*_coefCache[i]/snormVal;
839 RooSpan<double> RooAddPdf::evaluateBatch(std::size_t begin, std::size_t batchSize)
const {
840 auto normAndCache = getNormAndCache();
841 const RooArgSet* nset = normAndCache.first;
842 CacheElem* cache = normAndCache.second;
845 auto output = _batchData.makeWritableBatchInit(begin, batchSize, 0.);
846 const std::size_t n = output.size();
849 for (
unsigned int pdfNo = 0; pdfNo < _pdfList.size(); ++pdfNo) {
850 const auto& pdf =
static_cast<RooAbsPdf&
>(_pdfList[pdfNo]);
851 auto pdfOutputs = pdf.getValBatch(begin, batchSize, nset);
852 assert(pdfOutputs.size() == output.size());
854 const double coef = _coefCache[pdfNo] / (cache->_needSupNorm ?
855 static_cast<RooAbsReal*
>(cache->_suppNormList.at(pdfNo))->getVal() :
858 if (pdf.isSelectedComp()) {
859 for (std::size_t i = 0; i < n; ++i) {
860 output[i] += pdfOutputs[i] * coef;
873 void RooAddPdf::resetErrorCounters(Int_t resetValue)
875 RooAbsPdf::resetErrorCounters(resetValue) ;
876 _coefErrCount = resetValue ;
886 Bool_t RooAddPdf::checkObservables(
const RooArgSet* nset)
const
890 for (
int i = 0; i < _pdfList.getSize(); ++i) {
891 auto pdf =
static_cast<const RooAbsPdf *
>(_pdfList.at(i));
892 auto coef =
static_cast<const RooAbsReal*
>(_coefList.at(i));
893 if (pdf->observableOverlaps(nset,*coef)) {
894 coutE(InputArguments) <<
"RooAddPdf::checkObservables(" << GetName() <<
"): ERROR: coefficient " << coef->GetName()
895 <<
" and PDF " << pdf->GetName() <<
" have one or more dependents in common" << endl ;
914 Int_t RooAddPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
915 const RooArgSet* normSet,
const char* rangeName)
const
918 RooArgSet* allDepVars = getObservables(allVars) ;
919 RooArgSet allAnalVars(*allDepVars) ;
925 for (
const auto pdfArg : _pdfList) {
926 auto pdf =
static_cast<const RooAbsPdf *
>(pdfArg);
927 RooArgSet subAnalVars ;
928 pdf->getAnalyticalIntegralWN(allVars,subAnalVars,normSet,rangeName) ;
931 for (
const auto arg : allVars) {
932 if (!subAnalVars.find(arg->GetName()) && pdf->dependsOn(*arg)) {
933 allAnalVars.remove(*arg,kTRUE,kTRUE) ;
940 if (allAnalVars.getSize()==0) {
947 std::vector<Int_t> subCode(_pdfList.getSize());
948 Bool_t allOK(kTRUE) ;
949 for (
const auto arg : _pdfList) {
950 auto pdf =
static_cast<const RooAbsPdf *
>(arg);
951 RooArgSet subAnalVars ;
952 RooArgSet* allAnalVars2 = pdf->getObservables(allAnalVars) ;
953 subCode[n] = pdf->getAnalyticalIntegralWN(*allAnalVars2,subAnalVars,normSet,rangeName) ;
954 if (subCode[n]==0 && allAnalVars2->getSize()>0) {
955 coutE(InputArguments) <<
"RooAddPdf::getAnalyticalIntegral(" << GetName() <<
") WARNING: component PDF " << pdf->GetName()
956 <<
" advertises inconsistent set of integrals (e.g. (X,Y) but not X or Y individually."
957 <<
" Distributed analytical integration disabled. Please fix PDF" << endl ;
960 delete allAnalVars2 ;
968 analVars.add(allAnalVars) ;
971 RooArgSet* intSet =
new RooArgSet(allAnalVars) ;
972 Int_t masterCode = _codeReg.store(subCode,intSet)+1 ;
982 Double_t RooAddPdf::analyticalIntegralWN(Int_t code,
const RooArgSet* normSet,
const char* rangeName)
const
986 return getVal(normSet) ;
991 const std::vector<Int_t>& subCode = _codeReg.retrieve(code-1,intSet) ;
992 if (subCode.empty()) {
993 coutE(InputArguments) <<
"RooAddPdf::analyticalIntegral(" << GetName() <<
"): ERROR unrecognized integration code, " << code << endl ;
997 cxcoutD(Caching) <<
"RooAddPdf::aiWN(" << GetName() <<
") calling getProjCache with nset = " << (normSet?*normSet:RooArgSet()) << endl ;
999 if ((normSet==0 || normSet->getSize()==0) && _refCoefNorm.getSize()>0) {
1001 normSet = &_refCoefNorm ;
1004 CacheElem* cache = getProjCache(normSet,intSet,0) ;
1005 updateCoefficients(*cache,normSet) ;
1014 RooArgList* snormSet = (cache->_suppNormList.getSize()>0) ? &cache->_suppNormList : 0 ;
1015 for (
int i = 0; i < _pdfList.getSize(); ++i ) {
1016 auto pdf =
static_cast<const RooAbsPdf*
>(_pdfList.at(i));
1018 if (_coefCache[i]) {
1019 snormVal = snormSet ? ((RooAbsReal*) cache->_suppNormList.at(i))->getVal() : 1.0 ;
1022 Double_t val = pdf->analyticalIntegralWN(subCode[i],normSet,rangeName) ;
1023 if (pdf->isSelectedComp()) {
1024 value += val*_coefCache[i]/snormVal ;
1039 Double_t RooAddPdf::expectedEvents(
const RooArgSet* nset)
const
1041 Double_t expectedTotal(0.0);
1043 cxcoutD(Caching) <<
"RooAddPdf::expectedEvents(" << GetName() <<
") calling getProjCache with nset = " << (nset?*nset:RooArgSet()) << endl ;
1044 CacheElem* cache = getProjCache(nset) ;
1045 updateCoefficients(*cache,nset) ;
1047 if (cache->_rangeProjList.getSize()>0) {
1049 RooFIter iter1 = cache->_refRangeProjList.fwdIterator() ;
1050 RooFIter iter2 = cache->_rangeProjList.fwdIterator() ;
1051 RooFIter iter3 = _pdfList.fwdIterator() ;
1053 if (_allExtendable) {
1056 while ((pdf=(RooAbsPdf*)iter3.next())) {
1057 RooAbsReal* r1 = (RooAbsReal*)iter1.next() ;
1058 RooAbsReal* r2 = (RooAbsReal*)iter2.next() ;
1059 expectedTotal += (r2->getVal()/r1->getVal()) * pdf->expectedEvents(nset) ;
1064 RooFIter citer = _coefList.fwdIterator() ;
1066 while((coef=(RooAbsReal*)citer.next())) {
1067 Double_t ncomp = coef->getVal(nset) ;
1068 RooAbsReal* r1 = (RooAbsReal*)iter1.next() ;
1069 RooAbsReal* r2 = (RooAbsReal*)iter2.next() ;
1070 expectedTotal += (r2->getVal()/r1->getVal()) * ncomp ;
1079 if (_allExtendable) {
1081 RooFIter iter = _pdfList.fwdIterator() ;
1083 while((pdf=(RooAbsPdf*)iter.next())) {
1084 expectedTotal += pdf->expectedEvents(nset) ;
1089 RooFIter citer = _coefList.fwdIterator() ;
1091 while((coef=(RooAbsReal*)citer.next())) {
1092 Double_t ncomp = coef->getVal(nset) ;
1093 expectedTotal += ncomp ;
1099 return expectedTotal ;
1108 void RooAddPdf::selectNormalization(
const RooArgSet* depSet, Bool_t force)
1111 if (!force && _refCoefNorm.getSize()!=0) {
1116 fixCoefNormalization(RooArgSet()) ;
1120 RooArgSet* myDepSet = getObservables(depSet) ;
1121 fixCoefNormalization(*myDepSet) ;
1131 void RooAddPdf::selectNormalizationRange(
const char* rangeName, Bool_t force)
1133 if (!force && _refCoefRangeName) {
1137 fixCoefRange(rangeName) ;
1146 RooAbsGenContext* RooAddPdf::genContext(
const RooArgSet &vars,
const RooDataSet *prototype,
1147 const RooArgSet* auxProto, Bool_t verbose)
const
1149 return new RooAddGenContext(*
this,vars,prototype,auxProto,verbose) ;
1157 RooArgList RooAddPdf::CacheElem::containedArgs(Action)
1159 RooArgList allNodes;
1160 allNodes.add(_projList) ;
1161 allNodes.add(_suppProjList) ;
1162 allNodes.add(_refRangeProjList) ;
1163 allNodes.add(_rangeProjList) ;
1173 std::list<Double_t>* RooAddPdf::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi)
const
1175 list<Double_t>* sumHint = 0 ;
1176 Bool_t needClean(kFALSE) ;
1179 for (
const auto arg : _pdfList) {
1180 auto pdf =
static_cast<const RooAbsPdf*
>(arg);
1182 list<Double_t>* pdfHint = pdf->plotSamplingHint(obs,xlo,xhi) ;
1193 list<Double_t>* newSumHint =
new list<Double_t>(sumHint->size()+pdfHint->size()) ;
1196 merge(pdfHint->begin(),pdfHint->end(),sumHint->begin(),sumHint->end(),newSumHint->begin()) ;
1200 sumHint = newSumHint ;
1207 list<Double_t>::iterator new_end = unique(sumHint->begin(),sumHint->end()) ;
1208 sumHint->erase(new_end,sumHint->end()) ;
1218 std::list<Double_t>* RooAddPdf::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi)
const
1220 list<Double_t>* sumBinB = 0 ;
1221 Bool_t needClean(kFALSE) ;
1224 for (
auto arg : _pdfList) {
1225 auto pdf =
static_cast<const RooAbsPdf *
>(arg);
1226 list<Double_t>* pdfBinB = pdf->binBoundaries(obs,xlo,xhi) ;
1237 list<Double_t>* newSumBinB =
new list<Double_t>(sumBinB->size()+pdfBinB->size()) ;
1240 merge(pdfBinB->begin(),pdfBinB->end(),sumBinB->begin(),sumBinB->end(),newSumBinB->begin()) ;
1245 sumBinB = newSumBinB ;
1253 list<Double_t>::iterator new_end = unique(sumBinB->begin(),sumBinB->end()) ;
1254 sumBinB->erase(new_end,sumBinB->end()) ;
1264 Bool_t RooAddPdf::isBinnedDistribution(
const RooArgSet& obs)
const
1266 for (
const auto arg : _pdfList) {
1267 auto pdf =
static_cast<const RooAbsPdf*
>(arg);
1268 if (pdf->dependsOn(obs) && !pdf->isBinnedDistribution(obs)) {
1280 void RooAddPdf::setCacheAndTrackHints(RooArgSet& trackNodes)
1282 RooFIter aiter = pdfList().fwdIterator() ;
1284 while ((aarg=aiter.next())) {
1285 if (aarg->canNodeBeCached()==Always) {
1286 trackNodes.add(*aarg) ;
1298 void RooAddPdf::printMetaArgs(ostream& os)
const
1300 Bool_t first(kTRUE) ;
1302 if (_coefList.getSize() != 0) {
1303 for (
int i = 0; i < _pdfList.getSize(); ++i ) {
1304 const RooAbsArg * coef = _coefList.at(i);
1305 const RooAbsArg * pdf = _pdfList.at(i);
1312 if (i < _coefList.getSize()) {
1313 os << coef->GetName() <<
" * " << pdf->GetName();
1315 os <<
"[%] * " << pdf->GetName();
1320 for (
const auto pdf : _pdfList) {
1326 os << pdf->GetName() ;