27 std::string
const &refCoefNormRange,
int verboseEval)
41 fullDepList.
remove(*iset,
true,
true);
44 bool hasPdfWithCustomRange =
false;
47 for (std::size_t i = 0; i < pdfList.
size(); ++i) {
48 auto pdf =
static_cast<const RooAbsPdf *
>(pdfList.
at(i));
49 auto coef =
static_cast<const RooAbsReal *
>(coefList.
at(i));
51 hasPdfWithCustomRange |= pdf->normRange() !=
nullptr;
57 if (
auto pdfDeps = std::unique_ptr<RooArgSet>{pdf->getObservables(nset)}) {
58 supNSet.
remove(*pdfDeps,
true,
true);
62 if (
auto coefDeps = std::unique_ptr<RooArgSet>{coef ? coef->getObservables(nset) :
nullptr}) {
63 supNSet.
remove(*coefDeps,
true,
true);
66 std::unique_ptr<RooAbsReal> snorm;
67 auto name = std::string(addPdf.
GetName()) +
"_" + pdf->GetName() +
"_SupNorm";
68 if (!supNSet.
empty()) {
69 snorm = std::make_unique<RooRealIntegral>(
name.c_str(),
"Supplemental normalization integral",
72 <<
" making supplemental normalization set " << supNSet <<
" for pdf component "
76 if (!normRange.empty()) {
77 auto snormTerm = std::unique_ptr<RooAbsReal>(pdf->createIntegral(*nset, *nset, normRange.c_str()));
79 auto oldSnorm = std::move(snorm);
80 snorm = std::make_unique<RooProduct>(
"snorm",
"snorm", *oldSnorm.get(), *snormTerm.get());
81 snorm->addOwnedComponents(std::move(snormTerm), std::move(oldSnorm));
83 snorm = std::move(snormTerm);
89 if (verboseEval > 1) {
91 <<
") synching supplemental normalization list for norm"
92 << (nset ? *nset :
RooArgSet()) << std::endl;
97 const bool projectCoefsForRangeReasons = !refCoefNormRange.empty() || !normRange.empty() || hasPdfWithCustomRange;
100 if (refCoefNormSet.
empty() && !projectCoefsForRangeReasons) {
109 <<
")::getPC nset = " << (nset ? *nset :
RooArgSet()) <<
" nset2 = " << nset2
112 if (nset2.
empty() && !refCoefNormSet.
empty()) {
116 nset2.
add(refCoefNormSet);
119 if (!nset2.
equals(refCoefNormSet) || projectCoefsForRangeReasons) {
122 for (
auto *pdf : static_range_cast<const RooAbsPdf *>(pdfList)) {
125 std::unique_ptr<RooAbsReal> pdfProj;
126 if (!refCoefNormSet.
empty() && !nset2.
equals(refCoefNormSet)) {
127 pdfProj = std::unique_ptr<RooAbsReal>{pdf->createIntegral(nset2, refCoefNormSet, normRange.c_str())};
128 pdfProj->setOperMode(addPdf.
operMode());
130 <<
")!=_refCoefNormSet(" << refCoefNormSet
131 <<
") --> pdfProj = " << pdfProj->
GetName() << std::endl;
133 <<
") PP = " << pdfProj->GetName() << std::endl;
136 _projList.emplace_back(std::move(pdfProj));
140 auto deps = std::unique_ptr<RooArgSet>{pdf->getParameters(
RooArgSet())};
141 supNormSet.
remove(*deps,
true,
true);
143 std::unique_ptr<RooAbsReal> snorm;
144 auto name = std::string(addPdf.
GetName()) +
"_" + pdf->GetName() +
"_ProjSupNorm";
145 if (!supNormSet.
empty() && !nset2.
equals(refCoefNormSet)) {
146 snorm = std::make_unique<RooRealIntegral>(
name.c_str(),
"Projection Supplemental normalization integral",
149 <<
") SN = " << snorm->GetName() << std::endl;
154 std::unique_ptr<RooAbsReal> rangeProj2;
155 if (normRange != refCoefNormRange) {
157 pdf->getObservables(refCoefNormSet.
empty() ? nset : &refCoefNormSet, tmp);
158 auto int1 = std::unique_ptr<RooAbsReal>{pdf->createIntegral(tmp, tmp, normRange.c_str())};
159 auto int2 = std::unique_ptr<RooAbsReal>{pdf->createIntegral(tmp, tmp, refCoefNormRange.c_str())};
160 rangeProj2 = std::make_unique<RooRatio>(
"rangeProj",
"rangeProj", *int1, *int2);
161 rangeProj2->addOwnedComponents(std::move(int1), std::move(int2));
171 auto printVector = [](
auto const &
vec,
const char *
name) {
172 std::cout <<
"+++ " <<
name <<
":" << std::endl;
173 for (
auto const &arg :
vec) {
178 std::cout <<
"nullptr" << std::endl;
231 for (
auto arg : pdfList) {
232 auto pdf =
static_cast<RooAbsPdf *
>(arg);
234 coefSum += coefCache[i];
240 <<
") WARNING: total number of expected events is 0" << std::endl;
242 for (std::size_t j = 0; j < pdfList.
size(); j++) {
243 coefCache[j] /= coefSum;
251 double coefSum = std::accumulate(coefCache.begin(), coefCache.end(), 0.0);
254 <<
") WARNING: sum of coefficients is zero 0" << std::endl;
256 const double invCoefSum = 1. / coefSum;
257 for (std::size_t j = 0; j < coefCache.size(); j++) {
258 coefCache[j] *= invCoefSum;
264 double lastCoef = 1.0 - std::accumulate(coefCache.begin(), coefCache.end() - 1, 0.0);
265 coefCache.back() = lastCoef;
268 const float coefDegen = lastCoef < 0. ? -lastCoef : (lastCoef > 1. ? lastCoef - 1. : 0.);
269 if (coefDegen > 1.E-5) {
272 std::stringstream msg;
273 if (coefErrCount-- > 0) {
274 msg <<
"RooAddPdf::updateCoefCache(" << addPdf.
GetName()
275 <<
" WARNING: sum of PDF coefficients not in range [0-1], value=" << 1 - lastCoef;
276 if (coefErrCount == 0) {
277 msg <<
" (no more will be printed)";
279 oocoutW(&addPdf, Eval) << msg.str() << std::endl;
295 for (std::size_t i = 0; i < pdfList.
size(); i++) {
297 coefSum += coefCache[i];
303 for (std::size_t i = 0; i < pdfList.
size(); ++i) {
304 ooccoutD(&addPdf, Caching) <<
" ALEX: POST-SYNC coef[" << i <<
"] = " << coefCache[i]
305 <<
" ( _coefCache[i]/coefSum = " << coefCache[i] * coefSum <<
"/" << coefSum
306 <<
" ) " << std::endl;
312 <<
") sum of coefficients is zero." << std::endl;
315 for (std::size_t i = 0; i < pdfList.
size(); i++) {
316 coefCache[i] /= coefSum;
double projVal(std::size_t idx) const
OwningArgVector _projList
Projection integrals to be multiplied with coefficients.
AddCacheElem(RooAbsPdf const &addPdf, RooArgList const &pdfList, RooArgList const &coefList, const RooArgSet *nset, const RooArgSet *iset, RooArgSet const &refCoefNormSet, std::string const &refCoefNormRange, int verboseEval)
Create a RooAddPdf cache element for a given normalization set and projection configuration.
double projSuppNormVal(std::size_t idx) const
RooArgList containedArgs(Action) override
List all RooAbsArg derived contents in this cache element.
OwningArgVector _rangeProjList
Range integrals to be multiplied with coefficients (reference to target range)
double rangeProjScaleFactor(std::size_t idx) const
OwningArgVector _suppNormList
Supplemental normalization list.
bool doProjection() const
OwningArgVector _suppProjList
Projection integrals to multiply with coefficients for supplemental normalization.
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
OperMode operMode() const
Query the operation mode of this node.
bool equals(const RooAbsCollection &otherColl) const
Check if this and other collection have identically-named contents.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
const char * GetName() const override
Returns name of object.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
virtual double expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
const char * normRange() const
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
static void updateCoefficients(RooAbsPdf const &addPdf, std::vector< double > &coefCache, RooArgList const &pdfList, bool haveLastCoef, AddCacheElem &cache, const RooArgSet *nset, RooArgSet const &refCoefNormSet, bool allExtendable, int &coefErrCount)
Update the RooAddPdf coefficients for a given normalization set and projection configuration.
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
static RooMsgService & instance()
Return reference to singleton instance.
static RooConstVar & value(double value)
Return a constant value object with given value.
const char * GetName() const override
Returns name of object.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
__roodevice__ static __roohost__ double packFloatIntoNaN(float payload)
Pack float into mantissa of a NaN.