57 ClassImp(RooRealSumFunc);
59 Bool_t RooRealSumFunc::_doFloorGlobal = kFALSE;
62 RooRealSumFunc::RooRealSumFunc()
66 _funcIter = _funcList.createIterator();
67 _coefIter = _coefList.createIterator();
73 RooRealSumFunc::RooRealSumFunc(
const char *name,
const char *title)
74 : RooAbsReal(name, title), _normIntMgr(this, 10), _haveLastCoef(kFALSE),
75 _funcList(
"!funcList",
"List of functions", this), _coefList(
"!coefList",
"List of coefficients", this),
79 _funcIter = _funcList.createIterator();
80 _coefIter = _coefList.createIterator();
85 RooRealSumFunc::RooRealSumFunc(
const char *name,
const char *title, RooAbsReal &func1, RooAbsReal &func2,
87 : RooAbsReal(name, title), _normIntMgr(this, 10), _haveLastCoef(kFALSE),
88 _funcList(
"!funcList",
"List of functions", this), _coefList(
"!coefList",
"List of coefficients", this),
96 _funcIter = _funcList.createIterator();
97 _coefIter = _coefList.createIterator();
100 _funcList.add(func2);
101 _coefList.add(coef1);
106 RooRealSumFunc::RooRealSumFunc(
const char *name,
const char *title,
const RooArgList &inFuncList,
107 const RooArgList &inCoefList)
108 : RooAbsReal(name, title), _normIntMgr(this, 10), _haveLastCoef(kFALSE),
109 _funcList(
"!funcList",
"List of functions", this), _coefList(
"!coefList",
"List of coefficients", this),
118 if (!(inFuncList.getSize() == inCoefList.getSize() + 1 || inFuncList.getSize() == inCoefList.getSize())) {
119 coutE(InputArguments) <<
"RooRealSumFunc::RooRealSumFunc(" << GetName()
120 <<
") number of pdfs and coefficients inconsistent, must have Nfunc=Ncoef or Nfunc=Ncoef+1"
125 _funcIter = _funcList.createIterator();
126 _coefIter = _coefList.createIterator();
129 TIterator *funcIter = inFuncList.createIterator();
130 TIterator *coefIter = inCoefList.createIterator();
134 while ((coef = (RooAbsArg *)coefIter->Next())) {
135 func = (RooAbsArg *)funcIter->Next();
137 if (!dynamic_cast<RooAbsReal *>(coef)) {
138 coutW(InputArguments) <<
"RooRealSumFunc::RooRealSumFunc(" << GetName() <<
") coefficient " << coef->GetName()
139 <<
" is not of type RooAbsReal, ignored" << endl;
142 if (!dynamic_cast<RooAbsReal *>(func)) {
143 coutW(InputArguments) <<
"RooRealSumFunc::RooRealSumFunc(" << GetName() <<
") func " << func->GetName()
144 <<
" is not of type RooAbsReal, ignored" << endl;
147 _funcList.add(*func);
148 _coefList.add(*coef);
151 func = (RooAbsReal *)funcIter->Next();
153 if (!dynamic_cast<RooAbsReal *>(func)) {
154 coutE(InputArguments) <<
"RooRealSumFunc::RooRealSumFunc(" << GetName() <<
") last func " << coef->GetName()
155 <<
" is not of type RooAbsReal, fatal error" << endl;
158 _funcList.add(*func);
160 _haveLastCoef = kTRUE;
169 RooRealSumFunc::RooRealSumFunc(
const RooRealSumFunc &other,
const char *name)
170 : RooAbsReal(other, name), _normIntMgr(other._normIntMgr, this), _haveLastCoef(other._haveLastCoef),
171 _funcList(
"!funcList", this, other._funcList), _coefList(
"!coefList", this, other._coefList),
172 _doFloor(other._doFloor)
176 _funcIter = _funcList.createIterator();
177 _coefIter = _coefList.createIterator();
182 RooRealSumFunc::~RooRealSumFunc()
192 Double_t RooRealSumFunc::evaluate()
const
199 RooFIter funcIter = _funcList.fwdIterator();
200 RooFIter coefIter = _coefList.fwdIterator();
205 Double_t lastCoef(1);
206 while ((coef = (RooAbsReal *)coefIter.next())) {
207 func = (RooAbsReal *)funcIter.next();
208 Double_t coefVal = coef->getVal();
210 cxcoutD(Eval) <<
"RooRealSumFunc::eval(" << GetName() <<
") coefVal = " << coefVal
211 <<
" funcVal = " << func->IsA()->GetName() <<
"::" << func->GetName() <<
" = " << func->getVal()
213 if (func->isSelectedComp()) {
214 value += func->getVal() * coefVal;
216 lastCoef -= coef->getVal();
220 if (!_haveLastCoef) {
222 func = (RooAbsReal *)funcIter.next();
223 if (func->isSelectedComp()) {
224 value += func->getVal() * lastCoef;
227 cxcoutD(Eval) <<
"RooRealSumFunc::eval(" << GetName() <<
") lastCoef = " << lastCoef
228 <<
" funcVal = " << func->getVal() << endl;
231 if (lastCoef < 0 || lastCoef > 1) {
232 coutW(Eval) <<
"RooRealSumFunc::evaluate(" << GetName()
233 <<
" WARNING: sum of FUNC coefficients not in range [0-1], value=" << 1 - lastCoef << endl;
238 if (value < 0 && (_doFloor || _doFloorGlobal)) {
246 Bool_t RooRealSumFunc::checkObservables(
const RooArgSet *nset)
const
261 while ((coef = (RooAbsReal *)_coefIter->Next())) {
262 func = (RooAbsReal *)_funcIter->Next();
263 if (func->observableOverlaps(nset, *coef)) {
264 coutE(InputArguments) <<
"RooRealSumFunc::checkObservables(" << GetName() <<
"): ERROR: coefficient "
265 << coef->GetName() <<
" and FUNC " << func->GetName()
266 <<
" have one or more observables in common" << endl;
269 if (coef->dependsOn(*nset)) {
270 coutE(InputArguments) <<
"RooRealPdf::checkObservables(" << GetName() <<
"): ERROR coefficient "
271 << coef->GetName() <<
" depends on one or more of the following observables";
281 Int_t RooRealSumFunc::getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars,
const RooArgSet *normSet2,
282 const char *rangeName)
const
290 if (allVars.getSize() == 0)
296 analVars.add(allVars);
297 RooArgSet *normSet = normSet2 ? getObservables(normSet2) : 0;
300 Int_t sterileIdx(-1);
301 CacheElem *cache = (CacheElem *)_normIntMgr.getObj(normSet, &analVars, &sterileIdx, RooNameReg::ptr(rangeName));
306 return _normIntMgr.lastIndex() + 1;
310 cache =
new CacheElem;
315 while ((func = (RooAbsReal *)_funcIter->Next())) {
316 RooAbsReal *funcInt = func->createIntegral(analVars, rangeName);
317 if(funcInt->InheritsFrom(RooRealIntegral::Class())) ((RooRealIntegral*)funcInt)->setAllowComponentSelection(
true);
318 cache->_funcIntList.addOwned(*funcInt);
319 if (normSet && normSet->getSize() > 0) {
320 RooAbsReal *funcNorm = func->createIntegral(*normSet);
321 cache->_funcNormList.addOwned(*funcNorm);
326 Int_t code = _normIntMgr.setObj(normSet, &analVars, (RooAbsCacheElement *)cache, RooNameReg::ptr(rangeName));
339 Double_t RooRealSumFunc::analyticalIntegralWN(Int_t code,
const RooArgSet *normSet2,
const char *rangeName)
const
349 return getVal(normSet2);
352 CacheElem *cache = (CacheElem *)_normIntMgr.getObjByIndex(code - 1);
357 std::unique_ptr<RooArgSet> vars(getParameters(RooArgSet()));
358 std::unique_ptr<RooArgSet> iset(_normIntMgr.nameSet2ByIndex(code - 1)->select(*vars));
359 std::unique_ptr<RooArgSet> nset(_normIntMgr.nameSet1ByIndex(code - 1)->select(*vars));
361 Int_t code2 = getAnalyticalIntegralWN(*iset, dummy, nset.get(), rangeName);
362 assert(code == code2);
364 cache = (CacheElem *)_normIntMgr.getObjByIndex(code - 1);
368 RooFIter funcIntIter = cache->_funcIntList.fwdIterator();
369 RooFIter coefIter = _coefList.fwdIterator();
370 RooFIter funcIter = _funcList.fwdIterator();
371 RooAbsReal *coef(0), *funcInt(0), *func(0);
375 Double_t lastCoef(1);
376 while ((coef = (RooAbsReal *)coefIter.next())) {
377 funcInt = (RooAbsReal *)funcIntIter.next();
378 func = (RooAbsReal *)funcIter.next();
379 Double_t coefVal = coef->getVal(normSet2);
382 if (normSet2 == 0 || func->isSelectedComp()) {
384 value += funcInt->getVal() * coefVal;
386 lastCoef -= coef->getVal(normSet2);
390 if (!_haveLastCoef) {
392 funcInt = (RooAbsReal *)funcIntIter.next();
393 if (normSet2 == 0 || func->isSelectedComp()) {
395 value += funcInt->getVal() * lastCoef;
399 if (lastCoef < 0 || lastCoef > 1) {
400 coutW(Eval) <<
"RooRealSumFunc::evaluate(" << GetName()
401 <<
" WARNING: sum of FUNC coefficients not in range [0-1], value=" << 1 - lastCoef << endl;
406 if (normSet2 && normSet2->getSize() > 0) {
410 RooAbsReal *funcNorm;
411 RooFIter funcNormIter = cache->_funcNormList.fwdIterator();
412 RooFIter coefIter2 = _coefList.fwdIterator();
413 while ((coef = (RooAbsReal *)coefIter2.next())) {
414 funcNorm = (RooAbsReal *)funcNormIter.next();
415 Double_t coefVal = coef->getVal(normSet2);
418 normVal += funcNorm->getVal() * coefVal;
423 if (!_haveLastCoef) {
424 funcNorm = (RooAbsReal *)funcNormIter.next();
426 normVal += funcNorm->getVal() * lastCoef;
430 return value / normVal;
434 std::list<Double_t> *RooRealSumFunc::binBoundaries(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi)
const
436 list<Double_t> *sumBinB = 0;
437 Bool_t needClean(kFALSE);
439 RooFIter iter = _funcList.fwdIterator();
442 while ((func = (RooAbsReal *)iter.next())) {
444 list<Double_t> *funcBinB = func->binBoundaries(obs, xlo, xhi);
453 list<Double_t> *newSumBinB =
new list<Double_t>(sumBinB->size() + funcBinB->size());
456 merge(funcBinB->begin(), funcBinB->end(), sumBinB->begin(), sumBinB->end(), newSumBinB->begin());
461 sumBinB = newSumBinB;
469 list<Double_t>::iterator new_end = unique(sumBinB->begin(), sumBinB->end());
470 sumBinB->erase(new_end, sumBinB->end());
477 Bool_t RooRealSumFunc::isBinnedDistribution(
const RooArgSet &obs)
const
481 RooFIter iter = _funcList.fwdIterator();
483 while ((func = (RooAbsReal *)iter.next())) {
484 if (func->dependsOn(obs) && !func->isBinnedDistribution(obs)) {
493 std::list<Double_t> *RooRealSumFunc::plotSamplingHint(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi)
const
495 list<Double_t> *sumHint = 0;
496 Bool_t needClean(kFALSE);
498 RooFIter iter = _funcList.fwdIterator();
501 while ((func = (RooAbsReal *)iter.next())) {
503 list<Double_t> *funcHint = func->plotSamplingHint(obs, xlo, xhi);
514 list<Double_t> *newSumHint =
new list<Double_t>(sumHint->size() + funcHint->size());
517 merge(funcHint->begin(), funcHint->end(), sumHint->begin(), sumHint->end(), newSumHint->begin());
521 sumHint = newSumHint;
529 list<Double_t>::iterator new_end = unique(sumHint->begin(), sumHint->end());
530 sumHint->erase(new_end, sumHint->end());
537 void RooRealSumFunc::setCacheAndTrackHints(RooArgSet &trackNodes)
540 RooFIter siter = funcList().fwdIterator();
542 while ((sarg = siter.next())) {
543 if (sarg->canNodeBeCached() == Always) {
544 trackNodes.add(*sarg);
552 void RooRealSumFunc::printMetaArgs(ostream &os)
const
562 RooAbsArg *coef, *func;
563 if (_coefList.getSize() != 0) {
564 while ((coef = (RooAbsArg *)_coefIter->Next())) {
570 func = (RooAbsArg *)_funcIter->Next();
571 os << coef->GetName() <<
" * " << func->GetName();
573 func = (RooAbsArg *)_funcIter->Next();
575 os <<
" + [%] * " << func->GetName();
579 while ((func = (RooAbsArg *)_funcIter->Next())) {
585 os << func->GetName();