Skip to content

Commit 7363049

Browse files
committed
[RF] Move updateCoefficients() from RooAddPdf/Model to RooAddHelpers
The same function was duplicated in RooAddPdf and RooAddModel, and it can therefore be moved into the new `RooAddHelpers` file.
1 parent 9240dc8 commit 7363049

File tree

7 files changed

+158
-256
lines changed

7 files changed

+158
-256
lines changed

roofit/roofitcore/inc/RooAbsReal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,6 +545,7 @@ class RooAbsReal : public RooAbsArg {
545545

546546
friend class RooRealSumPdf ;
547547
friend class RooRealSumFunc;
548+
friend class RooAddHelpers ;
548549
friend class RooAddPdf ;
549550
friend class RooAddModel ;
550551
void selectComp(bool flag) {

roofit/roofitcore/inc/RooAddModel.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ class RooAddModel : public RooResolutionModel {
3333
RooAddModel(const RooAddModel& other, const char* name=nullptr) ;
3434
TObject* clone(const char* newname) const override { return new RooAddModel(*this,newname) ; }
3535
RooResolutionModel* convolution(RooFormulaVar* basis, RooAbsArg* owner) const override ;
36-
~RooAddModel() override ;
3736

3837
double evaluate() const override ;
3938
bool checkObservables(const RooArgSet* nset) const override ;
@@ -93,10 +92,10 @@ class RooAddModel : public RooResolutionModel {
9392
void selectNormalizationRange(const char* rangeName=nullptr, bool force=false) override ;
9493

9594
mutable RooSetProxy _refCoefNorm ; ///<! Reference observable set for coefficient interpretation
96-
mutable TNamed* _refCoefRangeName ; ///<! Reference range name for coefficient interpretation
95+
mutable TNamed* _refCoefRangeName = nullptr; ///<! Reference range name for coefficient interpretation
9796

98-
bool _projectCoefs ; ///< If true coefficients need to be projected for use in evaluate()
99-
mutable double* _coefCache ; ///<! Transiet cache with transformed values of coefficients
97+
bool _projectCoefs = false; ///< If true coefficients need to be projected for use in evaluate()
98+
mutable std::vector<double> _coefCache; ///<! Transiet cache with transformed values of coefficients
10099

101100

102101
mutable RooObjCacheManager _projCacheMgr ; ///<! Manager of cache with coefficient projections and transformations
@@ -114,14 +113,14 @@ class RooAddModel : public RooResolutionModel {
114113

115114
mutable RooObjCacheManager _intCacheMgr ; ///<! Manager of cache with integrals
116115

117-
mutable RooAICRegistry _codeReg ; ///<! Registry of component analytical integration codes
116+
mutable RooAICRegistry _codeReg = 10; ///<! Registry of component analytical integration codes
118117

119118
RooListProxy _pdfList ; ///< List of component PDFs
120119
RooListProxy _coefList ; ///< List of coefficients
121120
mutable RooArgList* _snormList{nullptr}; ///<! List of supplemental normalization factors
122121

123-
bool _haveLastCoef ; ///< Flag indicating if last PDFs coefficient was supplied in the ctor
124-
bool _allExtendable ; ///< Flag indicating if all PDF components are extendable
122+
bool _haveLastCoef = false; ///< Flag indicating if last PDFs coefficient was supplied in the ctor
123+
bool _allExtendable = false; ///< Flag indicating if all PDF components are extendable
125124

126125
mutable Int_t _coefErrCount ; ///<! Coefficient error counter
127126

roofit/roofitcore/inc/RooAddPdf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class RooAddPdf : public RooAbsPdf {
101101
mutable TNamed* _refCoefRangeName = nullptr ; ///< Reference range name for coefficient interpreation
102102

103103
bool _projectCoefs = false; ///< If true coefficients need to be projected for use in evaluate()
104-
std::vector<double> _coefCache; ///<! Transient cache with transformed values of coefficients
104+
mutable std::vector<double> _coefCache; ///<! Transient cache with transformed values of coefficients
105105

106106

107107
mutable RooObjCacheManager _projCacheMgr ; //! Manager of cache with coefficient projections and transformations

roofit/roofitcore/src/RooAddHelpers.cxx

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <RooAbsPdf.h>
1414
#include <RooArgSet.h>
15+
#include <RooNaNPacker.h>
1516
#include <RooRealConstant.h>
1617
#include <RooRealIntegral.h>
1718
#include <RooRealVar.h>
@@ -239,3 +240,127 @@ RooArgList AddCacheElem::containedArgs(Action)
239240

240241
return allNodes;
241242
}
243+
244+
void RooAddHelpers::updateCoefficients(RooAbsPdf const &addPdf, RooArgList const &pdfList, RooArgList const &coefList,
245+
AddCacheElem &cache, const RooArgSet *nset, bool projectCoefs,
246+
RooArgSet const &refCoefNorm, bool allExtendable, std::vector<double> &coefCache,
247+
int &coefErrCount)
248+
{
249+
bool haveLastCoef = pdfList.size() == coefList.size();
250+
251+
coefCache.resize(haveLastCoef ? coefList.size() : pdfList.size(), 0.);
252+
253+
// Straight coefficients
254+
if (allExtendable) {
255+
256+
// coef[i] = expectedEvents[i] / SUM(expectedEvents)
257+
double coefSum(0);
258+
std::size_t i = 0;
259+
for (auto arg : pdfList) {
260+
auto pdf = static_cast<RooAbsPdf *>(arg);
261+
coefCache[i] = pdf->expectedEvents(!refCoefNorm.empty() ? &refCoefNorm : nset);
262+
coefSum += coefCache[i];
263+
i++;
264+
}
265+
266+
if (coefSum == 0.) {
267+
oocoutW(&addPdf, Eval) << addPdf.ClassName() << "::updateCoefCache(" << addPdf.GetName()
268+
<< ") WARNING: total number of expected events is 0" << std::endl;
269+
} else {
270+
for (std::size_t j = 0; j < pdfList.size(); j++) {
271+
coefCache[j] /= coefSum;
272+
}
273+
}
274+
275+
} else {
276+
if (haveLastCoef) {
277+
278+
// coef[i] = coef[i] / SUM(coef)
279+
double coefSum(0);
280+
std::size_t i = 0;
281+
for (auto coefArg : coefList) {
282+
auto coef = static_cast<RooAbsReal *>(coefArg);
283+
coefCache[i] = coef->getVal(nset);
284+
coefSum += coefCache[i++];
285+
}
286+
if (coefSum == 0.) {
287+
oocoutW(&addPdf, Eval) << addPdf.ClassName() << "::updateCoefCache(" << addPdf.GetName()
288+
<< ") WARNING: sum of coefficients is zero 0" << std::endl;
289+
} else {
290+
const double invCoefSum = 1. / coefSum;
291+
for (std::size_t j = 0; j < coefList.size(); j++) {
292+
coefCache[j] *= invCoefSum;
293+
}
294+
}
295+
} else {
296+
297+
// coef[i] = coef[i] ; coef[n] = 1-SUM(coef[0...n-1])
298+
double lastCoef(1);
299+
std::size_t i = 0;
300+
for (auto coefArg : coefList) {
301+
auto coef = static_cast<RooAbsReal *>(coefArg);
302+
coefCache[i] = coef->getVal(nset);
303+
lastCoef -= coefCache[i++];
304+
}
305+
coefCache[coefList.size()] = lastCoef;
306+
307+
// Treat coefficient degeneration
308+
const float coefDegen = lastCoef < 0. ? -lastCoef : (lastCoef > 1. ? lastCoef - 1. : 0.);
309+
if (coefDegen > 1.E-5) {
310+
coefCache[coefList.size()] = RooNaNPacker::packFloatIntoNaN(100.f * coefDegen);
311+
312+
std::stringstream msg;
313+
if (coefErrCount-- > 0) {
314+
msg << "RooAddPdf::updateCoefCache(" << addPdf.GetName()
315+
<< " WARNING: sum of PDF coefficients not in range [0-1], value=" << 1 - lastCoef;
316+
if (coefErrCount == 0) {
317+
msg << " (no more will be printed)";
318+
}
319+
oocoutW(&addPdf, Eval) << msg.str() << std::endl;
320+
}
321+
}
322+
}
323+
}
324+
325+
// Stop here if not projection is required or needed
326+
if ((!projectCoefs && !addPdf.normRange()) || cache._projList.empty()) {
327+
return;
328+
}
329+
330+
// Adjust coefficients for given projection
331+
double coefSum(0);
332+
{
333+
RooAbsReal::GlobalSelectComponentRAII compRAII(true);
334+
335+
for (std::size_t i = 0; i < pdfList.size(); i++) {
336+
337+
RooAbsReal *pp = ((RooAbsReal *)cache._projList.at(i));
338+
RooAbsReal *sn = ((RooAbsReal *)cache._suppProjList.at(i));
339+
RooAbsReal *r1 = ((RooAbsReal *)cache._refRangeProjList.at(i));
340+
RooAbsReal *r2 = ((RooAbsReal *)cache._rangeProjList.at(i));
341+
342+
double proj = pp->getVal() / sn->getVal() * (r2->getVal() / r1->getVal());
343+
344+
coefCache[i] *= proj;
345+
coefSum += coefCache[i];
346+
}
347+
}
348+
349+
if ((RooMsgService::_debugCount > 0) &&
350+
RooMsgService::instance().isActive(&addPdf, RooFit::Caching, RooFit::DEBUG)) {
351+
for (std::size_t i = 0; i < pdfList.size(); ++i) {
352+
ooccoutD(&addPdf, Caching) << " ALEX: POST-SYNC coef[" << i << "] = " << coefCache[i]
353+
<< " ( _coefCache[i]/coefSum = " << coefCache[i] * coefSum << "/" << coefSum
354+
<< " ) " << std::endl;
355+
}
356+
}
357+
358+
if (coefSum == 0.) {
359+
oocoutE(&addPdf, Eval) << addPdf.ClassName() << "::updateCoefCache(" << addPdf.GetName()
360+
<< ") sum of coefficients is zero." << std::endl;
361+
}
362+
363+
for (std::size_t i = 0; i < pdfList.size(); i++) {
364+
coefCache[i] /= coefSum;
365+
}
366+
}

roofit/roofitcore/src/RooAddHelpers.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,12 @@ class AddCacheElem : public RooAbsCacheElement {
3434
RooArgList _rangeProjList; ///< Range integrals to be multiplied with coefficients (target range)
3535
};
3636

37+
class RooAddHelpers {
38+
public:
39+
static void updateCoefficients(RooAbsPdf const &addPdf, RooArgList const &pdfList, RooArgList const &coefList,
40+
AddCacheElem &cache, const RooArgSet *nset, bool projectCoefs,
41+
RooArgSet const &refCoefNorm, bool allExtendable, std::vector<double> &coefCache,
42+
int &coefErrCount);
43+
};
44+
3745
#endif

0 commit comments

Comments
 (0)