#include "RooFit.h"
#include "RooSimWSTool.h"
#include "RooMsgService.h"
#include "RooCategory.h"
#include "RooRealVar.h"
#include "RooAbsPdf.h"
#include "RooStringVar.h"
#include "RooSuperCategory.h"
#include "RooCatType.h"
#include "RooCustomizer.h"
#include "RooMultiCategory.h"
#include "RooSimultaneous.h"
#include "RooGlobalFunc.h"
#include "RooFracRemainder.h"
ClassImp(RooSimWSTool)
ClassImp(RooSimWSTool::BuildConfig)
ClassImp(RooSimWSTool::MultiBuildConfig)
ClassImp(RooSimWSTool::SplitRule)
ClassImp(RooSimWSTool::ObjBuildConfig)
ClassImp(RooSimWSTool::ObjSplitRule)
;
using namespace std ;
RooSimWSTool::RooSimWSTool(RooWorkspace& ws) : _ws(&ws)
{
}
RooSimWSTool::~RooSimWSTool()
{
}
RooSimultaneous* RooSimWSTool::build(const char* simPdfName, const char* protoPdfName, const RooCmdArg& arg1,const RooCmdArg& arg2,
const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
{
BuildConfig bc(protoPdfName,arg1,arg2,arg3,arg4,arg5,arg6) ;
return build(simPdfName,bc) ;
}
RooSimultaneous* RooSimWSTool::build(const char* simPdfName,BuildConfig& bc)
{
ObjBuildConfig* obc = validateConfig(bc) ;
if (!obc) return 0 ;
obc->print() ;
RooSimultaneous* ret = executeBuild(simPdfName,*obc) ;
delete obc ;
return ret ;
}
RooSimWSTool::ObjBuildConfig* RooSimWSTool::validateConfig(BuildConfig& bc)
{
ObjBuildConfig* obc = new ObjBuildConfig ;
if (bc._masterCatName.length()>0) {
obc->_masterCat = _ws->cat(bc._masterCatName.c_str()) ;
if (!obc->_masterCat) {
coutE(ObjectHandling) << "RooSimWSTool::build(" << GetName() << ") ERROR: associated workspace " << _ws->GetName()
<< " does not contain a category named " << bc._masterCatName
<< " that was designated as master index category in the build configuration" << endl ;
delete obc ;
return 0 ;
}
} else {
obc->_masterCat = 0 ;
}
map<string,SplitRule>::iterator pdfiter ;
for (pdfiter = bc._pdfmap.begin() ; pdfiter != bc._pdfmap.end() ; ++pdfiter) {
RooAbsPdf* pdf = _ws->pdf(pdfiter->second.GetName()) ;
if (!pdf) {
coutE(ObjectHandling) << "RooSimWSTool::build(" << GetName() << ") ERROR: associated workspace " << _ws->GetName()
<< " does not contain a pdf named " << pdfiter->second.GetName() << endl ;
delete obc ;
return 0 ;
}
ObjSplitRule osr ;
SplitRule& sr = pdfiter->second ;
map<string, pair<list<string>,string> >::iterator pariter ;
for (pariter=sr._paramSplitMap.begin() ; pariter!=sr._paramSplitMap.end() ; ++pariter) {
RooAbsArg* farg = _ws->fundArg(pariter->first.c_str()) ;
if (!farg) {
coutE(ObjectHandling) << "RooSimWSTool::build(" << GetName() << ") ERROR: associated workspace " << _ws->GetName()
<< " does not contain a variable named " << pariter->first.c_str()
<< " as specified in splitting rule of parameter " << pariter->first << " of p.d.f " << pdf << endl ;
delete obc ;
return 0 ;
}
if (!pdf->dependsOn(*farg)) {
coutE(ObjectHandling) << "RooSimWSTool::build(" << GetName() << ") ERROR: specified parameter " << pariter->first
<< " in split is not function of p.d.f " << pdf->GetName() << endl ;
delete obc ;
return 0 ;
}
RooArgSet splitCatSet ;
list<string>::iterator catiter ;
for (catiter = pariter->second.first.begin() ; catiter!=pariter->second.first.end() ; ++catiter) {
RooAbsCategory* cat = _ws->catfunc(catiter->c_str()) ;
if (!cat) {
coutE(ObjectHandling) << "RooSimWSTool::build(" << GetName() << ") ERROR: associated workspace " << _ws->GetName()
<< " does not contain a category named " << catiter->c_str()
<< " as specified in splitting rule of parameter " << pariter->first << " of p.d.f " << pdf << endl ;
delete obc ;
return 0 ;
}
splitCatSet.add(*cat) ;
}
TIterator* iter = splitCatSet.createIterator() ;
RooAbsArg* arg ;
while((arg=(RooAbsArg*)iter->Next())) {
RooArgSet tmp(splitCatSet) ;
tmp.remove(*arg) ;
if (arg->dependsOnValue(tmp)) {
coutE(InputArguments) << "RooSimWSTool::build(" << GetName() << ") ERROR: Ill defined split: splitting category function " << arg->GetName()
<< " used in composite split " << splitCatSet << " of parameter " << farg->GetName() << " of pdf " << pdf->GetName()
<< " depends on one or more of the other splitting categories in the composite split" << endl ;
delete obc ;
delete iter ;
return 0 ;
}
}
delete iter ;
if (pariter->second.second.size()>0) {
if (!dynamic_cast<RooAbsReal*>(farg)) {
coutE(InputArguments) << "RooSimWSTool::build(" << GetName() << ") ERROR: Constrained split specified in non real-valued parameter " << farg->GetName() << endl ;
delete obc ;
return 0 ;
}
}
osr._paramSplitMap[farg].first.add(splitCatSet) ;
osr._paramSplitMap[farg].second = pariter->second.second ;
if (obc->_masterCat) {
list<string>::iterator misi ;
for (misi=sr._miStateNameList.begin() ; misi!=sr._miStateNameList.end() ; ++misi) {
const RooCatType* ctype = obc->_masterCat->lookupType(misi->c_str(),kFALSE) ;
if (ctype==0) {
coutE(ObjectHandling) << "RooSimWSTool::build(" << GetName() << ") ERROR: master index category " << obc->_masterCat->GetName()
<< " does not have a state named " << *misi << " which was specified as state associated with p.d.f "
<< sr.GetName() << endl ;
delete obc ;
return 0 ;
}
osr._miStateList.push_back(ctype) ;
}
}
obc->_usedSplitCats.add(splitCatSet,kTRUE) ;
}
obc->_pdfmap[pdf] = osr ;
}
map<string,string>::iterator riter ;
for (riter=bc._restr.begin() ; riter!=bc._restr.end() ; ++riter) {
RooCategory* cat = _ws->cat(riter->first.c_str()) ;
if (!cat) {
coutE(ObjectHandling) << "RooSimWSTool::build(" << GetName() << ") ERROR: associated workspace " << _ws->GetName()
<< " does not contain a category named " << riter->first
<< " for which build was requested to be restricted to states " << riter->second << endl ;
delete obc ;
return 0 ;
}
char buf[4096] ;
list<const RooCatType*> rlist ;
strcpy(buf,riter->second.c_str()) ;
char* tok = strtok(buf,",") ;
while(tok) {
const RooCatType* ctype = cat->lookupType(tok,kFALSE) ;
if (!ctype) {
coutE(ObjectHandling) << "RooSimWSTool::build(" << GetName() << ") ERROR: restricted build category " << cat->GetName()
<< " does not have state " << tok << " as specified in restriction list" << endl ;
delete obc ;
return 0 ;
}
rlist.push_back(ctype) ;
tok = strtok(0,",") ;
}
obc->_restr[cat] = rlist ;
}
return obc ;
}
RooSimultaneous* RooSimWSTool::executeBuild(const char* simPdfName, ObjBuildConfig& obc)
{
RooArgSet cleanupList ;
RooAbsCategoryLValue* physCat = obc._masterCat ;
RooArgSet physModelSet ;
map<string,RooAbsPdf*> stateMap ;
map<RooAbsPdf*,ObjSplitRule>::iterator physIter = obc._pdfmap.begin() ;
while(physIter!=obc._pdfmap.end()) {
RooAbsPdf* physModel = physIter->first ;
physModelSet.add(*physModel,kTRUE) ;
list<const RooCatType*>::iterator stiter ;
for (stiter=physIter->second._miStateList.begin() ; stiter!=physIter->second._miStateList.end() ; ++stiter) {
stateMap[(*stiter)->GetName()] = physModel ;
}
++physIter ;
}
coutI(ObjectHandling) << "RooSimWSTool::executeBuild: list of prototype pdfs " << physModelSet << endl ;
RooArgSet splitCatSet(obc._usedSplitCats) ;
if (physCat) splitCatSet.add(*physCat) ;
RooSuperCategory masterSplitCat("masterSplitCat","Master splitting category",splitCatSet) ;
coutI(ObjectHandling) << "RooSimWSTool::executeBuild: list of splitting categories " << splitCatSet << endl ;
RooArgSet splitNodeListOwned ;
RooArgSet splitNodeListAll ;
TList* customizerList = new TList ;
TIterator* physMIter = physModelSet.createIterator() ;
RooAbsPdf* physModel ;
while((physModel=(RooAbsPdf*)physMIter->Next())) {
coutI(ObjectHandling) << "RooSimPdfBuilder::executeBuild: processing prototype pdf " << physModel->GetName() << endl ;
RooCustomizer* physCustomizer = new RooCustomizer(*physModel,masterSplitCat,splitNodeListOwned,&splitNodeListAll) ;
customizerList->Add(physCustomizer) ;
map<RooAbsArg*, pair<RooArgSet,string> >::iterator splitIter ;
for (splitIter = obc._pdfmap[physModel]._paramSplitMap.begin() ; splitIter != obc._pdfmap[physModel]._paramSplitMap.end() ; ++splitIter) {
RooArgSet& splitCatSetTmp = splitIter->second.first ;
string splitName = makeSplitName(splitCatSetTmp) ;
RooAbsCategory* splitCat = _ws->catfunc(splitName.c_str()) ;
if (!splitCat) {
splitCat = new RooMultiCategory(splitName.c_str(),splitName.c_str(),splitCatSetTmp) ;
cleanupList.addOwned(*splitCat) ;
_ws->import(*splitCat) ;
}
if(splitIter->second.second.size()>0) {
if (!splitCat->lookupType(splitIter->second.second.c_str())) {
coutE(InputArguments) << "RooSimWSTool::executeBuild(" << GetName() << ") ERROR: name of remainder state for constrained split, '"
<< splitIter->second.second << "' , does not match any state name of (composite) split category " << splitCat->GetName() << endl ;
return 0 ;
}
RooArgSet fracLeafList ;
TIterator* sctiter = splitCat->typeIterator() ;
RooCatType* type ;
while((type=(RooCatType*)sctiter->Next())) {
if (splitIter->second.second == type->GetName()) continue ;
TString splitLeafName(splitIter->first->GetName()) ;
splitLeafName.Append("_") ;
splitLeafName.Append(type->GetName()) ;
RooAbsArg* splitLeaf = _ws->fundArg(splitLeafName) ;
if (!splitLeaf) {
splitLeaf = (RooAbsArg*) splitIter->first->clone(splitLeafName) ;
_ws->import(*splitLeaf) ;
}
fracLeafList.add(*splitLeaf) ;
}
delete sctiter ;
RooFracRemainder* fracRem = new RooFracRemainder(Form("%s_%s",splitIter->first->GetName(),splitIter->second.second.c_str()),"Remainder fraction",fracLeafList) ;
cleanupList.addOwned(*fracRem) ;
_ws->import(*fracRem) ;
}
physCustomizer->splitArgs(*splitIter->first,*splitCat) ;
}
}
delete physMIter ;
splitNodeListAll.add(_ws->components()) ;
coutI(ObjectHandling) << "RooSimWSTool::executeBuild: configured customizers for all prototype pdfs" << endl ;
RooArgSet fitCatList ;
if (physCat) fitCatList.add(*physCat) ;
fitCatList.add(splitCatSet) ;
TIterator* fclIter = fitCatList.createIterator() ;
string mcatname = string(simPdfName) + "_index" ;
RooSuperCategory *fitCat = new RooSuperCategory(mcatname.c_str(),mcatname.c_str(),fitCatList) ;
cleanupList.addOwned(*fitCat) ;
RooSimultaneous* simPdf = new RooSimultaneous(simPdfName,simPdfName,*fitCat) ;
cleanupList.addOwned(*simPdf) ;
TIterator* fcIter = fitCat->typeIterator() ;
RooCatType* fcState ;
while((fcState=(RooCatType*)fcIter->Next())) {
fitCat->setLabel(fcState->GetName()) ;
fclIter->Reset() ;
RooAbsCategory* splitCat ;
Bool_t select(kFALSE) ;
if (obc._restr.size()>0) {
while((splitCat=(RooAbsCategory*)fclIter->Next())) {
list<const RooCatType*> slist = obc._restr[splitCat] ;
if (slist.size()==0) {
continue ;
}
list<const RooCatType*>::iterator sli ;
for (sli=slist.begin() ; sli!=slist.end() ; ++sli) {
if (string(splitCat->getLabel())==(*sli)->GetName()) {
select=kTRUE ;
}
}
}
if (!select) continue ;
} else {
select = kTRUE ;
}
RooCustomizer* physCustomizer ;
if (physCat) {
RooAbsPdf* pdf = stateMap[physCat->getLabel()] ;
if (pdf==0) continue ;
physCustomizer = (RooCustomizer*) customizerList->FindObject(pdf->GetName());
} else {
physCustomizer = (RooCustomizer*) customizerList->First() ;
}
coutI(ObjectHandling) << "RooSimWSTool::executeBuild: Customizing prototype pdf " << physCustomizer->GetName()
<< " for mode " << fcState->GetName() << endl ;
RooAbsPdf* fcPdf = (RooAbsPdf*) physCustomizer->build(masterSplitCat.getLabel(),kFALSE) ;
simPdf->addPdf(*fcPdf,fcState->GetName()) ;
}
delete fcIter ;
_ws->import(*simPdf,obc._conflProtocol) ;
customizerList->Delete() ;
delete customizerList ;
return (RooSimultaneous*) _ws->pdf(simPdf->GetName()) ;
}
std::string RooSimWSTool::makeSplitName(const RooArgSet& splitCatSet)
{
string name ;
TIterator* iter = splitCatSet.createIterator() ;
RooAbsArg* arg ;
Bool_t first=kTRUE ;
while((arg=(RooAbsArg*)iter->Next())) {
if (first) {
first=kFALSE;
} else {
name += "," ;
}
name += arg->GetName() ;
}
delete iter ;
return name ;
}
void RooSimWSTool::SplitRule::splitParameter(const char* paramNameList, const char* categoryNameList)
{
char paramBuf[4096] ;
char catBuf[4096] ;
strcpy(paramBuf,paramNameList) ;
strcpy(catBuf,categoryNameList) ;
list<string> catList ;
char* cat = strtok(catBuf,",") ;
while(cat) {
catList.push_back(cat) ;
cat = strtok(0,",") ;
}
char* param = strtok(paramBuf,",") ;
while(param) {
_paramSplitMap[param] = pair<list<string>,string>(catList,"") ;
param = strtok(0,",") ;
}
}
void RooSimWSTool::SplitRule::splitParameterConstrained(const char* paramNameList, const char* categoryNameList, const char* remainderStateName)
{
char paramBuf[4096] ;
char catBuf[4096] ;
strcpy(paramBuf,paramNameList) ;
strcpy(catBuf,categoryNameList) ;
list<string> catList ;
char* cat = strtok(catBuf,",") ;
while(cat) {
catList.push_back(cat) ;
cat = strtok(0,",") ;
}
char* param = strtok(paramBuf,",") ;
while(param) {
_paramSplitMap[param] = pair<list<string>,string>(catList,remainderStateName) ;
param = strtok(0,",") ;
}
}
void RooSimWSTool::SplitRule::configure(const RooCmdArg& arg1,const RooCmdArg& arg2,const RooCmdArg& arg3,
const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
{
list<const RooCmdArg*> cmdList ;
cmdList.push_back(&arg1) ; cmdList.push_back(&arg2) ;
cmdList.push_back(&arg3) ; cmdList.push_back(&arg4) ;
cmdList.push_back(&arg5) ; cmdList.push_back(&arg6) ;
list<const RooCmdArg*>::iterator iter ;
for (iter=cmdList.begin() ; iter!=cmdList.end() ; ++iter) {
if ((*iter)->opcode()==0) continue ;
string name = (*iter)->opcode() ;
if (name=="SplitParam") {
splitParameter((*iter)->getString(0),(*iter)->getString(1)) ;
} else if (name=="SplitParamConstrained") {
splitParameterConstrained((*iter)->getString(0),(*iter)->getString(1),(*iter)->getString(2)) ;
}
}
}
RooSimWSTool::BuildConfig::BuildConfig(const char* pdfName, SplitRule& sr)
{
internalAddPdf(pdfName,"",sr) ;
}
RooSimWSTool::BuildConfig::BuildConfig(const char* pdfName, const RooCmdArg& arg1,const RooCmdArg& arg2,
const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
{
SplitRule sr(pdfName) ;
sr.configure(arg1,arg2,arg3,arg4,arg5,arg6) ;
internalAddPdf(pdfName,"",sr) ;
_conflProtocol = RooFit::RenameConflictNodes(pdfName) ;
list<const RooCmdArg*> cmdList ;
cmdList.push_back(&arg1) ; cmdList.push_back(&arg2) ;
cmdList.push_back(&arg3) ; cmdList.push_back(&arg4) ;
cmdList.push_back(&arg5) ; cmdList.push_back(&arg6) ;
list<const RooCmdArg*>::iterator iter ;
for (iter=cmdList.begin() ; iter!=cmdList.end() ; ++iter) {
if ((*iter)->opcode()==0) continue ;
string name = (*iter)->opcode() ;
if (name=="Restrict") {
restrictBuild((*iter)->getString(0),(*iter)->getString(1)) ;
}
if (name=="RenameConflictNodes") {
_conflProtocol = *(*iter) ;
}
}
}
RooSimWSTool::BuildConfig::BuildConfig(const RooArgSet& )
{
}
void RooSimWSTool::BuildConfig::internalAddPdf(const char* pdfName, const char* miStateNameList,SplitRule& sr)
{
char buf[4096] ;
strcpy(buf,miStateNameList) ;
char* tok = strtok(buf,",") ;
while(tok) {
sr._miStateNameList.push_back(tok) ;
tok = strtok(0,",") ;
}
_pdfmap[pdfName] = sr ;
}
void RooSimWSTool::BuildConfig::restrictBuild(const char* catName, const char* stateList)
{
_restr[catName] = stateList ;
}
RooSimWSTool::MultiBuildConfig::MultiBuildConfig(const char* masterIndexCat)
{
_masterCatName = masterIndexCat ;
}
void RooSimWSTool::MultiBuildConfig::addPdf(const char* miStateList, const char* pdfName, const RooCmdArg& arg1,const RooCmdArg& arg2,
const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
{
SplitRule sr(pdfName) ;
sr.configure(arg1,arg2,arg3,arg4,arg5,arg6) ;
internalAddPdf(pdfName,miStateList,sr) ;
}
void RooSimWSTool::MultiBuildConfig::addPdf(const char* miStateList, const char* pdfName, SplitRule& sr)
{
internalAddPdf(pdfName,miStateList,sr) ;
}
RooSimWSTool::ObjSplitRule::~ObjSplitRule()
{
}
void RooSimWSTool::ObjBuildConfig::print()
{
map<RooAbsPdf*,ObjSplitRule>::iterator ri ;
for (ri = _pdfmap.begin() ; ri != _pdfmap.end() ; ++ri ) {
cout << "Splitrule for p.d.f " << ri->first->GetName() << endl ;
map<RooAbsArg*,pair<RooArgSet,string> >::iterator csi ;
for (csi = ri->second._paramSplitMap.begin() ; csi != ri->second._paramSplitMap.end() ; ++csi ) {
if (csi->second.second.length()>0) {
cout << " parameter " << csi->first->GetName() << " is split with constraint in categories " << csi->second.first
<< " with remainder in state " << csi->second.second << endl ;
} else {
cout << " parameter " << csi->first->GetName() << " is split with constraint in categories " << csi->second.first << endl ;
}
}
}
map<RooAbsCategory*,list<const RooCatType*> >::iterator riter ;
for (riter=_restr.begin() ; riter!=_restr.end() ; ++riter) {
cout << "Restricting build in category " << riter->first->GetName() << " to states " ;
list<const RooCatType*>::iterator i ;
for (i=riter->second.begin() ; i!=riter->second.end() ; i++) {
if (i!=riter->second.begin()) cout << "," ;
cout << (*i)->GetName() ;
}
cout << endl ;
}
}
Last change: Wed Jun 25 08:34:15 2008
Last generated: 2008-06-25 08:34
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.