#include "RooFit.h"
#include "TObjString.h"
#include "TObjString.h"
#include "RooSimultaneous.h"
#include "RooAbsCategoryLValue.h"
#include "RooPlot.h"
#include "RooCurve.h"
#include "RooRealVar.h"
#include "RooAddPdf.h"
#include "RooAbsData.h"
#include "Roo1DTable.h"
#include "RooSimGenContext.h"
#include "RooDataSet.h"
#include "RooCmdConfig.h"
#include "RooNameReg.h"
#include "RooGlobalFunc.h"
#include "RooNameReg.h"
ClassImp(RooSimultaneous)
;
RooSimultaneous::RooSimultaneous(const char *name, const char *title,
RooAbsCategoryLValue& indexCat) :
RooAbsPdf(name,title),
_plotCoefNormSet("plotCoefNormSet","plotCoefNormSet",this,kFALSE,kFALSE),
_normListMgr(10),
_indexCat("indexCat","Index category",this,indexCat),
_numPdf(0),
_anyCanExtend(kFALSE),
_anyMustExtend(kFALSE)
{
}
RooSimultaneous::RooSimultaneous(const char *name, const char *title,
const RooArgList& pdfList, RooAbsCategoryLValue& indexCat) :
RooAbsPdf(name,title),
_plotCoefNormSet("plotCoefNormSet","plotCoefNormSet",this,kFALSE,kFALSE),
_normListMgr(10),
_indexCat("indexCat","Index category",this,indexCat),
_numPdf(0),
_anyCanExtend(kFALSE),
_anyMustExtend(kFALSE)
{
if (pdfList.getSize() != indexCat.numTypes()) {
cout << "RooSimultaneous::ctor(" << GetName()
<< " ERROR: Number PDF list entries must match number of index category states, no PDFs added" << endl ;
return ;
}
TIterator* pIter = pdfList.createIterator() ;
TIterator* cIter = indexCat.typeIterator() ;
RooAbsPdf* pdf ;
RooCatType* type ;
while ((pdf=(RooAbsPdf*)pIter->Next())) {
type = (RooCatType*) cIter->Next() ;
addPdf(*pdf,type->GetName()) ;
if (pdf->canBeExtended()) _anyCanExtend = kTRUE ;
if (pdf->mustBeExtended()) _anyMustExtend = kTRUE ;
}
delete pIter ;
delete cIter ;
}
RooSimultaneous::RooSimultaneous(const RooSimultaneous& other, const char* name) :
RooAbsPdf(other,name),
_plotCoefNormSet("plotCoefNormSet",this,other._plotCoefNormSet),
_normListMgr(other._normListMgr),
_indexCat("indexCat",this,other._indexCat),
_numPdf(other._numPdf),
_anyCanExtend(other._anyCanExtend),
_anyMustExtend(other._anyMustExtend)
{
TIterator* pIter = other._pdfProxyList.MakeIterator() ;
RooRealProxy* proxy ;
while ((proxy=(RooRealProxy*)pIter->Next())) {
_pdfProxyList.Add(new RooRealProxy(proxy->GetName(),this,*proxy)) ;
}
delete pIter ;
}
RooSimultaneous::~RooSimultaneous()
{
_pdfProxyList.Delete() ;
}
RooAbsPdf* RooSimultaneous::getPdf(const char* catName) const
{
RooRealProxy* proxy = (RooRealProxy*) _pdfProxyList.FindObject(catName) ;
return proxy ? ((RooAbsPdf*)proxy->absArg()) : 0 ;
}
Bool_t RooSimultaneous::addPdf(const RooAbsPdf& pdf, const char* catLabel)
{
if (pdf.dependsOn(_indexCat.arg())) {
cout << "RooSimultaneous::addPdf(" << GetName() << "): ERROR, PDF " << pdf.GetName()
<< " overlaps with index category " << _indexCat.arg().GetName() << endl ;
return kTRUE ;
}
if (_pdfProxyList.FindObject(catLabel)) {
cout << "RooSimultaneous::addPdf(" << GetName() << "): ERROR, index state "
<< catLabel << " has already an associated PDF" << endl ;
return kTRUE ;
}
TObject* proxy = new RooRealProxy(catLabel,catLabel,this,(RooAbsPdf&)pdf) ;
_pdfProxyList.Add(proxy) ;
_numPdf += 1 ;
if (pdf.canBeExtended()) _anyCanExtend = kTRUE ;
if (pdf.mustBeExtended()) _anyMustExtend = kTRUE ;
return kFALSE ;
}
Double_t RooSimultaneous::evaluate() const
{
RooRealProxy* proxy = (RooRealProxy*) _pdfProxyList.FindObject((const char*) _indexCat) ;
assert(proxy!=0) ;
return ((RooAbsPdf*)(proxy->absArg()))->getVal(_normMgr.lastNormSet()) ;
}
Double_t RooSimultaneous::expectedEvents(const RooArgSet* nset) const
{
if (nset->contains(_indexCat.arg())) {
Double_t sum(0) ;
TIterator* iter = _pdfProxyList.MakeIterator() ;
RooRealProxy* proxy ;
while((proxy=(RooRealProxy*)iter->Next())) {
sum += ((RooAbsPdf*)(proxy->absArg()))->expectedEvents(nset) ;
}
delete iter ;
return sum ;
} else {
RooRealProxy* proxy = (RooRealProxy*) _pdfProxyList.FindObject((const char*) _indexCat) ;
assert(proxy!=0) ;
return ((RooAbsPdf*)(proxy->absArg()))->expectedEvents(nset);
}
}
Int_t RooSimultaneous::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
const RooArgSet* normSet, const char* rangeName) const
{
analVars.add(allVars) ;
Int_t code ;
RooArgList* normList = _normListMgr.getNormList(this,normSet,&analVars,0,RooNameReg::ptr(rangeName)) ;
if (normList) {
code = _normListMgr.lastIndex() ;
return code+1 ;
}
TIterator* iter = _pdfProxyList.MakeIterator() ;
normList = new RooArgList("normList") ;
RooRealProxy* proxy ;
while((proxy=(RooRealProxy*)iter->Next())) {
RooAbsReal* pdfInt = proxy->arg().createIntegral(analVars,normSet,0,rangeName) ;
normList->addOwned(*pdfInt) ;
}
delete iter ;
code = _normListMgr.setNormList(this,normSet,&analVars,normList,RooNameReg::ptr(rangeName)) ;
return code+1 ;
}
Double_t RooSimultaneous::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* ) const
{
if (code==0) {
return getVal(normSet) ;
}
RooArgList* normIntList = _normListMgr.getNormListByIndex(code-1) ;
RooRealProxy* proxy = (RooRealProxy*) _pdfProxyList.FindObject((const char*) _indexCat) ;
Int_t idx = _pdfProxyList.IndexOf(proxy) ;
return ((RooAbsReal*)normIntList->at(idx))->getVal(normSet) ;
}
Bool_t RooSimultaneous::redirectServersHook(const RooAbsCollection& newServerList, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t )
{
Bool_t ret(kFALSE) ;
Int_t i ;
for (i=0 ; i<_normListMgr.cacheSize() ; i++) {
RooArgList* nlist = _normListMgr.getNormListByIndex(i) ;
TIterator* iter = nlist->createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
ret |= arg->recursiveRedirectServers(newServerList,mustReplaceAll,nameChange) ;
}
delete iter ;
}
return ret ;
}
RooPlot* RooSimultaneous::plotOn(RooPlot *frame, RooLinkedList& cmdList) const
{
if (plotSanityChecks(frame)) return frame ;
RooCmdConfig pc(Form("RooSimultaneous::plotOn(%s)",GetName())) ;
pc.defineDouble("scaleFactor","Normalization",0,1.0) ;
pc.defineInt("scaleType","Normalization",0,RooAbsPdf::Relative) ;
pc.defineObject("projSet","Project",0) ;
pc.defineObject("sliceSet","SliceVars",0) ;
pc.defineObject("projDataSet","ProjData",0) ;
pc.defineObject("projData","ProjData",1) ;
pc.defineMutex("Project","SliceVars") ;
pc.allowUndefined() ;
pc.process(cmdList) ;
if (!pc.ok(kTRUE)) {
return frame ;
}
const RooAbsData* projData = (const RooAbsData*) pc.getObject("projData") ;
const RooArgSet* projDataSet = (const RooArgSet*) pc.getObject("projDataSet") ;
const RooArgSet* sliceSet = (const RooArgSet*) pc.getObject("sliceSet") ;
const RooArgSet* projSet = (const RooArgSet*) pc.getObject("projSet") ;
Double_t scaleFactor = pc.getDouble("scaleFactor") ;
ScaleType stype = (ScaleType) pc.getInt("scaleType") ;
if (!projData) {
cout << "RooSimultaneous::plotOn(" << GetName() << ") ERROR: must have a projection dataset for index category" << endl ;
return frame ;
}
RooArgSet projectedVars ;
if (sliceSet) {
makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,kTRUE) ;
TIterator* iter = sliceSet->createIterator() ;
RooAbsArg* sliceArg ;
while((sliceArg=(RooAbsArg*)iter->Next())) {
RooAbsArg* arg = projectedVars.find(sliceArg->GetName()) ;
if (arg) {
projectedVars.remove(*arg) ;
} else {
cout << "RooAbsReal::plotOn(" << GetName() << ") slice variable "
<< sliceArg->GetName() << " was not projected anyway" << endl ;
}
}
delete iter ;
} else if (projSet) {
makeProjectionSet(frame->getPlotVar(),projSet,projectedVars,kFALSE) ;
} else {
makeProjectionSet(frame->getPlotVar(),frame->getNormVars(),projectedVars,kTRUE) ;
}
Bool_t projIndex(kFALSE) ;
if (!_indexCat.arg().isDerived()) {
if (!projData->get()->find(_indexCat.arg().GetName())) {
cout << "RooSimultaneous::plotOn(" << GetName() << ") ERROR: Projection over index category "
<< "requested, but projection data set doesn't contain index category" << endl ;
return frame ;
}
if (projectedVars.find(_indexCat.arg().GetName())) {
projIndex=kTRUE ;
}
} else {
TIterator* sIter = _indexCat.arg().serverIterator() ;
RooAbsArg* server ;
RooArgSet projIdxServers ;
Bool_t anyServers(kFALSE) ;
while((server=(RooAbsArg*)sIter->Next())) {
if (projectedVars.find(server->GetName())) {
anyServers=kTRUE ;
projIdxServers.add(*server) ;
}
}
delete sIter ;
sIter = projIdxServers.createIterator() ;
Bool_t allServers(kTRUE) ;
while((server=(RooAbsArg*)sIter->Next())) {
if (!projData->get()->find(server->GetName())) {
allServers=kFALSE ;
}
}
delete sIter ;
if (!allServers) {
cout << "RooSimultaneous::plotOn(" << GetName()
<< ") ERROR: Projection dataset doesn't contain complete set of index category dependents" << endl ;
return frame ;
}
if (anyServers) {
projIndex = kTRUE ;
}
}
Roo1DTable* wTable = projData->table(_indexCat.arg()) ;
if (!projIndex) {
cout << "RooSimultaneous::plotOn(" << GetName() << ") plot on " << frame->getPlotVar()->GetName()
<< " represents a slice in the index category (" << _indexCat.arg().GetName() << ")" << endl ;
const RooAbsData* projDataTmp(projData) ;
if (projData) {
RooArgSet* indexCatComps = _indexCat.arg().getObservables(frame->getNormVars());
TString cutString ;
TIterator* compIter = indexCatComps->createIterator() ;
RooAbsCategory* idxComp ;
Bool_t first(kTRUE) ;
while((idxComp=(RooAbsCategory*)compIter->Next())) {
if (!first) {
cutString.Append("&&") ;
} else {
first=kFALSE ;
}
cutString.Append(Form("%s==%d",idxComp->GetName(),idxComp->getIndex())) ;
}
delete compIter ;
RooArgSet projDataVars(*projData->get()) ;
projDataVars.remove(*indexCatComps,kTRUE,kTRUE) ;
projDataTmp = ((RooAbsData*)projData)->reduce(projDataVars,cutString) ;
delete indexCatComps ;
}
RooLinkedList cmdList2(cmdList) ;
RooCmdArg tmp1 = RooFit::Normalization(scaleFactor*wTable->getFrac(_indexCat.arg().getLabel()),stype) ;
RooCmdArg tmp2 = RooFit::ProjWData(*projDataSet,*projDataTmp) ;
if (!cmdList.find("Asymmetry")) {
cmdList2.Add(&tmp1) ;
}
cmdList2.Add(&tmp2) ;
RooPlot* retFrame = getPdf(_indexCat.arg().getLabel())->plotOn(frame,cmdList2) ;
delete wTable ;
return retFrame ;
}
RooArgSet* idxCloneSet = (RooArgSet*) RooArgSet(_indexCat.arg()).snapshot(kTRUE) ;
RooAbsCategoryLValue* idxCatClone = (RooAbsCategoryLValue*) idxCloneSet->find(_indexCat.arg().GetName()) ;
RooArgSet* idxCompSliceSet = _indexCat.arg().getObservables(frame->getNormVars()) ;
idxCompSliceSet->remove(projectedVars,kTRUE,kTRUE) ;
TIterator* idxCompSliceIter = idxCompSliceSet->createIterator() ;
RooArgList pdfCompList ;
RooArgList wgtCompList ;
RooRealProxy* proxy ;
TIterator* pIter = _pdfProxyList.MakeIterator() ;
Double_t sumWeight(0) ;
while((proxy=(RooRealProxy*)pIter->Next())) {
idxCatClone->setLabel(proxy->name()) ;
Bool_t skip(kFALSE) ;
idxCompSliceIter->Reset() ;
RooAbsCategory* idxSliceComp ;
while((idxSliceComp=(RooAbsCategory*)idxCompSliceIter->Next())) {
RooAbsCategory* idxComp = (RooAbsCategory*) idxCloneSet->find(idxSliceComp->GetName()) ;
if (idxComp->getIndex()!=idxSliceComp->getIndex()) {
skip=kTRUE ;
break ;
}
}
if (skip) continue ;
RooRealVar *wgtVar = new RooRealVar(proxy->name(),"coef",wTable->getFrac(proxy->name())) ;
wgtCompList.addOwned(*wgtVar) ;
sumWeight += wTable->getFrac(proxy->name()) ;
pdfCompList.add(proxy->arg()) ;
}
TString plotVarName(GetName()) ;
RooAddPdf *plotVar = new RooAddPdf(plotVarName,"weighted sum of RS components",pdfCompList,wgtCompList) ;
if (_plotCoefNormSet.getSize()>0) {
plotVar->fixAddCoefNormalization(_plotCoefNormSet) ;
}
RooAbsData* projDataTmp(0) ;
RooArgSet projSetTmp ;
if (projData) {
TString cutString ;
if (idxCompSliceSet->getSize()>0) {
idxCompSliceIter->Reset() ;
RooAbsCategory* idxSliceComp ;
Bool_t first(kTRUE) ;
while((idxSliceComp=(RooAbsCategory*)idxCompSliceIter->Next())) {
if (!first) {
cutString.Append("&&") ;
} else {
first=kFALSE ;
}
cutString.Append(Form("%s==%d",idxSliceComp->GetName(),idxSliceComp->getIndex())) ;
}
}
RooArgSet projDataVars(*projData->get()) ;
RooArgSet* idxCatServers = _indexCat.arg().getObservables(frame->getNormVars()) ;
projDataVars.remove(*idxCatServers,kTRUE,kTRUE) ;
if (idxCompSliceSet->getSize()>0) {
projDataTmp = ((RooAbsData*)projData)->reduce(projDataVars,cutString) ;
} else {
projDataTmp = ((RooAbsData*)projData)->reduce(projDataVars) ;
}
if (projSet) {
projSetTmp.add(*projSet) ;
projSetTmp.remove(*idxCatServers,kTRUE,kTRUE);
}
delete idxCatServers ;
}
if (_indexCat.arg().isDerived() && idxCompSliceSet->getSize()>0) {
cout << "RooSimultaneous::plotOn(" << GetName() << ") plot on " << frame->getPlotVar()->GetName()
<< " represents a slice in index category components " ; idxCompSliceSet->Print("1") ;
RooArgSet* idxCompProjSet = _indexCat.arg().getObservables(frame->getNormVars()) ;
idxCompProjSet->remove(*idxCompSliceSet,kTRUE,kTRUE) ;
if (idxCompProjSet->getSize()>0) {
cout << "RooSimultaneous::plotOn(" << GetName() << ") plot on " << frame->getPlotVar()->GetName()
<< " averages with data index category components " ; idxCompProjSet->Print("1") ;
}
delete idxCompProjSet ;
} else {
cout << "RooSimultaneous::plotOn(" << GetName() << ") plot on " << frame->getPlotVar()->GetName()
<< " averages with data index category (" << _indexCat.arg().GetName() << ")" << endl ;
}
RooLinkedList cmdList2(cmdList) ;
RooCmdArg tmp1 = RooFit::Normalization(scaleFactor*sumWeight,stype) ;
RooCmdArg tmp2 = RooFit::ProjWData(*projDataSet,*projDataTmp) ;
if (!cmdList.find("Asymmetry")) {
cmdList2.Add(&tmp1) ;
}
cmdList2.Add(&tmp2) ;
RooPlot* frame2 ;
if (projSetTmp.getSize()>0) {
RooCmdArg tmp3 = RooFit::Project(projSetTmp) ;
cmdList2.Add(&tmp3) ;
frame2 = plotVar->plotOn(frame,cmdList2) ;
} else {
frame2 = plotVar->plotOn(frame,cmdList2) ;
}
delete pIter ;
delete wTable ;
delete idxCloneSet ;
delete idxCompSliceIter ;
delete idxCompSliceSet ;
delete plotVar ;
if (projDataTmp) delete projDataTmp ;
return frame2 ;
}
RooPlot* RooSimultaneous::plotOn(RooPlot *frame, Option_t* drawOptions, Double_t scaleFactor,
ScaleType stype, const RooAbsData* projData, const RooArgSet* projSet,
Double_t , Bool_t , const RooArgSet* ,
Double_t , Double_t , RooCurve::WingMode ) const
{
RooLinkedList cmdList ;
cmdList.Add(new RooCmdArg(RooFit::DrawOption(drawOptions))) ;
cmdList.Add(new RooCmdArg(RooFit::Normalization(scaleFactor,stype))) ;
if (projData) cmdList.Add(new RooCmdArg(RooFit::ProjWData(*projData))) ;
if (projSet) cmdList.Add(new RooCmdArg(RooFit::Project(*projSet))) ;
RooPlot* ret = plotOn(frame,cmdList) ;
cmdList.Delete() ;
return ret ;
}
void RooSimultaneous::selectNormalization(const RooArgSet* normSet, Bool_t )
{
_plotCoefNormSet.removeAll() ;
if (normSet) _plotCoefNormSet.add(*normSet) ;
}
void RooSimultaneous::selectNormalizationRange(const char* normRange, Bool_t )
{
_plotCoefNormRange = RooNameReg::ptr(normRange) ;
}
RooAbsGenContext* RooSimultaneous::genContext(const RooArgSet &vars, const RooDataSet *prototype,
const RooArgSet* auxProto, Bool_t verbose) const
{
const char* idxCatName = _indexCat.arg().GetName() ;
const RooArgSet* protoVars = prototype ? prototype->get() : 0 ;
if (vars.find(idxCatName) || (protoVars && protoVars->find(idxCatName))) {
return new RooSimGenContext(*this,vars,prototype,auxProto,verbose) ;
} else if (_indexCat.arg().isDerived()) {
Bool_t anyServer(kFALSE), allServers(kTRUE) ;
if (prototype) {
TIterator* sIter = _indexCat.arg().serverIterator() ;
RooAbsArg* server ;
while((server=(RooAbsArg*)sIter->Next())) {
if (prototype->get()->find(server->GetName())) {
anyServer=kTRUE ;
} else {
allServers=kFALSE ;
}
}
delete sIter ;
} else {
allServers=kTRUE ;
}
if (allServers) {
return new RooSimGenContext(*this,vars,prototype,auxProto,verbose) ;
} else if (!allServers && anyServer) {
cout << "RooSimultaneous::genContext: ERROR: prototype must include either all "
<< " components of the RooSimultaneous index category or none " << endl ;
return 0 ;
}
}
RooRealProxy* proxy = (RooRealProxy*) _pdfProxyList.FindObject(_indexCat.arg().getLabel()) ;
if (!proxy) {
cout << "RooSimultaneous::genContext(" << GetName()
<< ") ERROR: no PDF associated with current state ("
<< _indexCat.arg().GetName() << "=" << _indexCat.arg().getLabel() << ")" << endl ;
return 0 ;
}
return ((RooAbsPdf*)proxy->absArg())->genContext(vars,prototype,auxProto,verbose) ;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.