#include "RooFit.h"
#include "RooMsgService.h"
#include "TIterator.h"
#include "TIterator.h"
#include "TList.h"
#include "RooAddPdf.h"
#include "RooDataSet.h"
#include "RooRealProxy.h"
#include "RooPlot.h"
#include "RooRealVar.h"
#include "RooAddGenContext.h"
#include "RooRealConstant.h"
#include "RooNameReg.h"
#include "RooMsgService.h"
#include "RooRecursiveFraction.h"
#include "RooGlobalFunc.h"
#include "Riostream.h"
#include <algorithm>
ClassImp(RooAddPdf)
;
RooAddPdf::RooAddPdf() :
_refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
_refCoefRangeName(0),
_codeReg(10),
_snormList(0)
{
_pdfIter = _pdfList.createIterator() ;
_coefIter = _coefList.createIterator() ;
_coefCache = new Double_t[10] ;
_coefErrCount = _errorCount ;
}
RooAddPdf::RooAddPdf(const char *name, const char *title) :
RooAbsPdf(name,title),
_refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
_refCoefRangeName(0),
_projectCoefs(kFALSE),
_projCacheMgr(this,10),
_codeReg(10),
_pdfList("!pdfs","List of PDFs",this),
_coefList("!coefficients","List of coefficients",this),
_snormList(0),
_haveLastCoef(kFALSE),
_allExtendable(kFALSE)
{
_pdfIter = _pdfList.createIterator() ;
_coefIter = _coefList.createIterator() ;
_coefCache = new Double_t[10] ;
_coefErrCount = _errorCount ;
}
RooAddPdf::RooAddPdf(const char *name, const char *title,
RooAbsPdf& pdf1, RooAbsPdf& pdf2, RooAbsReal& coef1) :
RooAbsPdf(name,title),
_refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
_refCoefRangeName(0),
_projectCoefs(kFALSE),
_projCacheMgr(this,10),
_codeReg(10),
_pdfList("!pdfs","List of PDFs",this),
_coefList("!coefficients","List of coefficients",this),
_haveLastCoef(kFALSE),
_allExtendable(kFALSE)
{
_pdfIter = _pdfList.createIterator() ;
_coefIter = _coefList.createIterator() ;
_pdfList.add(pdf1) ;
_pdfList.add(pdf2) ;
_coefList.add(coef1) ;
_coefCache = new Double_t[_pdfList.getSize()] ;
_coefErrCount = _errorCount ;
}
RooAddPdf::RooAddPdf(const char *name, const char *title, const RooArgList& inPdfList, const RooArgList& inCoefList, Bool_t recursiveFractions) :
RooAbsPdf(name,title),
_refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
_refCoefRangeName(0),
_projectCoefs(kFALSE),
_projCacheMgr(this,10),
_codeReg(10),
_pdfList("!pdfs","List of PDFs",this),
_coefList("!coefficients","List of coefficients",this),
_haveLastCoef(kFALSE),
_allExtendable(kFALSE)
{
if (inPdfList.getSize()>inCoefList.getSize()+1 || inPdfList.getSize()<inCoefList.getSize()) {
coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName()
<< ") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1" << endl ;
assert(0) ;
}
if (recursiveFractions && inPdfList.getSize()!=inCoefList.getSize()+1) {
coutW(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName()
<< ") WARNING inconsistent input: recursive fractions options can only be used if Npdf=Ncoef+1, ignoring recursive fraction setting" << endl ;
}
_pdfIter = _pdfList.createIterator() ;
_coefIter = _coefList.createIterator() ;
TIterator* pdfIter = inPdfList.createIterator() ;
TIterator* coefIter = inCoefList.createIterator() ;
RooAbsPdf* pdf ;
RooAbsReal* coef ;
RooArgList partinCoefList ;
Bool_t first(kTRUE) ;
while((coef = (RooAbsPdf*)coefIter->Next())) {
pdf = (RooAbsPdf*) pdfIter->Next() ;
if (!pdf) {
coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName()
<< ") number of pdfs and coefficients inconsistent, must have Npdf=Ncoef or Npdf=Ncoef+1" << endl ;
assert(0) ;
}
if (!dynamic_cast<RooAbsReal*>(coef)) {
coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") coefficient " << coef->GetName() << " is not of type RooAbsReal, ignored" << endl ;
continue ;
}
if (!dynamic_cast<RooAbsReal*>(pdf)) {
coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not of type RooAbsPdf, ignored" << endl ;
continue ;
}
_pdfList.add(*pdf) ;
if (recursiveFractions) {
partinCoefList.add(*coef) ;
if (first) {
first = kFALSE ;
_coefList.add(*coef) ;
} else {
RooAbsReal* rfrac = new RooRecursiveFraction(Form("%s_recursive_fraction_%s",GetName(),pdf->GetName()),"Recursive Fraction",partinCoefList) ;
addOwnedComponents(*rfrac) ;
_coefList.add(*rfrac) ;
}
} else {
_coefList.add(*coef) ;
}
}
pdf = (RooAbsPdf*) pdfIter->Next() ;
if (pdf) {
if (!dynamic_cast<RooAbsReal*>(pdf)) {
coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") last pdf " << coef->GetName() << " is not of type RooAbsPdf, fatal error" << endl ;
assert(0) ;
}
_pdfList.add(*pdf) ;
if (recursiveFractions) {
partinCoefList.add(RooFit::RooConst(1)) ;
RooAbsReal* rfrac = new RooRecursiveFraction(Form("%s_recursive_fraction_%s",GetName(),pdf->GetName()),"Recursive Fraction",partinCoefList) ;
addOwnedComponents(*rfrac) ;
_coefList.add(*rfrac) ;
_haveLastCoef=kTRUE ;
}
} else {
_haveLastCoef=kTRUE ;
}
delete pdfIter ;
delete coefIter ;
_coefCache = new Double_t[_pdfList.getSize()] ;
_coefErrCount = _errorCount ;
}
RooAddPdf::RooAddPdf(const char *name, const char *title, const RooArgList& inPdfList) :
RooAbsPdf(name,title),
_refCoefNorm("!refCoefNorm","Reference coefficient normalization set",this,kFALSE,kFALSE),
_refCoefRangeName(0),
_projectCoefs(kFALSE),
_projCacheMgr(this,10),
_pdfList("!pdfs","List of PDFs",this),
_coefList("!coefficients","List of coefficients",this),
_haveLastCoef(kFALSE),
_allExtendable(kTRUE)
{
_pdfIter = _pdfList.createIterator() ;
_coefIter = _coefList.createIterator() ;
TIterator* pdfIter = inPdfList.createIterator() ;
RooAbsPdf* pdf ;
while((pdf = (RooAbsPdf*) pdfIter->Next())) {
if (!dynamic_cast<RooAbsReal*>(pdf)) {
coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not of type RooAbsPdf, ignored" << endl ;
continue ;
}
if (!pdf->canBeExtended()) {
coutE(InputArguments) << "RooAddPdf::RooAddPdf(" << GetName() << ") pdf " << pdf->GetName() << " is not extendable, ignored" << endl ;
continue ;
}
_pdfList.add(*pdf) ;
}
delete pdfIter ;
_coefCache = new Double_t[_pdfList.getSize()] ;
_coefErrCount = _errorCount ;
}
RooAddPdf::RooAddPdf(const RooAddPdf& other, const char* name) :
RooAbsPdf(other,name),
_refCoefNorm("!refCoefNorm",this,other._refCoefNorm),
_refCoefRangeName((TNamed*)other._refCoefRangeName),
_projectCoefs(other._projectCoefs),
_projCacheMgr(other._projCacheMgr,this),
_codeReg(other._codeReg),
_pdfList("!pdfs",this,other._pdfList),
_coefList("!coefficients",this,other._coefList),
_haveLastCoef(other._haveLastCoef),
_allExtendable(other._allExtendable)
{
_pdfIter = _pdfList.createIterator() ;
_coefIter = _coefList.createIterator() ;
_coefCache = new Double_t[_pdfList.getSize()] ;
_coefErrCount = _errorCount ;
}
RooAddPdf::~RooAddPdf()
{
delete _pdfIter ;
delete _coefIter ;
if (_coefCache) delete[] _coefCache ;
}
void RooAddPdf::fixCoefNormalization(const RooArgSet& refCoefNorm)
{
if (refCoefNorm.getSize()==0) {
_projectCoefs = kFALSE ;
return ;
}
_projectCoefs = kTRUE ;
_refCoefNorm.removeAll() ;
_refCoefNorm.add(refCoefNorm) ;
_projCacheMgr.reset() ;
}
void RooAddPdf::fixCoefRange(const char* rangeName)
{
_refCoefRangeName = (TNamed*)RooNameReg::ptr(rangeName) ;
if (_refCoefRangeName) _projectCoefs = kTRUE ;
}
RooAddPdf::CacheElem* RooAddPdf::getProjCache(const RooArgSet* nset, const RooArgSet* iset, const char* rangeName) const
{
CacheElem* cache = (CacheElem*) _projCacheMgr.getObj(nset,iset,0,RooNameReg::ptr(rangeName)) ;
if (cache) {
return cache ;
}
cache = new CacheElem ;
RooArgSet *fullDepList = getObservables(nset) ;
if (iset) {
fullDepList->remove(*iset,kTRUE,kTRUE) ;
}
_pdfIter->Reset() ;
_coefIter->Reset() ;
RooAbsPdf* pdf ;
RooAbsReal* coef ;
while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
coef=(RooAbsPdf*)_coefIter->Next() ;
RooArgSet supNSet(*fullDepList) ;
RooArgSet* pdfDeps = pdf->getObservables(nset) ;
if (pdfDeps) {
supNSet.remove(*pdfDeps,kTRUE,kTRUE) ;
delete pdfDeps ;
}
RooArgSet* coefDeps = coef ? coef->getObservables(nset) : 0 ;
if (coefDeps) {
supNSet.remove(*coefDeps,kTRUE,kTRUE) ;
delete coefDeps ;
}
RooAbsReal* snorm ;
TString name(GetName()) ;
name.Append("_") ;
name.Append(pdf->GetName()) ;
name.Append("_SupNorm") ;
if (supNSet.getSize()>0) {
snorm = new RooRealIntegral(name,"Supplemental normalization integral",RooRealConstant::value(1.0),supNSet) ;
} else {
snorm = new RooRealVar(name,"Unit Supplemental normalization integral",1.0) ;
}
cache->_suppNormList.addOwned(*snorm) ;
}
delete fullDepList ;
if (_verboseEval>1) {
cxcoutD(Caching) << "RooAddPdf::syncSuppNormList(" << GetName() << ") synching supplemental normalization list for norm" << (nset?*nset:RooArgSet()) << endl ;
if dologD(Caching) {
cache->_suppNormList.Print("v") ;
}
}
if (!_projectCoefs) {
_projCacheMgr.setObj(nset,iset,cache,RooNameReg::ptr(rangeName)) ;
return cache ;
}
RooArgSet* nset2 = nset ? getObservables(nset) : new RooArgSet() ;
if (!nset2->equals(_refCoefNorm) || _refCoefRangeName !=0 || rangeName !=0 ) {
coutI(Caching) << "RooAddPdf::syncCoefProjList(" << GetName() << ") projecting coefficients from "
<< *nset2 << (rangeName?":":"") << (rangeName?rangeName:"")
<< " to " << ((_refCoefNorm.getSize()>0)?_refCoefNorm:*nset2) << (_refCoefRangeName?":":"") << (_refCoefRangeName?RooNameReg::str(_refCoefRangeName):"") << endl ;
_pdfIter->Reset() ;
RooAbsPdf* thePdf ;
while((thePdf=(RooAbsPdf*)_pdfIter->Next())) {
RooAbsReal* pdfProj ;
if (!nset2->equals(_refCoefNorm)) {
pdfProj = thePdf->createIntegral(*nset2,_refCoefNorm) ;
pdfProj->setOperMode(operMode()) ;
} else {
TString name(GetName()) ;
name.Append("_") ;
name.Append(thePdf->GetName()) ;
name.Append("_ProjectNorm") ;
pdfProj = new RooRealVar(name,"Unit Projection normalization integral",1.0) ;
}
cache->_projList.addOwned(*pdfProj) ;
RooArgSet supNormSet(_refCoefNorm) ;
RooArgSet* deps = thePdf->getParameters(RooArgSet()) ;
supNormSet.remove(*deps,kTRUE,kTRUE) ;
delete deps ;
RooAbsReal* snorm ;
TString name(GetName()) ;
name.Append("_") ;
name.Append(thePdf->GetName()) ;
name.Append("_ProjSupNorm") ;
if (supNormSet.getSize()>0) {
snorm = new RooRealIntegral(name,"Projection Supplemental normalization integral",
RooRealConstant::value(1.0),supNormSet) ;
} else {
snorm = new RooRealVar(name,"Unit Projection Supplemental normalization integral",1.0) ;
}
cache->_suppProjList.addOwned(*snorm) ;
RooAbsReal* rangeProj1 ;
if (_refCoefRangeName && _refCoefNorm.getSize()>0) {
rangeProj1 = thePdf->createIntegral(_refCoefNorm,_refCoefNorm,RooNameReg::str(_refCoefRangeName)) ;
rangeProj1->setOperMode(operMode()) ;
} else {
TString theName(GetName()) ;
theName.Append("_") ;
theName.Append(thePdf->GetName()) ;
theName.Append("_RangeNorm1") ;
rangeProj1 = new RooRealVar(theName,"Unit range normalization integral",1.0) ;
}
cache->_refRangeProjList.addOwned(*rangeProj1) ;
RooAbsReal* rangeProj2 ;
if (rangeName && _refCoefNorm.getSize()>0) {
rangeProj2 = thePdf->createIntegral(_refCoefNorm,_refCoefNorm,rangeName) ;
rangeProj2->setOperMode(operMode()) ;
} else {
TString theName(GetName()) ;
theName.Append("_") ;
theName.Append(thePdf->GetName()) ;
theName.Append("_RangeNorm2") ;
rangeProj2 = new RooRealVar(theName,"Unit range normalization integral",1.0) ;
}
cache->_rangeProjList.addOwned(*rangeProj2) ;
}
}
delete nset2 ;
_projCacheMgr.setObj(nset,iset,cache,RooNameReg::ptr(rangeName)) ;
return cache ;
}
void RooAddPdf::updateCoefficients(CacheElem& cache, const RooArgSet* nset) const
{
Int_t i ;
if (_allExtendable) {
Double_t coefSum(0) ;
for (i=0 ; i<_pdfList.getSize() ; i++) {
_coefCache[i] = ((RooAbsPdf*)_pdfList.at(i))->expectedEvents(_refCoefNorm.getSize()>0?&_refCoefNorm:nset) ;
coefSum += _coefCache[i] ;
}
if (coefSum==0.) {
coutW(Eval) << "RooAddPdf::updateCoefCache(" << GetName() << ") WARNING: total number of expected events is 0" << endl ;
} else {
for (i=0 ; i<_pdfList.getSize() ; i++) {
_coefCache[i] /= coefSum ;
}
}
} else {
if (_haveLastCoef) {
Double_t coefSum(0) ;
for (i=0 ; i<_coefList.getSize() ; i++) {
_coefCache[i] = ((RooAbsPdf*)_coefList.at(i))->getVal(nset) ;
coefSum += _coefCache[i] ;
}
if (coefSum==0.) {
coutW(Eval) << "RooAddPdf::updateCoefCache(" << GetName() << ") WARNING: sum of coefficients is zero 0" << endl ;
} else {
for (i=0 ; i<_coefList.getSize() ; i++) {
_coefCache[i] /= coefSum ;
}
}
} else {
Double_t lastCoef(1) ;
for (i=0 ; i<_coefList.getSize() ; i++) {
_coefCache[i] = ((RooAbsPdf*)_coefList.at(i))->getVal(nset) ;
cxcoutD(Caching) << "SYNC: orig coef[" << i << "] = " << _coefCache[i] << endl ;
lastCoef -= _coefCache[i] ;
}
_coefCache[_coefList.getSize()] = lastCoef ;
cxcoutD(Caching) << "SYNC: orig coef[" << _coefList.getSize() << "] = " << _coefCache[_coefList.getSize()] << endl ;
if ((lastCoef<-1e-05 || (lastCoef-1)>1e-5) && _coefErrCount-->0) {
coutW(Eval) << "RooAddPdf::updateCoefCache(" << GetName()
<< " WARNING: sum of PDF coefficients not in range [0-1], value="
<< 1-lastCoef ;
if (_coefErrCount==0) {
coutW(Eval) << " (no more will be printed)" ;
}
coutW(Eval) << endl ;
}
}
}
if ((!_projectCoefs) || cache._projList.getSize()==0) {
return ;
}
Double_t coefSum(0) ;
for (i=0 ; i<_pdfList.getSize() ; i++) {
Bool_t _tmp = _globalSelectComp ;
RooAbsPdf::globalSelectComp(kTRUE) ;
RooAbsReal* pp = ((RooAbsReal*)cache._projList.at(i)) ;
RooAbsReal* sn = ((RooAbsReal*)cache._suppProjList.at(i)) ;
RooAbsReal* r1 = ((RooAbsReal*)cache._refRangeProjList.at(i)) ;
RooAbsReal* r2 = ((RooAbsReal*)cache._rangeProjList.at(i)) ;
cxcoutD(Caching) << "pp = " << pp->GetName() << endl
<< "sn = " << sn->GetName() << endl
<< "r1 = " << r1->GetName() << endl
<< "r2 = " << r2->GetName() << endl ;
Double_t proj = pp->getVal()/sn->getVal()*(r2->getVal()/r1->getVal()) ;
RooAbsPdf::globalSelectComp(_tmp) ;
_coefCache[i] *= proj ;
coefSum += _coefCache[i] ;
}
for (i=0 ; i<_pdfList.getSize() ; i++) {
_coefCache[i] /= coefSum ;
}
}
Double_t RooAddPdf::evaluate() const
{
const RooArgSet* nset = _normSet ;
CacheElem* cache = getProjCache(nset) ;
updateCoefficients(*cache,nset) ;
_pdfIter->Reset() ;
_coefIter->Reset() ;
RooAbsPdf* pdf ;
Double_t snormVal ;
Double_t value(0) ;
Int_t i(0) ;
while((pdf = (RooAbsPdf*)_pdfIter->Next())) {
if (_coefCache[i]!=0.) {
snormVal = nset ? ((RooAbsReal*)cache->_suppNormList.at(i))->getVal() : 1.0 ;
Double_t pdfVal = pdf->getVal(nset) ;
if (pdf->isSelectedComp()) {
value += pdfVal*_coefCache[i]/snormVal ;
}
}
i++ ;
}
return value ;
}
void RooAddPdf::resetErrorCounters(Int_t resetValue)
{
RooAbsPdf::resetErrorCounters(resetValue) ;
_coefErrCount = resetValue ;
}
Bool_t RooAddPdf::checkObservables(const RooArgSet* nset) const
{
Bool_t ret(kFALSE) ;
_pdfIter->Reset() ;
_coefIter->Reset() ;
RooAbsReal* coef ;
RooAbsReal* pdf ;
while((coef=(RooAbsReal*)_coefIter->Next())) {
pdf = (RooAbsReal*)_pdfIter->Next() ;
if (pdf->observableOverlaps(nset,*coef)) {
coutE(InputArguments) << "RooAddPdf::checkObservables(" << GetName() << "): ERROR: coefficient " << coef->GetName()
<< " and PDF " << pdf->GetName() << " have one or more dependents in common" << endl ;
ret = kTRUE ;
}
}
return ret ;
}
Int_t RooAddPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
const RooArgSet* normSet, const char* rangeName) const
{
RooArgSet* allDepVars = getObservables(allVars) ;
RooArgSet allAnalVars(*allDepVars) ;
delete allDepVars ;
TIterator* avIter = allVars.createIterator() ;
Int_t n(0) ;
_pdfIter->Reset() ;
RooAbsPdf* pdf ;
while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
RooArgSet subAnalVars ;
pdf->getAnalyticalIntegralWN(allVars,subAnalVars,normSet,rangeName) ;
avIter->Reset() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)avIter->Next())) {
if (!subAnalVars.find(arg->GetName()) && pdf->dependsOn(*arg)) {
allAnalVars.remove(*arg,kTRUE,kTRUE) ;
}
}
n++ ;
}
if (allAnalVars.getSize()==0) {
delete avIter ;
return 0 ;
}
_pdfIter->Reset() ;
n=0 ;
Int_t* subCode = new Int_t[_pdfList.getSize()] ;
Bool_t allOK(kTRUE) ;
while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
RooArgSet subAnalVars ;
RooArgSet* allAnalVars2 = pdf->getObservables(allAnalVars) ;
subCode[n] = pdf->getAnalyticalIntegralWN(*allAnalVars2,subAnalVars,normSet,rangeName) ;
if (subCode[n]==0 && allAnalVars2->getSize()>0) {
coutE(InputArguments) << "RooAddPdf::getAnalyticalIntegral(" << GetName() << ") WARNING: component PDF " << pdf->GetName()
<< " advertises inconsistent set of integrals (e.g. (X,Y) but not X or Y individually."
<< " Distributed analytical integration disabled. Please fix PDF" << endl ;
allOK = kFALSE ;
}
delete allAnalVars2 ;
n++ ;
}
if (!allOK) return 0 ;
analVars.add(allAnalVars) ;
RooArgSet* intSet = new RooArgSet(allAnalVars) ;
Int_t masterCode = _codeReg.store(subCode,_pdfList.getSize(),intSet)+1 ;
delete[] subCode ;
delete avIter ;
return masterCode ;
}
Double_t RooAddPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
{
if (code==0) {
return getVal(normSet) ;
}
RooArgSet* intSet ;
const Int_t* subCode = _codeReg.retrieve(code-1,intSet) ;
if (!subCode) {
coutE(InputArguments) << "RooAddPdf::analyticalIntegral(" << GetName() << "): ERROR unrecognized integration code, " << code << endl ;
assert(0) ;
}
CacheElem* cache = getProjCache(normSet,intSet,0) ;
updateCoefficients(*cache,normSet) ;
Double_t value(0) ;
_pdfIter->Reset() ;
_coefIter->Reset() ;
RooAbsPdf* pdf ;
Double_t snormVal ;
Int_t i(0) ;
RooArgList* snormSet = (cache->_suppNormList.getSize()>0) ? &cache->_suppNormList : 0 ;
while((pdf = (RooAbsPdf*)_pdfIter->Next())) {
if (_coefCache[i]) {
snormVal = snormSet ? ((RooAbsReal*) cache->_suppNormList.at(i))->getVal() : 1.0 ;
Double_t val = pdf->analyticalIntegralWN(subCode[i],normSet,rangeName) ;
if (pdf->isSelectedComp()) {
value += val*_coefCache[i]/snormVal ;
}
i++ ;
}
}
return value ;
}
Double_t RooAddPdf::expectedEvents(const RooArgSet* nset) const
{
Double_t expectedTotal(0.0);
CacheElem* cache = getProjCache(nset) ;
updateCoefficients(*cache,nset) ;
Int_t i(0) ;
for (i=0 ; i<_pdfList.getSize() ; i++) {
Double_t proj(1) ;
RooAbsReal* r1 = ((RooAbsReal*)cache->_refRangeProjList.at(i)) ;
RooAbsReal* r2 = ((RooAbsReal*)cache->_rangeProjList.at(i)) ;
if (r1 && r2) {
proj = (r2->getVal()/r1->getVal()) ;
}
Double_t ncomp = _allExtendable ? ((RooAbsPdf*)_pdfList.at(i))->expectedEvents(nset) : ((RooAbsReal*)_coefList.at(i))->getVal(nset) ;
expectedTotal += proj*ncomp ;
}
return expectedTotal ;
}
void RooAddPdf::selectNormalization(const RooArgSet* depSet, Bool_t force)
{
if (!force && _refCoefNorm.getSize()!=0) {
return ;
}
if (!depSet) {
fixCoefNormalization(RooArgSet()) ;
return ;
}
RooArgSet* myDepSet = getObservables(depSet) ;
fixCoefNormalization(*myDepSet) ;
delete myDepSet ;
}
void RooAddPdf::selectNormalizationRange(const char* rangeName, Bool_t force)
{
if (!force && _refCoefRangeName) {
return ;
}
fixCoefRange(rangeName) ;
}
RooAbsGenContext* RooAddPdf::genContext(const RooArgSet &vars, const RooDataSet *prototype,
const RooArgSet* auxProto, Bool_t verbose) const
{
return new RooAddGenContext(*this,vars,prototype,auxProto,verbose) ;
}
RooArgList RooAddPdf::CacheElem::containedArgs(Action)
{
RooArgList allNodes;
allNodes.add(_projList) ;
allNodes.add(_suppProjList) ;
allNodes.add(_refRangeProjList) ;
allNodes.add(_rangeProjList) ;
return allNodes ;
}
std::list<Double_t>* RooAddPdf::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
{
list<Double_t>* sumHint = 0 ;
_pdfIter->Reset() ;
RooAbsPdf* pdf ;
while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
list<Double_t>* pdfHint = pdf->plotSamplingHint(obs,xlo,xhi) ;
if (pdfHint) {
if (!sumHint) {
sumHint = pdfHint ;
} else {
list<Double_t>* newSumHint = new list<Double_t>(sumHint->size()+pdfHint->size()) ;
merge(pdfHint->begin(),pdfHint->end(),sumHint->begin(),sumHint->end(),newSumHint->begin()) ;
delete sumHint ;
sumHint = newSumHint ;
}
}
}
return sumHint ;
}
void RooAddPdf::printMetaArgs(ostream& os) const
{
_pdfIter->Reset() ;
_coefIter->Reset() ;
Bool_t first(kTRUE) ;
RooAbsArg* coef, *pdf ;
if (_coefList.getSize()!=0) {
while((coef=(RooAbsArg*)_coefIter->Next())) {
if (!first) {
os << " + " ;
} else {
first = kFALSE ;
}
pdf=(RooAbsArg*)_pdfIter->Next() ;
os << coef->GetName() << " * " << pdf->GetName() ;
}
pdf = (RooAbsArg*) _pdfIter->Next() ;
if (pdf) {
os << " + [%] * " << pdf->GetName() ;
}
} else {
while((pdf=(RooAbsArg*)_pdfIter->Next())) {
if (!first) {
os << " + " ;
} else {
first = kFALSE ;
}
os << pdf->GetName() ;
}
}
os << " " ;
}