diff --git a/roofit/roofitcore/src/RooAddHelpers.cxx b/roofit/roofitcore/src/RooAddHelpers.cxx index c380fbe396248..4121819f4176c 100644 --- a/roofit/roofitcore/src/RooAddHelpers.cxx +++ b/roofit/roofitcore/src/RooAddHelpers.cxx @@ -223,67 +223,42 @@ RooArgList AddCacheElem::containedArgs(Action) /// `_coefCache` does not matter. After this function, the `_coefCache` will be /// filled with the correctly scaled coefficients for each pdf. -void RooAddHelpers::updateCoefficients(RooAbsPdf const &addPdf, std::vector &coefCache, - RooArgList const &pdfList, bool haveLastCoef, AddCacheElem &cache, - const RooArgSet *nset, RooArgSet const &refCoefNormSet, bool allExtendable, - int &coefErrCount) +void RooAddHelpers::updateCoefficients(RooAbsPdf const &addPdf, std::size_t nPdfs, std::vector &coefCache, + bool haveLastCoef, AddCacheElem &cache, int &coefErrCount) { // Straight coefficients - if (allExtendable) { - - // coef[i] = expectedEvents[i] / SUM(expectedEvents) - double coefSum(0); - std::size_t i = 0; - for (auto arg : pdfList) { - auto pdf = static_cast(arg); - coefCache[i] = pdf->expectedEvents(!refCoefNormSet.empty() ? &refCoefNormSet : nset); - coefSum += coefCache[i]; - i++; - } + if (haveLastCoef) { + // coef[i] = coef[i] / SUM(coef) + double coefSum = std::accumulate(coefCache.begin(), coefCache.end(), 0.0); if (coefSum == 0.) { oocoutW(&addPdf, Eval) << addPdf.ClassName() << "::updateCoefCache(" << addPdf.GetName() - << ") WARNING: total number of expected events is 0" << std::endl; + << ") WARNING: sum of coefficients is zero 0" << std::endl; } else { - for (std::size_t j = 0; j < pdfList.size(); j++) { - coefCache[j] /= coefSum; + const double invCoefSum = 1. / coefSum; + for (std::size_t j = 0; j < coefCache.size(); j++) { + coefCache[j] *= invCoefSum; } } - } else { - if (haveLastCoef) { - - // coef[i] = coef[i] / SUM(coef) - double coefSum = std::accumulate(coefCache.begin(), coefCache.end(), 0.0); - if (coefSum == 0.) { - oocoutW(&addPdf, Eval) << addPdf.ClassName() << "::updateCoefCache(" << addPdf.GetName() - << ") WARNING: sum of coefficients is zero 0" << std::endl; - } else { - const double invCoefSum = 1. / coefSum; - for (std::size_t j = 0; j < coefCache.size(); j++) { - coefCache[j] *= invCoefSum; - } - } - } else { - // coef[i] = coef[i] ; coef[n] = 1-SUM(coef[0...n-1]) - double lastCoef = 1.0 - std::accumulate(coefCache.begin(), coefCache.end() - 1, 0.0); - coefCache.back() = lastCoef; - - // Treat coefficient degeneration - const float coefDegen = lastCoef < 0. ? -lastCoef : (lastCoef > 1. ? lastCoef - 1. : 0.); - if (coefDegen > 1.E-5) { - coefCache.back() = RooNaNPacker::packFloatIntoNaN(100.f * coefDegen); - - std::stringstream msg; - if (coefErrCount-- > 0) { - msg << "RooAddPdf::updateCoefCache(" << addPdf.GetName() - << " WARNING: sum of PDF coefficients not in range [0-1], value=" << 1 - lastCoef; - if (coefErrCount == 0) { - msg << " (no more will be printed)"; - } - oocoutW(&addPdf, Eval) << msg.str() << std::endl; + // coef[i] = coef[i] ; coef[n] = 1-SUM(coef[0...n-1]) + double lastCoef = 1.0 - std::accumulate(coefCache.begin(), coefCache.end() - 1, 0.0); + coefCache.back() = lastCoef; + + // Treat coefficient degeneration + const float coefDegen = lastCoef < 0. ? -lastCoef : (lastCoef > 1. ? lastCoef - 1. : 0.); + if (coefDegen > 1.E-5) { + coefCache.back() = RooNaNPacker::packFloatIntoNaN(100.f * coefDegen); + + std::stringstream msg; + if (coefErrCount-- > 0) { + msg << "RooAddPdf::updateCoefCache(" << addPdf.GetName() + << " WARNING: sum of PDF coefficients not in range [0-1], value=" << 1 - lastCoef; + if (coefErrCount == 0) { + msg << " (no more will be printed)"; } + oocoutW(&addPdf, Eval) << msg.str() << std::endl; } } } @@ -295,14 +270,14 @@ void RooAddHelpers::updateCoefficients(RooAbsPdf const &addPdf, std::vector 0) && RooMsgService::instance().isActive(&addPdf, RooFit::Caching, RooFit::DEBUG)) { - for (std::size_t i = 0; i < pdfList.size(); ++i) { + for (std::size_t i = 0; i < nPdfs; ++i) { ooccoutD(&addPdf, Caching) << " ALEX: POST-SYNC coef[" << i << "] = " << coefCache[i] << " ( _coefCache[i]/coefSum = " << coefCache[i] * coefSum << "/" << coefSum << " ) " << std::endl; @@ -314,7 +289,7 @@ void RooAddHelpers::updateCoefficients(RooAbsPdf const &addPdf, std::vector &coefCache, RooArgList const &pdfList, - bool haveLastCoef, AddCacheElem &cache, const RooArgSet *nset, - RooArgSet const &refCoefNormSet, bool allExtendable, int &coefErrCount); + static void updateCoefficients(RooAbsPdf const &addPdf, std::size_t nPdfs, std::vector &coefCache, + bool haveLastCoef, AddCacheElem &cache, int &coefErrCount); }; #endif diff --git a/roofit/roofitcore/src/RooAddModel.cxx b/roofit/roofitcore/src/RooAddModel.cxx index a8a5443053e6e..2a33a9ea3a1c2 100644 --- a/roofit/roofitcore/src/RooAddModel.cxx +++ b/roofit/roofitcore/src/RooAddModel.cxx @@ -329,14 +329,21 @@ AddCacheElem* RooAddModel::getProjCache(const RooArgSet* nset, const RooArgSet* /// multiply the various range and dimensional corrections needed in the /// current use context. -void RooAddModel::updateCoefficients(AddCacheElem& cache, const RooArgSet* nset) const +void RooAddModel::updateCoefficients(AddCacheElem &cache, const RooArgSet *nset) const { - _coefCache.resize(_pdfList.size()); - for(std::size_t i = 0; i < _coefList.size(); ++i) { - _coefCache[i] = static_cast(_coefList[i]).getVal(nset); - } - RooAddHelpers::updateCoefficients(*this, _coefCache, _pdfList, _haveLastCoef, cache, nset, - _refCoefNorm, _allExtendable, _coefErrCount); + _coefCache.resize(_pdfList.size()); + for (std::size_t i = 0; i < _coefList.size(); ++i) { + _coefCache[i] = static_cast(_coefList[i]).getVal(nset); + } + if (_allExtendable) { + for (std::size_t i = 0; i < _pdfList.size(); ++i) { + auto &pdf = static_cast(_pdfList[i]); + _coefCache[i] = pdf.expectedEvents(!_refCoefNorm.empty() ? &_refCoefNorm : nset); + } + } + + RooAddHelpers::updateCoefficients(*this, _pdfList.size(), _coefCache, _haveLastCoef || _allExtendable, cache, + _coefErrCount); } diff --git a/roofit/roofitcore/src/RooAddPdf.cxx b/roofit/roofitcore/src/RooAddPdf.cxx index 96ec3c0acd79e..dd9b79629aeb3 100644 --- a/roofit/roofitcore/src/RooAddPdf.cxx +++ b/roofit/roofitcore/src/RooAddPdf.cxx @@ -439,16 +439,23 @@ AddCacheElem* RooAddPdf::getProjCache(const RooArgSet* nset, const RooArgSet* is /// need to be copied from the `_coefList` elements to /// the `_coefCache`. True by default. -void RooAddPdf::updateCoefficients(AddCacheElem& cache, const RooArgSet* nset, bool syncCoefValues) const +void RooAddPdf::updateCoefficients(AddCacheElem &cache, const RooArgSet *nset, bool syncCoefValues) const { - _coefCache.resize(_pdfList.size()); - if(syncCoefValues) { - for(std::size_t i = 0; i < _coefList.size(); ++i) { - _coefCache[i] = static_cast(_coefList[i]).getVal(nset); - } - } - RooAddHelpers::updateCoefficients(*this, _coefCache, _pdfList, _haveLastCoef, cache, nset, - _refCoefNorm, _allExtendable, _coefErrCount); + _coefCache.resize(_pdfList.size()); + if (syncCoefValues) { + for (std::size_t i = 0; i < _coefList.size(); ++i) { + _coefCache[i] = static_cast(_coefList[i]).getVal(nset); + } + } + if (_allExtendable) { + for (std::size_t i = 0; i < _pdfList.size(); ++i) { + auto &pdf = static_cast(_pdfList[i]); + _coefCache[i] = pdf.expectedEvents(!_refCoefNorm.empty() ? &_refCoefNorm : nset); + } + } + + RooAddHelpers::updateCoefficients(*this, _pdfList.size(), _coefCache, _haveLastCoef || _allExtendable, cache, + _coefErrCount); } ////////////////////////////////////////////////////////////////////////////////