75using std::endl, std::string, std::vector, std::list, std::ostream, std::map, std::ostringstream;
112 _pdfList(
"!pdfs",
"List of PDFs",this)
115 _pdfNSetList.emplace_back(std::make_unique<RooArgSet>(
"nset")) ;
121 _pdfNSetList.emplace_back(std::make_unique<RooArgSet>(
"nset")) ;
126 coutW(InputArguments) <<
"RooProdPdf::RooProdPdf(" <<
GetName()
127 <<
") multiple components with extended terms detected,"
128 <<
" product will not be extendable." << std::endl ;
159 _pdfList(
"!pdfs",
"List of PDFs",this)
206 _pdfList(
"!pdfs",
"List of PDFs",this)
229 _pdfList(
"!pdfList",
"List of PDFs",this)
248 _pdfList(
"!pdfs",
"List of PDFs",this)
260 _cacheMgr(other._cacheMgr,this),
261 _genCode(other._genCode),
262 _cutOff(other._cutOff),
263 _pdfList(
"!pdfs",this,other._pdfList),
264 _extendedIndex(other._extendedIndex),
265 _useDefaultGen(other._useDefaultGen),
266 _refRangeName(other._refRangeName),
267 _selfNorm(other._selfNorm),
268 _defNormSet(other._defNormSet)
271 for(
auto const& nset : other._pdfNSetList) {
272 _pdfNSetList.emplace_back(std::make_unique<RooArgSet>(nset->GetName()));
285 Int_t numExtended(0) ;
288 for(
auto const* pdf : static_range_cast<RooAbsPdf*>(fullPdfSet)) {
290 _pdfNSetList.emplace_back(std::make_unique<RooArgSet>(
"nset")) ;
292 if (pdf->canBeExtended()) {
300 for(
auto * carg : static_range_cast<RooCmdArg*>(
l)) {
302 if (0 == strcmp(carg->GetName(),
"Conditional")) {
304 Int_t argType = carg->getInt(0) ;
305 auto pdfSet =
static_cast<RooArgSet const*
>(carg->getSet(0));
306 auto normSet =
static_cast<RooArgSet const*
>(carg->getSet(1));
308 for(
auto * thePdf : static_range_cast<RooAbsPdf*>(*pdfSet)) {
311 _pdfNSetList.emplace_back(std::make_unique<RooArgSet>(0 == argType ?
"nset" :
"cset"));
314 if (thePdf->canBeExtended()) {
321 }
else if (0 != strlen(carg->GetName())) {
322 coutW(InputArguments) <<
"Unknown arg: " << carg->GetName() << std::endl ;
328 coutW(InputArguments) <<
"RooProdPdf::RooProdPdf(" <<
GetName()
329 <<
") WARNING: multiple components with extended terms detected,"
330 <<
" product will not be extendable." << std::endl ;
378 cxcoutD(Eval) <<
"RooProdPdf::calculate(" <<
GetName() <<
") rearranged product calculation"
392 const auto normSet = cache.
_normList[i].get();
394 const double piVal = partInt.getVal(!normSet->empty() ? normSet :
nullptr);
406void eraseNullptrs(std::vector<T*>&
v) {
407 v.erase(std::remove_if(
v.begin(),
v.end(), [](T*
x){ return x == nullptr; } ),
v.end());
410void removeCommon(std::vector<RooAbsArg*> &
v, std::span<RooAbsArg * const> other) {
412 for (
auto const& arg : other) {
413 auto namePtrMatch = [&arg](
const RooAbsArg* elm) {
414 return elm !=
nullptr && elm->namePtr() == arg->namePtr();
417 auto found = std::find_if(
v.begin(),
v.end(), namePtrMatch);
418 if(found !=
v.end()) {
425void addCommon(std::vector<RooAbsArg*> &
v, std::vector<RooAbsArg*>
const& o1, std::vector<RooAbsArg*>
const& o2) {
427 for (
auto const& arg : o1) {
428 auto namePtrMatch = [&arg](
const RooAbsArg* elm) {
429 return elm->namePtr() == arg->namePtr();
432 if(std::find_if(o2.begin(), o2.end(), namePtrMatch) != o2.end()) {
441 const char *range = normRange.
Length() > 0 ? normRange.
Data() :
nullptr;
444 if (normObs->getMin(range) != normObs->getMin(refRange) || normObs->getMax(range) != normObs->getMax(refRange))
459 std::vector<RooArgSet> depAllList;
460 std::vector<RooArgSet> depIntNoNormList;
467 std::vector<RooAbsArg*> pdfIntNoNormDeps;
468 std::vector<RooAbsArg*> pdfIntSet;
469 std::vector<RooAbsArg*> pdfNSet;
470 std::vector<RooAbsArg*> pdfCSet;
471 std::vector<RooAbsArg*> pdfNormDeps;
472 std::vector<RooAbsArg*> pdfAllDeps;
475 for(std::size_t iPdf = 0; iPdf <
_pdfList.
size(); ++iPdf) {
486 RooArgSet pdfLeafList(
"leafNodeServerList") ;
488 auto getObservablesOfCurrentPdf = [&pdfLeafList](
489 std::vector<RooAbsArg*> & out,
491 for (
const auto arg : pdfLeafList) {
492 if (arg->dependsOnValue(dataList) && arg->isLValue()) {
499 if (0 == strcmp(
"cset", pdfNSetOrig.GetName())) {
500 getObservablesOfCurrentPdf(pdfNSet, normSet);
501 removeCommon(pdfNSet, pdfNSetOrig.get());
502 pdfCSet = pdfNSetOrig.get();
505 getObservablesOfCurrentPdf(pdfNSet, pdfNSetOrig);
513 getObservablesOfCurrentPdf(pdfAllDeps, normSet);
517 if (!pdfNSet.empty()) {
519 addCommon(pdfNormDeps, pdfAllDeps, pdfNSet);
522 pdfNormDeps = pdfAllDeps;
526 getObservablesOfCurrentPdf(pdfIntSet, intSet) ;
529 if (pdfNormDeps.empty() && !pdfCSet.empty()) {
530 removeCommon(pdfIntSet, pdfCSet);
533 pdfIntNoNormDeps.clear();
534 pdfIntNoNormDeps = pdfIntSet;
535 removeCommon(pdfIntNoNormDeps, pdfNormDeps);
540 auto lIter = factorized.terms.begin();
541 auto ldIter = factorized.norms.begin();
542 for(;lIter != factorized.terms.end(); (++lIter, ++ldIter, ++j)) {
551 bool normOverlap = termNormDeps->
overlaps(pdfNormDeps.begin(), pdfNormDeps.end());
556 termNormDeps->
add(pdfNormDeps.begin(), pdfNormDeps.end(),
false);
557 depAllList[j].add(pdfAllDeps.begin(), pdfAllDeps.end(),
false);
559 termIntDeps->
add(pdfIntSet.begin(), pdfIntSet.end(),
false);
561 if (termIntNoNormDeps) {
562 termIntNoNormDeps->add(pdfIntNoNormDeps.begin(), pdfIntNoNormDeps.end(),
false);
564 termIntNoNormDeps->add(pdfIntNoNormDeps.begin(), pdfIntNoNormDeps.end(),
false);
571 if (!(pdfNormDeps.empty() && pdfAllDeps.empty() &&
572 pdfIntSet.empty()) || normSet.empty()) {
575 depAllList.emplace_back(pdfAllDeps.begin(), pdfAllDeps.end(),
"termAllDeps");
576 termIntDeps =
new RooArgSet(pdfIntSet.begin(), pdfIntSet.end(),
"termIntDeps");
577 depIntNoNormList.emplace_back(pdfIntNoNormDeps.begin(), pdfIntNoNormDeps.end(),
"termIntNoNormDeps");
578 termIntNoNormDeps = &depIntNoNormList.back();
581 termNormDeps->
add(pdfNormDeps.begin(), pdfNormDeps.end(),
false);
583 factorized.terms.Add(term);
584 factorized.norms.Add(termNormDeps);
585 factorized.ints.Add(termIntDeps);
594 auto lIter = factorized.terms.
begin();
595 auto ldIter = factorized.norms.begin();
596 for(;lIter != factorized.terms.end(); (++lIter, ++ldIter, ++i)) {
597 normDeps =
static_cast<RooArgSet*
>(*ldIter);
601 impDeps.remove(*normDeps,
true,
true);
604 factorized.imps.Add(snap);
608 auto crossDeps = std::unique_ptr<RooAbsCollection>{depIntNoNormList[i].
selectCommon(*normDeps)};
611 factorized.cross.Add(snap);
627 Int_t sterileIdx(-1);
633 std::unique_ptr<CacheElem> cache =
createCacheElem(nset, iset, isetRangeName);
643 const char* isetRangeName)
const
646 auto cache = std::make_unique<CacheElem>();
657 std::list<std::vector<RooArgSet*>> groupedList;
663 std::map<std::string, RooArgSet> ratioTerms;
664 for (
auto const&
group : groupedList) {
665 if (1 ==
group.size()) {
668 Int_t termIdx = factorized.terms.IndexOf(term);
680 std::ostringstream str; termImpSet.printValue(str);
681 ratioTerms[str.str()].addOwned(std::move(ratio));
686 for (
auto const& term :
group) {
688 Int_t termIdx = factorized.terms.IndexOf(term);
699 std::ostringstream str; termImpSet.printValue(str);
700 ratioTerms[str.str()].addOwned(std::move(ratio));
710 for (
auto const&
group : groupedList) {
711 for (
auto const& term :
group) {
712 Int_t termIdx = factorized.terms.IndexOf(term);
719 ostringstream str; termNSet.printValue(str);
720 if (!ratioTerms[str.str()].empty()) {
721 term->add(ratioTerms[str.str()]);
722 cache->_ownedList.addOwned(std::move(ratioTerms[str.str()]));
727 for (
auto const&
group : groupedList) {
728 if (1 ==
group.size()) {
731 Int_t termIdx = factorized.terms.IndexOf(term);
732 RooArgSet *norm = factorized.termNormDeps(termIdx);
733 RooArgSet *integ = factorized.termIntDeps(termIdx);
734 RooArgSet *xdeps = factorized.termCrossDeps(termIdx);
735 RooArgSet *imps = factorized.termImpDeps(termIdx);
747 cache->_partList.add(*func.x0);
748 if (func.isOwned) cache->_ownedList.addOwned(std::unique_ptr<RooAbsArg>{func.x0});
750 cache->_normList.emplace_back(std::make_unique<RooArgSet>());
751 norm->snapshot(*cache->_normList.back(),
false);
753 cache->_numList.addOwned(std::move(func.x1));
754 cache->_denList.addOwned(std::move(func.x2));
761 for (
auto const &term :
group) {
762 Int_t termIdx = factorized.terms.IndexOf(term);
763 RooArgSet *norm = factorized.termNormDeps(termIdx);
764 RooArgSet *integ = factorized.termIntDeps(termIdx);
765 RooArgSet *xdeps = factorized.termCrossDeps(termIdx);
766 RooArgSet *imps = factorized.termImpDeps(termIdx);
774 termISet.
remove(outerIntDeps,
true,
true);
776 auto func =
processProductTerm(nset, iset, isetRangeName, term, termNSet, termISet,
true);
778 compTermSet.add(*func.x0);
779 if (func.isOwned) cache->_ownedList.addOwned(std::unique_ptr<RooAbsArg>{func.x0});
780 compTermNorm.add(*norm,
false);
782 compTermNum.add(*func.x1.release());
783 compTermDen.add(*func.x2.release());
794 const std::string prodname =
makeRGPPName(
"SPECPROD", compTermSet, outerIntDeps,
RooArgSet(), isetRangeName);
795 auto prodtmp = std::make_unique<RooProduct>(prodname.c_str(), prodname.c_str(), compTermSet);
797 const std::string intname =
makeRGPPName(
"SPECINT", compTermSet, outerIntDeps,
RooArgSet(), isetRangeName);
798 auto inttmp = std::make_unique<RooRealIntegral>(intname.c_str(), intname.c_str(), *prodtmp, outerIntDeps,
nullptr,
nullptr, isetRangeName);
799 inttmp->setStringAttribute(
"PROD_TERM_TYPE",
"SPECINT");
801 cache->_partList.add(*inttmp);
805 auto prodtmp_num = std::make_unique<RooProduct>(prodname_num.c_str(), prodname_num.c_str(), compTermNum);
806 prodtmp_num->addOwnedComponents(compTermNum);
810 auto prodtmp_den = std::make_unique<RooProduct>(prodname_den.c_str(), prodname_den.c_str(), compTermDen);
811 prodtmp_den->addOwnedComponents(compTermDen);
814 std::string
name =
Form(
"SPEC_RATIO(%s,%s)", prodname_num.c_str(), prodname_den.c_str());
815 auto ndr = std::make_unique<RooFormulaVar>(
name.c_str(),
"@0/@1",
RooArgList(*prodtmp_num, *prodtmp_den));
818 std::unique_ptr<RooAbsReal> numtmp{ndr->createIntegral(outerIntDeps,isetRangeName)};
819 numtmp->addOwnedComponents(std::move(ndr));
821 cache->_ownedList.addOwned(std::move(prodtmp));
822 cache->_ownedList.addOwned(std::move(inttmp));
823 cache->_ownedList.addOwned(std::move(prodtmp_num));
824 cache->_ownedList.addOwned(std::move(prodtmp_den));
825 cache->_numList.addOwned(std::move(numtmp));
827 cache->_normList.emplace_back(std::make_unique<RooArgSet>());
828 compTermNorm.snapshot(*cache->_normList.back(),
false);
857 std::unique_ptr<RooAbsReal> ratio_num{pdf.
createIntegral(termNset,normRangeTmp)};
858 std::unique_ptr<RooAbsReal> ratio_den{pdf.
createIntegral(termNset,refRange)};
859 auto ratio = std::make_unique<RooFormulaVar>(
Form(
"ratio(%s,%s)",ratio_num->GetName(),ratio_den->GetName()),
"@0/@1",
862 ratio->addOwnedComponents(std::move(ratio_num));
863 ratio->addOwnedComponents(std::move(ratio_den));
864 ratio->setAttribute(
"RATIO_TERM") ;
879 std::map<std::string,RooArgSet> denListList ;
881 string specIntRange ;
894 if (
string(
"SPECINT")==part->getStringAttribute(
"PROD_TERM_TYPE")) {
897 auto specratio =
static_cast<RooFormulaVar const*
>(&orig->integrand()) ;
900 std::unique_ptr<RooArgSet> components{orig->
getComponents()};
902 if (carg->getAttribute(
"RATIO_TERM")) {
911 nomList.add(*cust.build()) ;
927 if (arg->getAttribute(
"RATIO_TERM")) {
930 origNumTerm.add(*arg) ;
936 nomList.add(origNumTerm) ;
943 for (
auto iter = rangeComps.begin() ; iter != rangeComps.end() ; ++iter) {
947 if (
string(
"SPECINT")==part->getStringAttribute(
"PROD_TERM_TYPE")) {
950 auto specRatio =
static_cast<RooFormulaVar const*
>(&orig->integrand()) ;
951 specIntDeps.add(orig->intVars()) ;
952 if (orig->intRange()) {
953 specIntRange = orig->intRange() ;
958 for (
auto* parg : static_range_cast<RooAbsReal*>(dentmp->components())) {
959 if (ratio && parg->dependsOn(*ratio)) {
971 RooCustomizer cust(*tmpadd->list1().first(), (
"blah_" + *iter).c_str());
972 cust.replaceArg(*ratio,*specializedRatio) ;
973 partCust = cust.build() ;
977 cust.replaceArg(*ratio, *specializedRatio);
978 partCust = cust.build();
986 string name =
Form(
"%s_divided_by_ratio",specializedPartCust->GetName()) ;
987 auto specIntFinal = std::make_unique<RooFormulaVar>(
name.c_str(),
"@0/@1",
RooArgList(*specializedPartCust,*specializedRatio)) ;
988 specIntFinal->addOwnedComponents(std::move(specializedPartCust));
989 specIntFinal->addOwnedComponents(std::move(specializedRatio));
991 denListList[*iter].addOwned(std::move(specIntFinal));
1007 tmp.add(*specRatio) ;
1009 auto specDenProd = std::make_unique<RooProduct>(pname.c_str(),pname.c_str(),tmp) ;
1010 std::unique_ptr<RooAbsReal> specInt;
1013 specInt = std::unique_ptr<RooAbsReal>{specDenProd->createIntegral((
static_cast<RooRealIntegral*
>(den))->intVars(),iter->c_str())};
1014 specInt->addOwnedComponents(std::move(specDenProd));
1018 specInt = std::unique_ptr<RooAbsReal>{specDenProd->
createIntegral(origInt->intVars(),iter->c_str())};
1019 specInt->addOwnedComponents(std::move(specDenProd));
1021 throw string(
"this should not happen") ;
1025 string name =
Form(
"%s_divided_by_ratio",specInt->GetName()) ;
1026 auto specIntFinal = std::make_unique<RooFormulaVar>(
name.c_str(),
"@0/@1",
RooArgList(*specInt,*specRatio)) ;
1027 specIntFinal->addOwnedComponents(std::move(specInt));
1028 specIntFinal->addOwnedComponents(std::move(specRatio));
1029 denListList[*iter].addOwned(std::move(specIntFinal));
1040 if (nomList.empty()) {
1044 string name = std::string{
GetName()} +
"_numerator";
1047 std::unique_ptr<RooAbsReal> numerator = std::make_unique<RooProduct>(
name.c_str(),
name.c_str(),nomList) ;
1050 for (map<string,RooArgSet>::iterator iter = denListList.begin() ; iter != denListList.end() ; ++iter) {
1054 prod_comp->addOwnedComponents(std::move(iter->second));
1055 products.add(*prod_comp) ;
1059 norm->addOwnedComponents(products) ;
1061 if (!specIntDeps.empty()) {
1064 string namesr =
Form(
"SPEC_RATIO(%s,%s)",numerator->GetName(),norm->GetName()) ;
1066 ndr->addOwnedComponents(std::move(numerator));
1069 numerator = std::unique_ptr<RooAbsReal>{ndr->createIntegral(specIntDeps,specIntRange.c_str())};
1093 std::unique_ptr<RooAbsReal> numint_spec{
specializeIntegral(*numint,targetRangeName)};
1095 std::unique_ptr<RooAbsReal> ret = std::make_unique<RooFormulaVar>(
Form(
"ratio(%s,%s)",numint_spec->GetName(),denint->GetName()),
"@0/@1",
RooArgList(*numint_spec,*denint)) ;
1096 ret->addOwnedComponents(std::move(numint_spec));
1111 return std::unique_ptr<RooAbsReal>{orig->
integrand().createIntegral(orig->intVars(),targetRangeName)};
1118 return std::unique_ptr<RooAbsReal>{origInt->
integrand().createIntegral(origInt->intVars(),targetRangeName)};
1121 std::stringstream errMsg;
1122 errMsg <<
"specializeIntegral: unknown input type " <<
input.ClassName() <<
"::" <<
input.GetName();
1123 throw std::runtime_error(errMsg.str());
1134 for(
auto * term : static_range_cast<RooArgSet*>(factorized.terms)) {
1135 groupedTerms.emplace_back();
1136 groupedTerms.back().emplace_back(term) ;
1141 for(
auto * impDeps : static_range_cast<RooArgSet*>(factorized.imps)) {
1142 allImpDeps.
add(*impDeps,
false) ;
1147 for(
auto * intDeps : static_range_cast<RooArgSet*>(factorized.ints)) {
1148 allIntDeps.
add(*intDeps,
false) ;
1151 outerIntDeps.removeAll() ;
1152 outerIntDeps.add(*std::unique_ptr<RooArgSet>{allIntDeps.selectCommon(allImpDeps)});
1155 for(
RooAbsArg * outerIntDep : outerIntDeps) {
1158 std::vector<RooArgSet*>* newGroup = nullptr ;
1161 bool needMerge = false ;
1162 auto group = groupedTerms.begin();
1163 auto nGroups = groupedTerms.size();
1164 for (
size_t iGroup = 0; iGroup < nGroups; ++iGroup) {
1167 for (
auto const& term2 : *
group) {
1169 Int_t termIdx = factorized.terms.IndexOf(term2) ;
1170 if (factorized.termNormDeps(termIdx)->contains(*outerIntDep) ||
1171 factorized.termIntDeps(termIdx)->contains(*outerIntDep) ||
1172 factorized.termImpDeps(termIdx)->contains(*outerIntDep)) {
1180 if (newGroup==
nullptr) {
1181 groupedTerms.emplace_back() ;
1182 newGroup = &groupedTerms.back() ;
1186 for (
auto& term2 : *
group) {
1187 newGroup->emplace_back(term2) ;
1208 bool forceWrap)
const
1215 if (!termNSet.empty() && termNSet.size()==termISet.size() && isetRangeName==
nullptr) {
1222 if (nset && termNSet.
empty()) {
1227 if (iset && !termISet.empty()) {
1228 if (term->size()==1) {
1235 ret.x0 = std::unique_ptr<RooAbsReal>{pdf->
createIntegral(termISet,termNSet,isetRangeName)}.release();
1237 ret.x0->setStringAttribute(
"PROD_TERM_TYPE",
"IIIa") ;
1242 ret.x1 = std::unique_ptr<RooAbsReal>{pdf->
createIntegral(termISet,isetRangeName)};
1253 const std::string
name =
makeRGPPName(
"GENPROJ_",*term,termISet,termNSet,isetRangeName) ;
1254 ret.x0 =
new RooGenProdProj(
name.c_str(),
name.c_str(),*term,termISet,termNSet,isetRangeName) ;
1255 ret.x0->setStringAttribute(
"PROD_TERM_TYPE",
"IIIb") ;
1265 ret.x1 = std::unique_ptr<RooAbsReal>{tmp_prod->createIntegral(termISet,isetRangeName)};
1266 ret.x2 = std::unique_ptr<RooAbsReal>{tmp_prod->createIntegral(termNSet,
normRange())};
1274 if (nset && !nset->
empty() && term->size()>1) {
1277 const std::string
name =
makeRGPPName(
"GENPROJ_",*term,termISet,termNSet,isetRangeName) ;
1278 ret.x0 =
new RooGenProdProj(
name.c_str(),
name.c_str(),*term,termISet,termNSet,isetRangeName,
normRange()) ;
1281 ret.x0->setStringAttribute(
"PROD_TERM_TYPE",
"IVa") ;
1291 ret.x1 = std::unique_ptr<RooAbsReal>{tmp_prod->createIntegral(termISet,isetRangeName)};
1292 ret.x2 = std::unique_ptr<RooAbsReal>{tmp_prod->createIntegral(termNSet,
normRange())};
1299 for (
auto* pdf : static_range_cast<RooAbsPdf*>(*term)) {
1301 ret.isOwned =
false;
1312 ret0->setStringAttribute(
"PROD_TERM_TYPE",
"IVb") ;
1314 ret.x1 = std::unique_ptr<RooAbsReal>{pdf->createIntegral(
RooArgSet())};
1315 ret.x2 = std::unique_ptr<RooAbsReal>{pdf->createIntegral(termNSet,
normRange())};
1319 coutE(Eval) <<
"RooProdPdf::processProductTerm(" <<
GetName() <<
") unidentified term!!!" << std::endl ;
1330 const RooArgSet& nset,
const char* isetRangeName)
const
1334 std::ostringstream os;
1340 for (
auto const* pdf : static_range_cast<RooAbsPdf*>(term)) {
1341 if (!first) os <<
"_X_";
1343 os << pdf->GetName();
1378 const RooArgSet* normSet,
const char* rangeName)
const
1383 analVars.add(allVars) ;
1411 if (cache==
nullptr) {
1448 coutF(Generation) <<
"Requesting expected number of events from a RooProdPdf that does not contain an extended p.d.f" << std::endl ;
1449 throw std::logic_error(std::string(
"RooProdPdf ") +
GetName() +
" could not be extended.");
1458 coutF(Generation) <<
"Requesting expected number of events from a RooProdPdf that does not contain an extended p.d.f" << std::endl ;
1459 throw std::logic_error(std::string(
"RooProdPdf ") +
GetName() +
" could not be extended.");
1470 const RooArgSet* auxProto,
bool verbose)
const
1488 for (
auto const* arg : directVars) {
1494 std::vector<Int_t> code;
1496 for (
auto const* pdf : static_range_cast<RooAbsPdf*>(
_pdfList)) {
1498 Int_t pdfCode = pdf->getGenerator(directSafe,pdfDirect,staticInitOK);
1499 code.push_back(pdfCode);
1501 generateVars.add(pdfDirect) ;
1506 if (!generateVars.empty()) {
1511 return std::distance(
_genCode.begin(), found) + 1;
1513 _genCode.emplace_back(std::move(code));
1529 const std::vector<int>& codeList =
_genCode[code-1];
1531 for (
auto* pdf : static_range_cast<RooAbsPdf*>(
_pdfList)) {
1532 if (codeList[i]!=0) {
1533 pdf->initGenerator(codeList[i]) ;
1550 const std::vector<Int_t>& codeList =
_genCode[code-1];
1552 for (
auto* pdf : static_range_cast<RooAbsPdf*>(
_pdfList)) {
1553 if (codeList[i]!=0) {
1554 pdf->generateEvent(codeList[i]) ;
1568 ret.
add(_partList) ;
1571 if (_rearrangedNum) ret.add(*_rearrangedNum) ;
1572 if (_rearrangedDen) ret.add(*_rearrangedDen) ;
1585 os <<
indent <<
"RooProdPdf begin partial integral cache" << std::endl ;
1588 auto indent2 = std::string(
indent) +
"[" + std::to_string(curElem) +
"]";
1589 for(
auto const& arg : _partList) {
1590 arg->printCompactTree(os,indent2.c_str()) ;
1593 if (curElem==maxElem) {
1594 os <<
indent <<
"RooProdPdf end partial integral cache" << std::endl ;
1611 for (
auto* pdf : static_range_cast<RooAbsPdf*>(
_pdfList)) {
1613 if (pdf->dependsOn(arg)) {
1617 if (thePdf)
return false ;
1623 return thePdf?(thePdf->isDirectGenSafe(arg)):false ;
1644 for(
auto arg : pdfs) {
1647 coutW(InputArguments) <<
"RooProdPdf::addPdfs(" <<
GetName() <<
") list arg "
1648 << arg->GetName() <<
" is not a PDF, ignored" << std::endl ;
1659 _pdfNSetList.emplace_back(std::make_unique<RooArgSet>(
"nset"));
1663 if (numExtended>1) {
1664 coutW(InputArguments) <<
"RooProdPdf::addPdfs(" <<
GetName()
1665 <<
") WARNING: multiple components with extended terms detected,"
1666 <<
" product will not be extendable." << std::endl ;
1706 std::vector<TNamed const*> ptrs;
1707 ptrs.reserve(col.size());
1709 ptrs.push_back(arg->namePtr());
1711 std::sort(ptrs.begin(), ptrs.end());
1715bool sortedNamePtrsOverlap(std::vector<TNamed const*>
const& ptrsA, std::vector<TNamed const*>
const& ptrsB)
1717 auto pA = ptrsA.begin();
1718 auto pB = ptrsB.begin();
1719 while (pA != ptrsA.end() && pB != ptrsB.end()) {
1722 }
else if (*pB < *pA) {
1742std::unique_ptr<RooArgSet>
1745 auto constraints = std::make_unique<RooArgSet>(
"constraints");
1748 auto observablesNamePtrs = sortedNamePtrs(observables);
1749 auto constrainedParamsNamePtrs = sortedNamePtrs(constrainedParams);
1752 for (std::size_t iPdf = 0; iPdf <
_pdfList.
size(); ++iPdf) {
1756 pdf->getParameters(
nullptr, tmp);
1761 bool isConstraint =
false;
1764 auto tmpNamePtrs = sortedNamePtrs(tmp);
1776 isConstraint = !sortedNamePtrsOverlap(tmpNamePtrs, observablesNamePtrs) &&
1777 sortedNamePtrsOverlap(tmpNamePtrs, constrainedParamsNamePtrs);
1780 constraints->add(*pdf) ;
1787 tmp.remove(observables,
false,
true);
1788 pdfParams.add(tmp,
true) ;
1807 for (std::size_t iPdf = 0; iPdf <
_pdfList.
size(); ++iPdf) {
1812 if (
static_cast<int>(iPdf) ==
_extendedIndex || pdf->dependsOn(observables)) {
1814 pdf->getParameters(&observables, tmp);
1815 connectedPars->
add(tmp) ;
1818 return connectedPars ;
1851 for (
auto const* pdf : static_range_cast<RooAbsPdf*>(
_pdfList)) {
1852 if (std::list<double>* hint = pdf->plotSamplingHint(obs,xlo,xhi)) {
1867 for (
auto const* pdf : static_range_cast<RooAbsPdf*>(
_pdfList)) {
1868 if (pdf->dependsOn(obs) && !pdf->isBinnedDistribution(obs)) {
1886 for (
auto const* pdf : static_range_cast<RooAbsPdf*>(
_pdfList)) {
1887 if (std::list<double>* hint = pdf->binBoundaries(obs,xlo,xhi)) {
1904 if (i>0) os <<
" * " ;
1907 if (!ncset->empty()) {
1908 if (
string(
"nset")==ncset->GetName()) {
1913 for (
auto const* arg : *ncset) {
1919 os << arg->GetName() ;
1936 cxcoutD(LinkStateMgmt) <<
"RooProdPdf::redirectServersHook(" <<
GetName() <<
"): removing REMOVAL_DUMMY" << std::endl ;
1951 for(std::unique_ptr<RooArgSet>
const& normSet :
_pdfNSetList) {
1955 normSet->replace(arg, std::unique_ptr<RooAbsArg>{newArg->cloneTree()});
1965 os <<
"_partList\n";
1966 os << getColonSeparatedNameString(_partList) <<
"\n";
1968 os << getColonSeparatedNameString(_numList) <<
"\n";
1970 os << getColonSeparatedNameString(_denList) <<
"\n";
1971 os <<
"_ownedList\n";
1972 os << getColonSeparatedNameString(_ownedList) <<
"\n";
1973 os <<
"_normList\n";
1974 for(
auto const& set : _normList) {
1975 os << getColonSeparatedNameString(*set) <<
"\n";
1977 os <<
"_isRearranged" <<
"\n";
1978 os << _isRearranged <<
"\n";
1979 os <<
"_rearrangedNum" <<
"\n";
1980 if(_rearrangedNum) {
1981 os << getColonSeparatedNameString(*_rearrangedNum) <<
"\n";
1983 os <<
"nullptr" <<
"\n";
1985 os <<
"_rearrangedDen" <<
"\n";
1986 if(_rearrangedDen) {
1987 os << getColonSeparatedNameString(*_rearrangedDen) <<
"\n";
1989 os <<
"nullptr" <<
"\n";
1995 if (normSet.empty())
1998 if (pdfNset && !pdfNset->empty()) {
1999 std::unique_ptr<RooArgSet> out;
2000 if (0 == strcmp(
"cset", pdfNset->GetName())) {
2004 out = std::make_unique<RooArgSet>(normSet);
2006 out->selectCommon(*pdfNset, common);
2007 out->remove(common);
2009 out = std::make_unique<RooArgSet>(*pdfNset);
2014 if (!arg->getStringAttribute(
"__prefix__")) {
2015 arg->SetName((std::string(prefix) + arg->GetName()).c_str());
2016 arg->setStringAttribute(
"__prefix__", prefix);
2026std::unique_ptr<RooAbsArg>
2029 if (ctx.likelihoodMode()) {
2031 if (binnedInfo.binnedPdf && binnedInfo.binnedPdf !=
this) {
2032 return binnedInfo.binnedPdf->compileForNormSet(normSet, ctx);
2036 std::unique_ptr<RooProdPdf> prodPdfClone{
static_cast<RooProdPdf *
>(this->
Clone())};
2054 std::vector<std::pair<RooAbsPdf *, std::string>> restoreNormRanges;
2055 if (
const char *prodNormRange =
normRange()) {
2056 std::vector<std::string> rangeTokens =
ROOT::Split(prodNormRange,
",",
true);
2057 for (
auto *pdf : static_range_cast<RooAbsPdf *>(prodPdfClone->_pdfList)) {
2059 pdf->getObservables(&normSet, pdfObs);
2060 bool rangeDefined = !pdfObs.
empty();
2063 for (
auto const &token : rangeTokens) {
2064 if (!lval || !lval->hasRange(token.c_str())) {
2065 rangeDefined =
false;
2069 if (rangeDefined && std::string(pdf->normRange() ? pdf->normRange() :
"") != prodNormRange) {
2070 restoreNormRanges.emplace_back(pdf, pdf->normRange() ? pdf->normRange() :
"");
2071 pdf->setNormRange(prodNormRange);
2076 for (
const auto server : prodPdfClone->servers()) {
2078 RooArgSet const &nset = nsetForServer ? *nsetForServer : normSet;
2081 server->getObservables(&nset, depList);
2083 ctx.compileServer(*server, *prodPdfClone, depList);
2086 for (
auto const &[pdf, oldRange] : restoreNormRanges) {
2087 pdf->setNormRange(oldRange.empty() ? nullptr : oldRange.c_str());
2097 std::make_unique<RooFit::Detail::RooFixedProdPdf>(std::move(prodPdfClone), ctx.mapToCompiled(normSet));
2098 ctx.markAsCompiled(*fixedProdPdf);
2100 return fixedProdPdf;
2105RooFixedProdPdf::RooFixedProdPdf(std::unique_ptr<RooProdPdf> &&prodPdf,
RooArgSet const &normSet)
2106 :
RooAbsPdf(prodPdf->GetName(), prodPdf->GetTitle()),
2108 _servers(
"!servers",
"List of servers", this),
2109 _prodPdf{std::move(prodPdf)}
2116 cache->_ownedList.releaseOwnership();
2117 cache->_numList.releaseOwnership();
2118 cache->_denList.releaseOwnership();
2133 for (
RooAbsArg *arg : cache->_partList) {
2140 _normSet{other._normSet},
2141 _servers(
"!servers", this, other._servers),
2142 _prodPdf{static_cast<
RooProdPdf *>(other._prodPdf->Clone())},
2143 _isRearranged{other._isRearranged}
2158 std::vector<std::span<const double>> factors;
2161 auto span = ctx.at(arg);
2162 factors.push_back(span);
2164 std::array<double, 1> special{
static_cast<double>(factors.size())};
2175 for (
auto *arg : static_range_cast<RooAbsReal *>(*
partList())) {
2176 value *= arg->getVal();
ROOT::RRangeCast< T, false, Range_t > static_range_cast(Range_t &&coll)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Common abstract base class for objects that represent a value and a "shape" in RooFit.
RooExpensiveObjectCache & expensiveObjectCache() const
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
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'.
friend class RooRealIntegral
RooFit::OwningPtr< RooArgSet > getComponents() const
Create a RooArgSet with all components (branch nodes) of the expression tree headed by this object.
TObject * Clone(const char *newname=nullptr) const override
Make a clone of an object using the Streamer facility.
void treeNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=nullptr, bool doBranch=true, bool doLeaf=true, bool valueOnly=false, bool recurseNonDerived=false) const
Fill supplied list with nodes of the arg tree, following all server links, starting with ourself as t...
RooAbsArg * findNewServer(const RooAbsCollection &newSet, bool nameChange) const
Find the new server in the specified set that matches the old server.
OperMode operMode() const
Query the operation mode of this node.
Abstract container object that can hold multiple RooAbsArg objects.
virtual bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false)
Remove the specified argument from our list.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Int_t index(const RooAbsArg *arg) const
Returns index of given arg, or -1 if arg is not in the collection.
bool overlaps(Iterator_t otherCollBegin, Iterator_t otherCollEnd) const
Storage_t::size_type size() const
const_iterator begin() const
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.
TString _normRange
Normalization range.
virtual bool isDirectGenSafe(const RooAbsArg &arg) const
Check if given observable can be safely generated using the pdfs internal generator mechanism (if tha...
RooArgSet const * _normSet
! Normalization set with for above integral
bool canBeExtended() const
If true, PDF can provide extended likelihood term.
const char * normRange() const
bool redirectServersHook(const RooAbsCollection &newServerList, bool mustReplaceAll, bool nameChange, bool isRecursiveStep) override
Hook function intercepting redirectServer calls.
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool verbose=false) const
Interface function to create a generator context from a p.d.f.
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...
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
bool _forceNumInt
Force numerical integration if flag set.
TString integralNameSuffix(const RooArgSet &iset, const RooArgSet *nset=nullptr, const char *rangeName=nullptr, bool omitEmpty=false) const
Construct string with unique suffix name to give to integral object that encodes integrated observabl...
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 ...
Calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
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.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
RooArgSet * selectCommon(const RooAbsCollection &refColl) const
Use RooAbsCollection::selecCommon(), but return as RooArgSet.
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=nullptr)
Setter function without integration set.
RooArgSet selectFromSet1(RooArgSet const &argSet, int index) const
Create RooArgSet containing the objects that are both in the cached set 1 with a given index and an i...
T * getObjByIndex(Int_t index) const
Retrieve payload object by slot index.
RooArgSet selectFromSet2(RooArgSet const &argSet, int index) const
Create RooArgSet containing the objects that are both in the cached set 2 with a given index and an i...
void reset()
Clear the cache.
Int_t lastIndex() const
Return index of slot used in last get or set operation.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=nullptr, const TNamed *isetRangeName=nullptr)
Getter function without integration set.
Named container for two doubles, two integers two object points and three string pointers that can be...
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...
bool remove(const RooAbsArg &var, bool silent=false, bool matchByNameOnly=false) override
Remove object 'var' from set and deregister 'var' as server to owner.
TObject * clone(const char *newname=nullptr) const override
RooCustomizer is a factory class to produce clones of a prototype composite PDF object with the same ...
Container class to hold unbinned data.
void markAsCompiled(RooAbsArg &arg) const
A RooProdPdf with a fixed normalization set can be replaced by this class.
RooFixedProdPdf(std::unique_ptr< RooProdPdf > &&prodPdf, RooArgSet const &normSet)
RooArgSet const * partList() const
double evaluate() const override
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
void doEval(RooFit::EvalContext &ctx) const override
Evaluate product of PDFs in batch mode.
std::unique_ptr< RooProdPdf > _prodPdf
RooAbsReal const * rearrangedDen() const
RooAbsReal const * rearrangedNum() const
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
void Delete(Option_t *o=nullptr) override
Remove all elements in collection and delete all elements NB: Collection does not own elements,...
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.
RooArgList containedArgs(Action) override
Return RooAbsArg components contained in the cache.
std::unique_ptr< RooAbsReal > _rearrangedNum
void printCompactTreeHook(std::ostream &, const char *, Int_t, Int_t) override
Hook function to print cache contents in tree printing of RooProdPdf.
std::vector< std::unique_ptr< RooArgSet > > _normList
std::unique_ptr< RooAbsReal > _rearrangedDen
void writeToStream(std::ostream &os) const
Efficient implementation of a product of PDFs of the form.
std::unique_ptr< RooArgSet > getConstraints(const RooArgSet &observables, RooArgSet const &constrainedParams, RooArgSet &pdfParams) const override
Return all parameter constraint p.d.f.s on parameters listed in constrainedParams.
Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, bool staticInitOK=true) const override
Query internal generation capabilities of component p.d.f.s and aggregate capabilities into master co...
void rearrangeProduct(CacheElem &) const
double analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Return analytical integral defined by given scenario code.
~RooProdPdf() override
Destructor.
Int_t _extendedIndex
Index of extended PDF (if any)
std::unique_ptr< RooAbsReal > specializeRatio(RooFormulaVar &input, const char *targetRangeName) const
RooProdPdf()
Default constructor.
void removePdfs(RooAbsCollection const &pdfs)
Remove some PDFs from the factors of this RooProdPdf.
bool _useDefaultGen
Use default or distributed event generator.
std::vector< std::unique_ptr< RooArgSet > > _pdfNSetList
List of PDF component normalization sets.
std::unique_ptr< RooArgSet > fillNormSetForServer(RooArgSet const &normSet, RooAbsArg const &server) const
std::unique_ptr< RooAbsReal > specializeIntegral(RooAbsReal &orig, const char *targetRangeName) const
void factorizeProduct(const RooArgSet &normSet, const RooArgSet &intSet, Factorized &factorized) const
Factorize product in irreducible terms for given choice of integration/normalization.
bool forceAnalyticalInt(const RooAbsArg &dep) const override
Force RooRealIntegral to offer all observables for internal integration.
std::unique_ptr< RooAbsArg > compileForNormSet(RooArgSet const &normSet, RooFit::Detail::CompileContext &ctx) const override
RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool verbose=false) const override
Return generator context optimized for generating events from product p.d.f.s.
TNamed * _refRangeName
Reference range name for interpretation of conditional products.
void addPdfs(RooAbsCollection const &pdfs)
Add some full PDFs to the factors of this RooProdPdf.
RooListProxy _pdfList
List of PDF components.
Int_t getPartIntList(const RooArgSet *nset, const RooArgSet *iset, const char *isetRangeName=nullptr) const
Return list of (partial) integrals of product terms for integration of p.d.f over observables iset wh...
void printMetaArgs(std::ostream &os) const override
Customized printing of arguments of a RooProdPdf to more intuitively reflect the contents of the prod...
std::list< double > * binBoundaries(RooAbsRealLValue &, double, double) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
RooObjCacheManager _cacheMgr
! The cache manager
std::string makeRGPPName(const char *pfx, const RooArgSet &term, const RooArgSet &iset, const RooArgSet &nset, const char *isetRangeName) const
Make an appropriate automatic name for a RooGenProdProj object in getPartIntList()
bool isDirectGenSafe(const RooAbsArg &arg) const override
Forward determination of safety of internal generator code to component p.d.f that would generate the...
ProcessProductTermOutput processProductTerm(const RooArgSet *nset, const RooArgSet *iset, const char *isetRangeName, const RooArgSet *term, const RooArgSet &termNSet, const RooArgSet &termISet, bool forceWrap=false) const
Calculate integrals of factorized product terms over observables iset while normalized to observables...
std::unique_ptr< RooAbsReal > makeCondPdfRatioCorr(RooAbsReal &term, const RooArgSet &termNset, const RooArgSet &termImpSet, const char *normRange, const char *refRange) const
For single normalization ranges.
RooArgSet * findPdfNSet(RooAbsPdf const &pdf) const
Look up user specified normalization set for given input PDF component.
ExtendMode extendMode() const override
If this product contains exactly one extendable p.d.f return the extension abilities of that p....
std::list< double > * plotSamplingHint(RooAbsRealLValue &obs, double xlo, double xhi) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
double expectedEvents(const RooArgSet *nset) const override
Return the expected number of events associated with the extendable input PDF in the product.
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.
bool isBinnedDistribution(const RooArgSet &obs) const override
If all components that depend on obs are binned that so is the product.
friend class RooProdGenContext
RooArgSet * getConnectedParameters(const RooArgSet &observables) const
Return all parameter constraint p.d.f.s on parameters listed in constrainedParams.
double calculate(const RooProdPdf::CacheElem &cache, bool verbose=false) const
Calculate running product of pdfs terms, using the supplied normalization set in 'normSetList' for ea...
RooArgSet _defNormSet
Default normalization set.
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,...
CacheElem * getCacheElem(RooArgSet const *nset) const
bool redirectServersHook(const RooAbsCollection &, bool, bool, bool) override
Implement support for node removal.
void groupProductTerms(std::list< std::vector< RooArgSet * > > &groupedTerms, RooArgSet &outerIntDeps, Factorized const &factorized) const
Group product into terms that can be calculated independently.
std::vector< std::vector< int > > _genCode
! Registry of composite direct generator codes
void initGenerator(Int_t code) override
Forward one-time initialization call to component generation initialization methods.
void generateEvent(Int_t code) override
Generate a single event with configuration specified by 'code' Defer internal generation to component...
void fixRefRange(const char *rangeName)
std::unique_ptr< CacheElem > createCacheElem(const RooArgSet *nset, const RooArgSet *iset, const char *isetRangeName=nullptr) const
double evaluate() const override
Calculate current value of object.
void initializeFromCmdArgList(const RooArgSet &fullPdfSet, const RooLinkedList &l)
Initialize RooProdPdf configuration from given list of RooCmdArg configuration arguments and set of '...
void selectNormalizationRange(const char *rangeName=nullptr, bool force=false) override
Interface function used by test statistics to freeze choice of range for interpretation of conditiona...
double _cutOff
Cutoff parameter for running product.
Represents the product of a given set of RooAbsReal objects.
Performs hybrid numerical/analytical integrals of RooAbsReal objects.
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooArgSet *nset=nullptr, const RooNumIntConfig *cfg=nullptr, const char *rangeName=nullptr) const override
Create an object that represents the integral of the function over one or more observables listed in ...
const RooAbsReal & integrand() const
Variable that can be changed from the outside.
The TNamed class is the base class for all named ROOT classes.
const char * GetName() const override
Returns name of object.
Mother of all ROOT objects.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
const char * Data() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
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={})
BinnedLOutput getBinnedL(RooAbsPdf const &pdf)
std::string getColonSeparatedNameString(RooArgSet const &argSet, char delim=':')