1717#include < RooRealIntegral.h>
1818#include < RooRealVar.h>
1919
20+ // //////////////////////////////////////////////////////////////////////////////
21+ // / Create a RooAddPdf cache element for a given normalization set and
22+ // / projection configuration.
23+
2024AddCacheElem::AddCacheElem (RooAbsPdf const &addPdf, RooArgList const &pdfList, RooArgList const &coefList,
2125 const RooArgSet *nset, const RooArgSet *iset, const char *rangeName, bool projectCoefs,
2226 RooArgSet const &refCoefNorm, TNamed const *refCoefRangeName, int verboseEval)
@@ -110,12 +114,12 @@ AddCacheElem::AddCacheElem(RooAbsPdf const &addPdf, RooArgList const &pdfList, R
110114 << (refCoefRangeName ? RooNameReg::str (refCoefRangeName) : " " ) << std::endl;
111115
112116 // Recalculate projection integrals of PDFs
113- for (auto *thePdf : static_range_cast<const RooAbsPdf *>(pdfList)) {
117+ for (auto *pdf : static_range_cast<const RooAbsPdf *>(pdfList)) {
114118
115119 // Calculate projection integral
116120 std::unique_ptr<RooAbsReal> pdfProj;
117121 if (!nset2.equals (refCoefNorm)) {
118- pdfProj = std::unique_ptr<RooAbsReal>{thePdf ->createIntegral (nset2, refCoefNorm, addPdf.normRange ())};
122+ pdfProj = std::unique_ptr<RooAbsReal>{pdf ->createIntegral (nset2, refCoefNorm, addPdf.normRange ())};
119123 pdfProj->setOperMode (addPdf.operMode ());
120124 oocxcoutD (&addPdf, Caching) << addPdf.ClassName () << " (" << addPdf.GetName () << " )::getPC nset2(" << nset2
121125 << " )!=_refCoefNorm(" << refCoefNorm << " ) --> pdfProj = " << pdfProj->GetName ()
@@ -128,11 +132,11 @@ AddCacheElem::AddCacheElem(RooAbsPdf const &addPdf, RooArgList const &pdfList, R
128132
129133 // Calculation optional supplemental normalization term
130134 RooArgSet supNormSet (refCoefNorm);
131- auto deps = std::unique_ptr<RooArgSet>{thePdf ->getParameters (RooArgSet ())};
135+ auto deps = std::unique_ptr<RooArgSet>{pdf ->getParameters (RooArgSet ())};
132136 supNormSet.remove (*deps, true , true );
133137
134138 std::unique_ptr<RooAbsReal> snorm;
135- auto name = std::string (addPdf.GetName ()) + " _" + thePdf ->GetName () + " _ProjSupNorm" ;
139+ auto name = std::string (addPdf.GetName ()) + " _" + pdf ->GetName () + " _ProjSupNorm" ;
136140 if (!supNormSet.empty () && !nset2.equals (refCoefNorm)) {
137141 snorm = std::make_unique<RooRealIntegral>(name.c_str (), " Projection Supplemental normalization integral" ,
138142 RooRealConstant::value (1.0 ), supNormSet);
@@ -155,7 +159,7 @@ AddCacheElem::AddCacheElem(RooAbsPdf const &addPdf, RooArgList const &pdfList, R
155159
156160 // ----------
157161 RooArgSet tmpObs;
158- thePdf ->getObservables (&refCoefNorm, tmpObs);
162+ pdf ->getObservables (&refCoefNorm, tmpObs);
159163 bool allIdent = true ;
160164 for (auto *rvarg : dynamic_range_cast<RooRealVar *>(tmpObs)) {
161165 if (rvarg) {
@@ -170,9 +174,8 @@ AddCacheElem::AddCacheElem(RooAbsPdf const &addPdf, RooArgList const &pdfList, R
170174 if (refCoefRangeName && !refCoefNorm.empty () && !allIdent) {
171175
172176 RooArgSet tmp;
173- thePdf->getObservables (&refCoefNorm, tmp);
174- rangeProj1 =
175- std::unique_ptr<RooAbsReal>{thePdf->createIntegral (tmp, tmp, RooNameReg::str (refCoefRangeName))};
177+ pdf->getObservables (&refCoefNorm, tmp);
178+ rangeProj1 = std::unique_ptr<RooAbsReal>{pdf->createIntegral (tmp, tmp, RooNameReg::str (refCoefRangeName))};
176179
177180 // rangeProj1->setOperMode(operMode()) ;
178181 oocxcoutD (&addPdf, Caching) << " " << addPdf.ClassName () << " ::syncCoefProjList(" << addPdf.GetName ()
@@ -187,14 +190,14 @@ AddCacheElem::AddCacheElem(RooAbsPdf const &addPdf, RooArgList const &pdfList, R
187190 << " nset = " << (nset ? *nset : RooArgSet ()) << std::endl;
188191 if (rangeName && !refCoefNorm.empty ()) {
189192
190- rangeProj2 = std::unique_ptr<RooAbsReal>{thePdf ->createIntegral (refCoefNorm, refCoefNorm, rangeName)};
193+ rangeProj2 = std::unique_ptr<RooAbsReal>{pdf ->createIntegral (refCoefNorm, refCoefNorm, rangeName)};
191194 // rangeProj2->setOperMode(operMode()) ;
192195
193196 } else if (addPdf.normRange ()) {
194197
195198 RooArgSet tmp;
196- thePdf ->getObservables (&refCoefNorm, tmp);
197- rangeProj2 = std::unique_ptr<RooAbsReal>{thePdf ->createIntegral (tmp, tmp, addPdf.normRange ())};
199+ pdf ->getObservables (&refCoefNorm, tmp);
200+ rangeProj2 = std::unique_ptr<RooAbsReal>{pdf ->createIntegral (tmp, tmp, addPdf.normRange ())};
198201 oocxcoutD (&addPdf, Caching) << " " << addPdf.ClassName () << " ::syncCoefProjList(" << addPdf.GetName ()
199202 << " ) R2 = " << rangeProj2->GetName () << std::endl;
200203 }
@@ -230,15 +233,20 @@ RooArgList AddCacheElem::containedArgs(Action)
230233 return allNodes;
231234}
232235
233- void RooAddHelpers::updateCoefficients (RooAbsPdf const &addPdf, RooArgList const &pdfList, RooArgList const &coefList,
234- AddCacheElem &cache, const RooArgSet *nset, bool projectCoefs,
235- RooArgSet const &refCoefNorm, bool allExtendable, std::vector<double > &coefCache,
236- int &coefErrCount)
236+ // //////////////////////////////////////////////////////////////////////////////
237+ // / Update the RooAddPdf coefficients for a given normalization set and
238+ // / projection configuration. The `coefCache` argument should have the same
239+ // / size as `pdfList`. It needs to be initialized with the raw values of the
240+ // / coefficients, as obtained from the `_coefList` proxy in the RooAddPdf. If
241+ // / the last coefficient is not given, the initial value of the last element of
242+ // / `_coefCache` does not matter. After this function, the `_coefCache` will be
243+ // / filled with the correctly scaled coefficients for each pdf.
244+
245+ void RooAddHelpers::updateCoefficients (RooAbsPdf const &addPdf, std::vector<double > &coefCache,
246+ RooArgList const &pdfList, bool haveLastCoef, AddCacheElem &cache,
247+ const RooArgSet *nset, bool projectCoefs, RooArgSet const &refCoefNorm,
248+ bool allExtendable, int &coefErrCount)
237249{
238- bool haveLastCoef = pdfList.size () == coefList.size ();
239-
240- coefCache.resize (haveLastCoef ? coefList.size () : pdfList.size (), 0 .);
241-
242250 // Straight coefficients
243251 if (allExtendable) {
244252
@@ -265,38 +273,26 @@ void RooAddHelpers::updateCoefficients(RooAbsPdf const &addPdf, RooArgList const
265273 if (haveLastCoef) {
266274
267275 // coef[i] = coef[i] / SUM(coef)
268- double coefSum (0 );
269- std::size_t i = 0 ;
270- for (auto coefArg : coefList) {
271- auto coef = static_cast <RooAbsReal *>(coefArg);
272- coefCache[i] = coef->getVal (nset);
273- coefSum += coefCache[i++];
274- }
276+ double coefSum = std::accumulate (coefCache.begin (), coefCache.end (), 0.0 );
275277 if (coefSum == 0 .) {
276278 oocoutW (&addPdf, Eval) << addPdf.ClassName () << " ::updateCoefCache(" << addPdf.GetName ()
277279 << " ) WARNING: sum of coefficients is zero 0" << std::endl;
278280 } else {
279281 const double invCoefSum = 1 . / coefSum;
280- for (std::size_t j = 0 ; j < coefList .size (); j++) {
282+ for (std::size_t j = 0 ; j < coefCache .size (); j++) {
281283 coefCache[j] *= invCoefSum;
282284 }
283285 }
284286 } else {
285287
286288 // coef[i] = coef[i] ; coef[n] = 1-SUM(coef[0...n-1])
287- double lastCoef (1 );
288- std::size_t i = 0 ;
289- for (auto coefArg : coefList) {
290- auto coef = static_cast <RooAbsReal *>(coefArg);
291- coefCache[i] = coef->getVal (nset);
292- lastCoef -= coefCache[i++];
293- }
294- coefCache[coefList.size ()] = lastCoef;
289+ double lastCoef = 1.0 - std::accumulate (coefCache.begin (), coefCache.end () - 1 , 0.0 );
290+ coefCache.back () = lastCoef;
295291
296292 // Treat coefficient degeneration
297293 const float coefDegen = lastCoef < 0 . ? -lastCoef : (lastCoef > 1 . ? lastCoef - 1 . : 0 .);
298294 if (coefDegen > 1 .E -5 ) {
299- coefCache[coefList. size ()] = RooNaNPacker::packFloatIntoNaN (100 .f * coefDegen);
295+ coefCache. back () = RooNaNPacker::packFloatIntoNaN (100 .f * coefDegen);
300296
301297 std::stringstream msg;
302298 if (coefErrCount-- > 0 ) {
0 commit comments