467 _protoPdfSet(protoPdfSet)
483 buildConfig->
addOwned(*
new RooStringVar(
"physModels",
"List and mapping of physics models to include in build",
"",4096)) ;
484 buildConfig->
addOwned(*
new RooStringVar(
"splitCats",
"List of categories used for splitting",
"",1024)) ;
508 const RooArgSet* auxSplitCats,
bool verbose)
510 const char* spaceChars =
" \t" ;
513 int buflen = strlen(((
RooStringVar*)buildConfig.
find(
"physModels"))->getVal())+1 ;
514 std::vector<char> bufContainer(buflen);
515 char *buf = bufContainer.data() ;
517 strlcpy(buf,((
RooStringVar*)buildConfig.
find(
"physModels"))->getVal(),buflen) ;
519 if (strstr(buf,
" : ")) {
520 const char* physCatName = strtok(buf,spaceChars) ;
523 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR physics index category " << physCatName
524 <<
" not found in dataset variables" << endl ;
527 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: category indexing physics model: " << physCatName << endl ;
535 strtok(0,spaceChars) ;
536 physName = strtok(0,spaceChars) ;
538 physName = strtok(buf,spaceChars) ;
542 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR: No models specified, nothing to do!" << endl ;
553 if (strchr(physName,
'=')) {
556 coutW(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: WARNING: without physCat specification "
557 <<
"<physCatState>=<pdfProtoName> association is meaningless" << endl ;
559 stateName = physName ;
560 physName = strchr(stateName,
'=') ;
565 stateName = physName ;
570 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR requested physics model "
571 << (physName?physName:
"(null)") <<
" is not defined" << endl ;
576 if (stateMap.
find(stateName)) {
577 coutW(InputArguments) <<
"RooSimPdfBuilder::buildPdf: WARNING: multiple PDFs specified for state "
578 << stateName <<
", only first will be used" << endl ;
583 physModelSet.
add(*physModel,
true) ;
589 physName = strtok(0,spaceChars) ;
592 }
else if (physCat==0) {
593 coutW(InputArguments) <<
"RooSimPdfBuilder::buildPdf: WARNING: without physCat specification, only the first model will be used" << endl ;
597 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: list of physics models " << physModelSet << endl ;
602 TList splitStateList ;
605 buflen = strlen(((
RooStringVar*)buildConfig.
find(
"splitCats"))->getVal())+1 ;
606 bufContainer.resize(buflen);
607 buf = bufContainer.data();
609 strlcpy(buf,((
RooStringVar*)buildConfig.
find(
"splitCats"))->getVal(),buflen) ;
611 char *catName = strtok(buf,spaceChars) ;
617 if (strchr(catName,
'(')) {
619 catName = R__STRTOK_R(catName,
"(",&tokenPtr) ;
620 stateList = R__STRTOK_R(0,
")",&tokenPtr) ;
628 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR requested split category " << (catName?catName:
"(null)")
629 <<
" is not a RooCategory in the dataset" << endl ;
632 splitCatSet.
add(*splitCat) ;
636 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: splitting of category " << catName
637 <<
" restricted to states (" << stateList <<
")" << endl ;
642 splitStateList.
Add(slist) ;
644 char* stateLabel = R__STRTOK_R(stateList,
",",&tokenPtr) ;
650 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR splitCat " << splitCat->
GetName()
651 <<
" doesn't have a state named " << stateLabel << endl ;
657 stateLabel = R__STRTOK_R(0,
",",&tokenPtr) ;
661 catName = strtok(0,spaceChars) ;
663 if (physCat) splitCatSet.
add(*physCat) ;
664 RooSuperCategory masterSplitCat(
"masterSplitCat",
"Master splitting category",splitCatSet) ;
666 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: list of splitting categories " << splitCatSet << endl ;
672 if (!std::unique_ptr<RooArgSet>{auxSplitCats->
snapshot(
true)}) {
673 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf(" <<
GetName() <<
") Couldn't deep-clone set auxiliary splitcats, abort." << endl ;
677 for (
const auto arg : *auxSplitCats) {
683 coutW(InputArguments) <<
"RooSimPdfBuilder::buildPdf: WARNING: dataset contains a fundamental splitting category " << endl
684 <<
" with the same name as an auxiliary split function (" << aux->
GetName() <<
"). " << endl
685 <<
" Auxiliary split function will be ignored" << endl ;
690 std::unique_ptr<RooArgSet> parSet{aux->
getParameters(splitCatSet)} ;
691 if (parSet->getSize()>0) {
692 coutW(InputArguments) <<
"RooSimPdfBuilder::buildPdf: WARNING: ignoring auxiliary category " << aux->
GetName()
693 <<
" because it has servers that are not listed in splitCatSet: " << *parSet << endl ;
701 auxSplitSet.
add(*aux) ;
704 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: list of auxiliary splitting categories " << auxSplitSet << endl ;
707 TList customizerList;
710 for (
const auto arg : physModelSet) {
711 auto physModel =
static_cast<const RooAbsPdf*
>(arg);
713 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: processing physics model " << physModel->
GetName() << endl ;
716 customizerList.
Add(physCustomizer) ;
722 enum Mode { SplitCat, Colon, ParamList } ;
723 Mode mode(SplitCat) ;
725 const char* splitCatName ;
733 splitCatName = token.data();
735 if (token.find(
',') != std::string::npos) {
740 const std::string origCompCatName{splitCatName} ;
745 for (
const auto& catName2 :
ROOT::Split(token,
",")) {
754 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR " << catName2
755 <<
" not found in the primary or auxilary splitcat list" << endl ;
761 compCatSet.
add(*cat) ;
767 for (
const auto theArg : compCatSet) {
770 if (theArg->dependsOnValue(tmp)) {
771 coutE(InputArguments)
772 <<
"RooSimPdfBuilder::buildPDF: ERROR: Ill defined split: auxiliary splitting category "
773 << theArg->GetName() <<
" used in composite split " << compCatSet
774 <<
" depends on one or more of the other splitting categories in the composite split"
784 splitCat =
new RooMultiCategory(origCompCatName.c_str(), origCompCatName.c_str(), compCatSet) ;
800 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR splitting category "
801 << splitCatName <<
" not found in the primary or auxiliary splitcat list" << endl ;
814 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR in parsing, expected ':' after "
815 << splitCat <<
", found " << token << endl ;
827 std::unique_ptr<RooArgSet> paramList{physModel->getParameters(dependents)} ;
830 std::unique_ptr<RooArgSet> compList{physModel->getComponents()} ;
831 paramList->
add(*compList) ;
833 const bool lastCharIsComma = (token[token.size()-1]==
',') ;
835 for (
const auto& paramName :
ROOT::Split(token,
",",
true)) {
837 std::string remainderState;
839 const auto pos = paramName.find(
'[');
840 if (pos != std::string::npos) {
841 const auto posEnd = paramName.find(
']');
842 remainderState = paramName.substr(pos+1, posEnd - pos - 1);
848 if (!remainderState.empty()) {
849 if (!splitCat->
hasLabel(remainderState)) {
850 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR fraction split of parameter "
851 << paramName <<
" has invalid remainder state name: " << remainderState << endl ;
858 RooAbsArg* param = paramList->find(paramName.data()) ;
860 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR " << paramName
861 <<
" is not a parameter of physics model " << physModel->
GetName() << endl ;
866 splitParamList.
add(*param) ;
869 if (!remainderState.empty()) {
873 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR fraction split requested of non-real valued parameter "
884 if (remStateSplitList && !remStateSplitList->
FindObject(remainderState.data())) {
885 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR " << paramName
886 <<
" remainder state " << remainderState <<
" in parameter split "
887 << param->
GetName() <<
" is not actually being built" << endl ;
893 std::unique_ptr<TIterator> iter{splitCat->
typeIterator()} ;
896 std::string formExpr{
"1"} ;
902 if (std::string{
type->GetName()} != remainderState)
continue ;
905 if (remStateSplitList && !remStateSplitList->
FindObject(
type->GetName())) {
910 const auto splitLeafName = std::string{param->
GetName()} +
"_" +
type->GetName();
920 fracLeafList.
add(*splitLeaf) ;
921 formExpr +=
Form(
"-@%d",i++) ;
925 const auto remLeafName = std::string{param->
GetName()} +
"_" + remainderState;
932 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: creating remainder fraction formula for " << remainderState
933 <<
" specialization of split parameter " << param->
GetName() <<
" " << formExpr << endl ;
939 physCustomizer->
splitArgs(splitParamList,*splitCat) ;
941 if (!lastCharIsComma) mode = SplitCat ;
946 if (mode!=SplitCat) {
947 coutE(InputArguments) <<
"RooSimPdfBuilder::buildPdf: ERROR in parsing, expected "
948 << (mode==Colon?
":":
"parameter list") <<
" in " << ruleStr->
getVal() << endl ;
953 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: no splitting rules for " << physModel->GetName() << endl ;
957 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: configured customizers for all physics models" << endl ;
959 customizerList.
Print() ;
964 if (physCat) fitCatList.
add(*physCat) ;
965 fitCatList.
add(splitCatSet) ;
972 std::unique_ptr<TIterator> fcIter{fitCat->
typeIterator()} ;
975 while((fcState=(
RooCatType*)fcIter->Next())) {
981 for (
const auto arg : fitCatList) {
986 if (!slist) continue ;
992 if (!select) continue ;
999 if (!physNameVar) continue ;
1005 coutI(ObjectHandling) <<
"RooSimPdfBuilder::buildPdf: Customizing physics model " << physCustomizer->
GetName()
1006 <<
" for mode " << fcState->
GetName() << endl ;
1016 splitStateList.
Delete() ;
char * Form(const char *fmt,...)
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
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_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Recursively replace all servers with the new servers in newSet.
virtual TObject * clone(const char *newname=0) const =0
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
RooAbsCategory is the base class for objects that represent a discrete value with a finite number of ...
bool hasLabel(const std::string &label) const
Check if a state with name label exists.
virtual const char * getCurrentLabel() const
Return label string of current state.
TIterator * typeIterator() const
const RooCatType * lookupType(value_type index, Bool_t printError=kFALSE) const
Find our type corresponding to the specified index, or return nullptr for no match.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
virtual Bool_t addOwned(RooAbsArg &var, Bool_t silent=kFALSE)
Add an argument and transfer the ownership to the collection.
void useHashMapForFind(bool flag) const
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
RooArgList is a container object that can hold multiple RooAbsArg objects.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
RooCatType is an auxilary class for RooAbsCategory and defines a a single category state.
virtual const Text_t * GetName() const
Returns name of object.
RooCategory is an object to represent discrete states.
RooCustomizer is a factory class to produce clones of a prototype composite PDF object with the same ...
void splitArgs(const RooArgSet &argSet, const RooAbsCategory &splitCat)
Split all arguments in 'set' into individualized clones for each defined state of 'splitCat'.
RooAbsArg * build(const char *masterCatState, Bool_t verbose=kFALSE)
Build a clone of the prototype executing all registered 'replace' rules and 'split' rules for the mas...
RooMultiCategory connects several RooAbsCategory objects into a single category.
This tool has now been superseded by RooSimWSTool
RooArgSet _compSplitCatSet
std::list< RooSuperCategory * > _fitCatList
std::list< RooSimultaneous * > _simPdfList
RooArgSet * createProtoBuildConfig()
Make RooArgSet of configuration objects.
void addSpecializations(const RooArgSet &specSet)
RooArgSet _splitNodeListOwned
TList _retiredCustomizerList
RooSimultaneous * buildPdf(const RooArgSet &buildConfig, const RooArgSet &dependents, const RooArgSet *auxSplitCats=0, bool verbose=false)
Initialize needed components.
RooSimPdfBuilder(const RooArgSet &pdfProtoList)
RooSimultaneous facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
Bool_t addPdf(const RooAbsPdf &pdf, const char *catLabel)
Associate given PDF with index category state label 'catLabel'.
RooStringVar is a RooAbsArg implementing string values.
const char * getVal() const
The RooSuperCategory can join several RooAbsCategoryLValue objects into a single category.
virtual Bool_t setLabel(const char *label, Bool_t printError=kTRUE) override
Set the value of the super category by specifying the state name.
virtual void Print(Option_t *option="") const
Default print for collections, calls Print(option, 1).
void SetName(const char *name)
virtual void AddAll(const TCollection *col)
Add all objects from collection col to this collection.
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
virtual const char * GetName() const
Returns name of object.
Mother of all ROOT objects.
virtual const char * GetName() const
Returns name of object.
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.