101 _refCoefNorm(
"!refCoefNorm",
"Reference coefficient normalization set",this,false,false),
102 _projCacheMgr(this,10),
103 _pdfList(
"!pdfs",
"List of PDFs",this),
104 _coefList(
"!coefficients",
"List of coefficients",this),
105 _coefErrCount{_errorCount}
115 using PdfInfo = std::pair<std::string,RooAbsArg*>;
116 std::set<PdfInfo> seen;
118 PdfInfo elem{pdf->
GetName(), pdf};
119 auto comp = [&](PdfInfo
const&
p){
return p.first == elem.first &&
p.second != elem.second; };
120 auto found = std::find_if(seen.begin(), seen.end(), comp);
121 if(found != seen.end()) {
122 std::stringstream errorMsg;
123 errorMsg <<
"RooAddPdf::RooAddPdf(" <<
GetName()
124 <<
") pdf list contains pdfs with duplicate name \"" << pdf->GetName() <<
"\".";
125 coutE(InputArguments) << errorMsg.str() << std::endl;
126 throw std::invalid_argument(errorMsg.str().c_str());
160 bool recursiveFractions)
165 if (inPdfList.
size()>inCoefList.
size()+1 || inPdfList.
size()<inCoefList.
size()) {
166 std::stringstream errorMsg;
167 errorMsg <<
"RooAddPdf::RooAddPdf(" <<
GetName()
168 <<
") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1.";
169 coutE(InputArguments) << errorMsg.str() << std::endl;
170 throw std::invalid_argument(errorMsg.str().c_str());
173 if (recursiveFractions && inPdfList.
size()!=inCoefList.
size()+1) {
174 std::stringstream errorMsg;
175 errorMsg <<
"RooAddPdf::RooAddPdf(" <<
GetName()
176 <<
"): Recursive fractions option can only be used if Npdf=Ncoef+1.";
177 coutE(InputArguments) << errorMsg.str() << std::endl;
178 throw std::invalid_argument(errorMsg.str());
185 partinCoefList.
add(coef) ;
186 if(partinCoefList.
size() == 1) {
191 std::stringstream rfracName;
192 rfracName <<
GetName() <<
"_recursive_fraction_" << pdf.
GetName() <<
"_" << partinCoefList.
size();
193 auto rfrac = std::make_unique<RooRecursiveFraction>(rfracName.str().c_str(),
"Recursive Fraction",partinCoefList) ;
194 auto & rfracRef = *rfrac;
199 for (
auto i = 0u; i < inCoefList.
size(); ++i) {
200 auto coef =
dynamic_cast<RooAbsReal*
>(inCoefList.
at(i));
201 auto pdf =
dynamic_cast<RooAbsPdf*
>(inPdfList.
at(i));
202 if (inPdfList.
at(i) ==
nullptr) {
203 std::stringstream errorMsg;
204 errorMsg <<
"RooAddPdf::RooAddPdf(" <<
GetName()
205 <<
") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1";
206 coutE(InputArguments) << errorMsg.str() << std::endl;
207 throw std::invalid_argument(errorMsg.str());
210 std::stringstream errorMsg;
211 errorMsg <<
"RooAddPdf::RooAddPdf(" <<
GetName() <<
") coefficient " << (coef ? coef->GetName() :
"") <<
" is not of type RooAbsReal, ignored";
212 coutE(InputArguments) << errorMsg.str() << std::endl;
213 throw std::invalid_argument(errorMsg.str());
216 std::stringstream errorMsg;
217 errorMsg <<
"RooAddPdf::RooAddPdf(" <<
GetName() <<
") pdf " << (pdf ? pdf->
GetName() :
"") <<
" is not of type RooAbsPdf, ignored";
218 coutE(InputArguments) << errorMsg.str() << std::endl;
219 throw std::invalid_argument(errorMsg.str());
224 _coefList.
add(recursiveFractions ? addRecursiveCoef(*pdf, *coef) : *coef);
227 if (inPdfList.
size() == inCoefList.
size() + 1) {
231 coutE(InputArguments) <<
"RooAddPdf::RooAddPdf(" <<
GetName() <<
") last argument " << inPdfList.
at(inCoefList.
size())->
GetName() <<
" is not of type RooAbsPdf." << std::endl;
232 throw std::invalid_argument(
"Last argument for RooAddPdf is not a PDF.");
237 if (recursiveFractions) {
263 for (
const auto pdfArg : inPdfList) {
264 auto pdf =
dynamic_cast<const RooAbsPdf*
>(pdfArg);
267 std::stringstream errorMsg;
268 errorMsg <<
"RooAddPdf::RooAddPdf(" <<
GetName() <<
") pdf " << (pdf ? pdf->GetName() :
"")
269 <<
" is not of type RooAbsPdf, RooAddPdf constructor call is invalid!";
270 coutE(InputArguments) << errorMsg.str() << std::endl;
271 throw std::invalid_argument(errorMsg.str().c_str());
273 if (!pdf->canBeExtended()) {
274 std::stringstream errorMsg;
275 errorMsg <<
"RooAddPdf::RooAddPdf(" <<
GetName() <<
") pdf " << pdf->GetName()
276 <<
" is not extendable, RooAddPdf constructor call is invalid!";
277 coutE(InputArguments) << errorMsg.str() << std::endl;
278 throw std::invalid_argument(errorMsg.str().c_str());
292 _refCoefNorm(
"!refCoefNorm", this, other._refCoefNorm),
293 _refCoefRangeName((
TNamed *)other._refCoefRangeName),
294 _projCacheMgr(other._projCacheMgr, this),
295 _codeReg(other._codeReg),
296 _pdfList(
"!pdfs", this, other._pdfList),
297 _coefList(
"!coefficients", this, other._coefList),
298 _haveLastCoef(other._haveLastCoef),
299 _allExtendable(other._allExtendable),
300 _recursive(other._recursive),
301 _coefErrCount(_errorCount)
321 if (refCoefNorm.
empty()) {
351 std::vector<std::string> names;
362 for (std::string
const &
name : names) {
364 refCoefNorm.
add(*arg);
366 throw std::runtime_error(
"Internal logic error in RooAddPdf::materializeRefCoefNormFromAttribute()");
461 if(nset && nset->
empty()) nset =
nullptr;
463 if (nset ==
nullptr) {
488 if(nset ==
nullptr) {
496 if (nset ==
nullptr) {
497 coutW(Eval) <<
"Evaluating RooAddPdf " <<
GetName() <<
" without a defined normalization set. This can lead to ambiguous "
498 "coefficients definition and incorrect results."
499 <<
" Use RooAddPdf::fixCoefNormalization(nset) to provide a normalization set for "
500 "defining uniquely RooAddPdf coefficients!"
508 return {nset, cache};
523 bool nsetChanged(
false) ;
534 double snormVal = 1.;
537 double pdfVal = pdf.getVal(nset);
538 if (pdf.isSelectedComp()) {
568 if(coefVals.size() > 1) {
570 throw std::runtime_error(
"The RooAddPdf doesn't support per-event coefficients in CUDA mode yet!");
578 std::vector<std::span<const double>> pdfs;
579 std::vector<double> coefs;
585 for (
unsigned int pdfNo = 0; pdfNo <
_pdfList.
size(); ++pdfNo)
588 if (pdf->isSelectedComp())
590 pdfs.push_back(ctx.
at(pdf));
632 const RooArgSet* normSet,
const char* rangeName)
const
642 for (
const auto pdfArg :
_pdfList) {
643 auto pdf =
static_cast<const RooAbsPdf *
>(pdfArg);
645 pdf->getAnalyticalIntegralWN(allVars,subAnalVars,normSet,rangeName) ;
648 for (
const auto arg : allVars) {
649 if (!subAnalVars.
find(arg->GetName()) && pdf->
dependsOn(*arg)) {
650 allAnalVars.
remove(*arg,
true,
true) ;
657 if (allAnalVars.empty()) {
667 auto pdf =
static_cast<const RooAbsPdf *
>(arg);
669 auto allAnalVars2 = std::unique_ptr<RooArgSet>{pdf->getObservables(allAnalVars)} ;
670 subCode[
n] = pdf->getAnalyticalIntegralWN(*allAnalVars2,subAnalVars,normSet,rangeName) ;
671 if (subCode[
n]==0 && !allAnalVars2->empty()) {
672 coutE(InputArguments) <<
"RooAddPdf::getAnalyticalIntegral(" <<
GetName() <<
") WARNING: component PDF " << pdf->
GetName()
673 <<
" advertises inconsistent set of integrals (e.g. (X,Y) but not X or Y individually."
674 <<
" Distributed analytical integration disabled. Please fix PDF" << std::endl ;
684 analVars.
add(allAnalVars) ;
708 if (subCode.empty()) {
709 std::stringstream errorMsg;
710 errorMsg <<
"RooAddPdf::analyticalIntegral(" <<
GetName() <<
"): ERROR unrecognized integration code, " << code;
711 coutE(InputArguments) << errorMsg.str() << std::endl;
712 throw std::invalid_argument(errorMsg.str().c_str());
715 cxcoutD(Caching) <<
"RooAddPdf::aiWN(" <<
GetName() <<
") calling getProjCache with nset = " << (normSet?*normSet:
RooArgSet()) << std::endl ;
739 double val = pdf->analyticalIntegralWN(subCode[i],normSet,rangeName) ;
740 if (pdf->isSelectedComp()) {
758 double expectedTotal{0.0};
760 cxcoutD(Caching) <<
"RooAddPdf::expectedEvents(" <<
GetName() <<
") calling getProjCache with nset = " << (nset?*nset:
RooArgSet()) << std::endl ;
786 return expectedTotal ;
792 std::unique_ptr<RooAbsReal> out;
794 auto name = std::string(
GetName()) +
"_expectedEvents";
797 for (
auto *pdf : static_range_cast<RooAbsPdf *>(
_pdfList)) {
798 sumSet.
addOwned(pdf->createExpectedEventsFunc(nset));
800 out = std::make_unique<RooAddition>(
name.c_str(),
name.c_str(), sumSet);
801 out->addOwnedComponents(std::move(sumSet));
822 std::unique_ptr<RooAbsReal> owner;
830 for (
auto *pdf : static_range_cast<RooAbsPdf *>(
_pdfList)) {
831 auto next = std::unique_ptr<RooAbsReal>{pdf->createIntegral(*nset, *nset,
_normRange)};
834 next->addOwnedComponents(std::move(owner));
835 owner = std::move(next);
837 auto fracIntegName = std::string(
GetName()) +
"_integSum";
839 std::make_unique<RooRealSumFunc>(fracIntegName.c_str(), fracIntegName.c_str(),
_coefList, terms);
840 fracInteg->addOwnedComponents(std::move(owner));
842 out = std::move(fracInteg);
846 std::string finalName = std::string(out->GetName()) +
"_finalized";
847 if (prodList.
empty()) {
853 auto finalOut = std::make_unique<RooProduct>(finalName.c_str(), finalName.c_str(), prodList);
854 finalOut->addOwnedComponents(std::move(prodList));
902 const RooArgSet* auxProto,
bool verbose)
const
956 bool nameChange,
bool isRecursiveStep)
965std::unique_ptr<RooAbsArg>
971 auto newArg = std::unique_ptr<RooAbsReal>{
static_cast<RooAbsReal *
>(
Clone())};
1005 std::string finalName = std::string(
GetName()) +
"_conditional";
1006 std::unique_ptr<RooAbsReal> denom{newArg->createIntegral(normSet,
_refCoefNorm)};
1007 auto finalArg = std::make_unique<RooGenericPdf>(finalName.c_str(),
"@0/@1",
RooArgList{*newArg, *denom});
1012 finalArg->addOwnedComponents(std::move(newArg));
1013 finalArg->addOwnedComponents(std::move(denom));
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
double rangeProjScaleFactor(std::size_t idx) const
bool doProjection() const
double suppNormVal(std::size_t idx) const
const std::vector< Int_t > & retrieve(Int_t masterCode) const
Retrieve the array of integer codes associated with the given master code.
Int_t store(const std::vector< Int_t > &codeList, RooArgSet *set1=nullptr, RooArgSet *set2=nullptr, RooArgSet *set3=nullptr, RooArgSet *set4=nullptr)
Store given arrays of integer codes, and up to four RooArgSets in the registry (each setX pointer may...
Common abstract base class for objects that represent a value and a "shape" in RooFit.
void clearValueAndShapeDirty() const
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
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.
bool addOwnedComponents(const RooAbsCollection &comps)
Take ownership of the contents of 'comps'.
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
bool isValueDirty() const
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
Abstract container object that can hold multiple RooAbsArg objects.
bool equals(const RooAbsCollection &otherColl) const
Check if this and other collection have identically-named contents.
RooFit::UniqueId< RooAbsCollection > const & uniqueId() const
Returns a unique ID that is different for every instantiated RooAbsCollection.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
Storage_t const & get() const
Const access to the underlying stl container.
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
RooAbsArg * first() const
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for generator contexts of RooAbsPdf objects.
Abstract interface for all probability density functions.
virtual bool syncNormalization(const RooArgSet *dset, bool adjustProxies=true) const
Verify that the normalization integral cached with this PDF is valid for given set of normalization o...
virtual void resetErrorCounters(Int_t resetValue=10)
Reset error counter to given value, limiting the number of future error messages for this pdf to 'res...
bool isActiveNormSet(RooArgSet const *normSet) const
Checks if normSet is the currently active normalization set of this PDF, meaning is exactly the same ...
TString _normRange
Normalization range.
const char * normRange() const
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
The cache manager.
static Int_t _verboseEval
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Abstract base class for objects that represent a real value and implements functionality common to al...
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create an object that represents the integral of the function over one or more observables listed in ...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
double _value
Cache for current value of object.
virtual void doEval(RooFit::EvalContext &) const
Base function for computing multiple values of a RooAbsReal.
static std::unique_ptr< RooAbsGenContext > create(const Pdf_t &pdf, const RooArgSet &vars, const RooDataSet *prototype, const RooArgSet *auxProto, bool verbose)
Returns a RooAddGenContext if possible, or, if the RooAddGenContext doesn't support this particular R...
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.
Efficient implementation of a sum of PDFs of the form.
RooListProxy _coefList
List of coefficients.
bool _allExtendable
Flag indicating if all PDF components are extendable.
void doEval(RooFit::EvalContext &) const override
Compute addition of PDFs in batches.
RooAICRegistry _codeReg
! Registry of component analytical integration codes
RooFit::UniqueId< RooArgSet >::Value_t _idOfLastUsedNormSet
!
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Return analytical integral defined by given scenario code.
std::unique_ptr< const RooArgSet > _copyOfLastNormSet
!
void updateCoefficients(AddCacheElem &cache, const RooArgSet *nset, bool syncCoefValues=true) const
Update the coefficient values in the given cache element: calculate new remainder fraction,...
void translate(RooFit::Detail::CodeSquashContext &ctx) const override
This function defines a translation for each RooAbsReal based object that can be used to express the ...
Int_t _coefErrCount
! Coefficient error counter
void setRecursiveFraction(bool recursiveFraction)
bool _haveLastCoef
Flag indicating if last PDFs coefficient was supplied in the constructor.
void selectNormalization(const RooArgSet *depSet=nullptr, bool force=false) override
Interface function used by test statistics to freeze choice of observables for interpretation of frac...
void printMetaArgs(std::ostream &os) const override
Customized printing of arguments of a RooAddPdf to more intuitively reflect the contents of the produ...
void finalizeConstruction()
void setCacheAndTrackHints(RooArgSet &) override
Label OK'ed components of a RooAddPdf with cache-and-track.
RooObjCacheManager _projCacheMgr
void materializeRefCoefNormFromAttribute() const
RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool verbose=false) const override
Return specialized context to efficiently generate toy events from RooAddPdfs return RooAbsPdf::genCo...
bool checkObservables(const RooArgSet *nset) const override
Check if PDF is valid for given normalization set.
void fixCoefNormalization(const RooArgSet &refCoefNorm)
By default the interpretation of the fraction coefficients is performed in the contextual choice of o...
std::pair< const RooArgSet *, AddCacheElem * > getNormAndCache(const RooArgSet *nset) const
Look up projection cache and per-PDF norm sets.
RooSetProxy _refCoefNorm
Reference observable set for coefficient interpretation.
void selectNormalizationRange(const char *rangeName=nullptr, bool force=false) override
Interface function used by test statistics to freeze choice of range for interpretation of fraction c...
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &numVars, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Determine which part (if any) of given integral can be performed analytically.
void setAllExtendable(bool allExtendable)
void resetErrorCounters(Int_t resetValue=10) override
Reset error counter to given value, limiting the number of future error messages for this pdf to 'res...
double expectedEvents(const RooArgSet *nset) const override
Return expected number of events for extended likelihood calculation, which is the sum of all coeffic...
double getValV(const RooArgSet *set=nullptr) const override
Calculate and return the current value.
std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const override
void fixCoefRange(const char *rangeName)
By default, fraction coefficients are assumed to refer to the default fit range.
AddCacheElem * getProjCache(const RooArgSet *nset, const RooArgSet *iset=nullptr) const
Manager of cache with coefficient projections and transformations.
std::list< double > * plotSamplingHint(RooAbsRealLValue &obs, double xlo, double xhi) const override
Loop over components for plot sampling hints and merge them if there are multiple.
RooListProxy _pdfList
List of component PDFs.
TNamed * _refCoefRangeName
Reference range name for coefficient interpretation.
std::unique_ptr< RooAbsReal > createExpectedEventsFunc(const RooArgSet *nset) const override
Returns an object that represents the expected number of events for a given normalization set,...
bool isBinnedDistribution(const RooArgSet &obs) const override
If all components that depend on obs are binned, so is their sum.
bool redirectServersHook(const RooAbsCollection &, bool, bool, bool) override
The cache manager.
std::vector< double > _coefCache
! Transient cache with transformed values of coefficients
const RooArgSet & getCoefNormalization() const
std::list< double > * binBoundaries(RooAbsRealLValue &, double, double) const override
Loop over components for plot sampling hints and merge them if there are multiple.
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.
Minimal configuration struct to steer the evaluation of a single node with the RooBatchCompute librar...
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=nullptr)
Setter function without integration set.
void reset()
Clear the cache.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=nullptr, const TNamed *isetRangeName=nullptr)
Getter function without integration set.
void removeAll() override
Remove all argument inset using remove(const RooAbsArg&).
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
Container class to hold unbinned data.
A class to maintain the context for squashing of RooFit models into code.
void addResult(RooAbsArg const *key, std::string const &value)
A function to save an expression that includes/depends on the result of the input node.
void markAsCompiled(RooAbsArg &arg) const
void compileServers(RooAbsArg &arg, RooArgSet const &normSet)
std::span< const double > at(RooAbsArg const *arg, RooAbsArg const *caller=nullptr)
std::span< double > output()
RooBatchCompute::Config config(RooAbsArg const *arg) const
static const char * str(const TNamed *ptr)
Return C++ string corresponding to given TNamed pointer.
static const TNamed * ptr(const char *stringPtr)
Return a unique TNamed pointer for given C++ string.
void setCacheAndTrackHints(RooArgSet &) override
Label OK'ed components of a RooRealSumPdf with cache-and-track.
bool checkObservables(const RooArgSet *nset) const override
Check if FUNC is valid for given normalization set.
std::list< double > * plotSamplingHint(RooAbsRealLValue &, double, double) const override
Interface for returning an optional hint for initial sampling points when constructing a curve projec...
std::list< double > * binBoundaries(RooAbsRealLValue &, double, double) const override
Retrieve bin boundaries if this distribution is binned in obs.
void printMetaArgs(std::ostream &os) const override
Customized printing of arguments of a RooRealSumPdf to more intuitively reflect the contents of the p...
static std::string translateImpl(RooFit::Detail::CodeSquashContext &ctx, RooAbsArg const *klass, RooArgList const &funcList, RooArgList const &coefList, bool normalize=false)
bool isBinnedDistribution(const RooArgSet &obs) const override
Check if all components that depend on obs are binned.
The TNamed class is the base class for all named ROOT classes.
const char * GetName() const override
Returns name of object.
RooConstVar & RooConst(double val)
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
void compute(Config cfg, Computer comp, std::span< double > output, VarSpan vars, ArgSpan extraArgs={})
void getSortedComputationGraph(RooAbsArg const &func, RooArgSet &out)
std::string getColonSeparatedNameString(RooArgSet const &argSet, char delim=':')