Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooSimWSTool.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17//////////////////////////////////////////////////////////////////////////////
18/// \class RooSimWSTool
19/// The RooSimWSTool is a tool operating on RooWorkspace objects that
20/// can clone PDFs into a series of variations that are joined together
21/// into a RooSimultaneous PDF.
22///
23/// ## Splitting a single PDF
24/// The simplest use case is to take a workspace PDF as prototype and
25/// "split" a parameter of that PDF into two specialized parameters
26/// depending on a category in the dataset.
27///
28/// For example, given a Gaussian
29/// PDF \f$ G(x \,|\, m,s) \f$ we want to construct a \f$ G_a(x \,|\, m_a,s) \f$ and a \f$ G_b(x \,|\, m_b,s) \f$
30/// with different mean parameters to be fit to a dataset with observables
31/// \f$ (x,c) \f$ where \f$ c \f$ is a category with states 'a' and 'b'.
32///
33/// Using RooSimWSTool, one can create a simultaneous PDF from \f$ G_a \f$ and \f$ G_b \f$
34/// from \f$ G \f$ with the following commands:
35/// ```
36/// RooSimWSTool wst(wspace);
37/// wst.build("G_sim", "G", SplitParam("m","c"));
38/// ```
39///
40/// #### Splitting using a product category
41/// From this simple example one can go to builds of arbitrary complexity
42/// by specifying multiple SplitParam arguments on multiple parameters
43/// involving multiple splitting categories. Splits can also be performed
44/// in the product of multiple categories, *i.e.*,
45/// ```
46/// wst.build("G_sim", "G", SplitParam("m","c,d"));
47/// ```
48/// splits the parameter \f$ m \f$ in the product of the states of \f$ c \f$ and
49/// \f$ d \f$.
50///
51/// #### Constrained split
52/// Another possibility
53/// is the "constrained" split, which clones the parameter for all but one state
54/// and inserts a formula specialization in a chosen state that evaluates
55/// to \f$ 1 - \sum_i(a_i) \f$ where \f$ a_i \f$ are all other specializations. For example,
56/// given a category \f$ c \f$ with the states `"A","B","C","D"`, the specification
57/// ```
58/// SplitParamConstrained("m","c","D")
59/// ```
60/// will create the parameters \f$ m_A,m_B,m_C \f$ and a formula expression \f$ m_D \f$
61/// that evaluates to \f$ (1-(m_A+m_B+m_C)) \f$. Constrained splits can also be
62/// specified in the product of categories. In that case, the name of the
63/// remainder state follows the syntax `"{State1;State2}"`, where `State1` and
64/// `State2` are the state names of the two spitting categories.
65///
66/// ## Splitting multiple PDFs
67/// The examples so far deal with a single prototype PDF. It is also
68/// possible to build with multiple prototype PDFs by specifying a
69/// mapping between the prototype to use and the names of states of
70/// a "master" splitting category. To specify these configurations,
71/// an intermediate `MultiBuildConfig` must be composed with all
72/// the necessary specifications. This, for example,
73/// ```
74/// RooSimWSTool::MultiBuildConfig mbc("mc");
75/// mbc.addPdf("I","G",SplitParam("m,s","c"));
76/// mbc.addPdf("II,III","F",SplitParam("a","c,d"));
77/// ```
78/// configures a build with two prototype PDFs \f$ G \f$ and \f$ F \f$.
79/// Prototype \f$ G \f$ is used for state `"I"` of the master split category
80/// `mc` and prototype \f$ F \f$ is used for states `"II"` and `"III"` of the
81/// master split category `mc`. Furthermore, the parameters \f$ m,s \f$ of
82/// prototype \f$ G \f$ are split
83/// in category \f$ c \f$ while the parameter \f$ a \f$ of prototype \f$ F \f$ is split in
84/// the product of the categories \f$ c \f$ and \f$ d \f$. The actual build is then
85/// performed by passing the build configuration to RooSimWSTool, *e.g.*,
86/// ```
87/// wst.build("MASTER", mbc);
88/// ```
89/// By default, a specialisation is built for each permutation of
90/// states of the splitting categories that are used. It is possible
91/// to restrict the building of specialised PDFs to a subset of states
92/// by adding a restriction on the number of states to build as follows:
93/// ```
94/// mbc.restrictBuild("c","A,B");
95/// ```
96/// The restrictBuild method can be called multiple times, but at most
97/// once for each splitting category in use. For simple builds with a single
98/// prototype, restriction can be specified with a Restrict() argument
99/// on the build command line.
100///
101
102
103#include "RooSimWSTool.h"
104
106#include "RooMsgService.h"
107#include "RooCategory.h"
108#include "RooRealVar.h"
109#include "RooAbsPdf.h"
110#include "RooSuperCategory.h"
111#include "RooCustomizer.h"
112#include "RooMultiCategory.h"
113#include "RooSimultaneous.h"
114#include "RooGlobalFunc.h"
115#include "RooFracRemainder.h"
116#include "RooFactoryWSTool.h"
117
118using std::string, std::endl, std::map, std::list, std::pair, std::cout, std::vector;
119
120namespace {
121
122class SimWSIFace : public RooFactoryWSTool::IFace {
123public:
124 std::string create(RooFactoryWSTool& ft, const char* typeName, const char* instanceName, std::vector<std::string> args) override ;
125} ;
126
127static Int_t init();
128
129Int_t dummy = init() ;
130
131Int_t init()
132{
133 static SimWSIFace iface{};
134 RooFactoryWSTool::registerSpecial("SIMCLONE",&iface);
135 RooFactoryWSTool::registerSpecial("MSIMCLONE",&iface);
136 (void) dummy;
137 return 0 ;
138}
139
140}
141
142////////////////////////////////////////////////////////////////////////////////
143/// Constructor of SimWSTool on given workspace. All input is taken from the workspace
144/// All output is stored in the workspace
145
147{
148}
149
150
151
152////////////////////////////////////////////////////////////////////////////////
153/// Destructor
154
156{
157}
158
159
160
161////////////////////////////////////////////////////////////////////////////////
162/// Build a RooSimultaneous PDF with name simPdfName from cloning specializations of protytpe PDF protoPdfName.
163/// <table>
164/// <tr><th> Optional Arguments <th> Effect
165/// <tr><td> SplitParam(varname, catname) <td> Split parameter(s) with given name(s) in category(s) with given names
166/// <tr><td> SplitParam(var, cat) <td> Split given parameter(s) in given category(s)
167/// <tr><td> SplitParamConstrained(vname, cname, remainder) <td> Make constrained split in parameter(s) with given name(s) in category(s) with given names
168/// putting remainder fraction formula in state with name "remainder"
169/// <tr><td> SplitParamConstrained(var,cat,remainder) <td> Make constrained split in parameter(s) with given name(s) in category(s) with given names
170/// putting remainder fraction formula in state with name "remainder"
171/// <tr><td> Restrict(catName,stateNameList) <td> Restrict build by only considered listed state names of category with given name
172
173RooSimultaneous* RooSimWSTool::build(const char* simPdfName, const char* protoPdfName, const RooCmdArg& arg1,const RooCmdArg& arg2,
174 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
175{
176 BuildConfig bc(protoPdfName,arg1,arg2,arg3,arg4,arg5,arg6) ;
177 return build(simPdfName,bc) ;
178}
179
180
181
182////////////////////////////////////////////////////////////////////////////////
183/// Build a RooSimultaneous PDF with name simPdfName from cloning specializations of protytpe PDF protoPdfName.
184/// Use the provided BuildConfig or MultiBuildConfig object to configure the build
185
186RooSimultaneous* RooSimWSTool::build(const char* simPdfName,BuildConfig& bc, bool verbose)
187{
188 auto obc = validateConfig(bc);
189 if (!obc) return nullptr;
190
191 if (verbose) {
192 obc->print() ;
193 }
194
195 RooSimultaneous* ret = executeBuild(simPdfName,*obc,verbose) ;
196
197 return ret ;
198}
199
200
201
202////////////////////////////////////////////////////////////////////////////////
203/// Validate build configuration. If not syntax errors or missing objects are found,
204/// return an ObjBuildConfig in which all names are replaced with object pointers.
205
206std::unique_ptr<RooSimWSTool::ObjBuildConfig> RooSimWSTool::validateConfig(BuildConfig& bc)
207{
208 // Create empty object version of build config
209 auto obc = std::make_unique<ObjBuildConfig>();
210
211 if (bc._masterCatName.length()>0) {
212 obc->_masterCat = _ws->cat(bc._masterCatName) ;
213 if (!obc->_masterCat) {
214 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: associated workspace " << _ws->GetName()
215 << " does not contain a category named " << bc._masterCatName
216 << " that was designated as master index category in the build configuration" << endl ;
217 return nullptr;
218 }
219 } else {
220 obc->_masterCat = nullptr ;
221 }
222
223 map<string,SplitRule>::iterator pdfiter ;
224 // Check that we have the p.d.f.s
225 for (pdfiter = bc._pdfmap.begin() ; pdfiter != bc._pdfmap.end() ; ++pdfiter) {
226
227 // Check that p.d.f exists
228 RooAbsPdf* pdf = _ws->pdf(pdfiter->second.GetName()) ;
229 if (!pdf) {
230 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: associated workspace " << _ws->GetName()
231 << " does not contain a pdf named " << pdfiter->second.GetName() << endl ;
232 return nullptr;
233 }
234
235 // Create empty object version of split rule set
236 ObjSplitRule osr ;
237
238 // Convert names of parameters and splitting categories to objects in workspace, fill object split rule
239 SplitRule& sr = pdfiter->second ;
240
241 map<string, pair<list<string>,string> >::iterator pariter ;
242 for (pariter=sr._paramSplitMap.begin() ; pariter!=sr._paramSplitMap.end() ; ++pariter) {
243
244 // Check that variable with given name exists in workspace
245 RooAbsArg* farg = _ws->fundArg(pariter->first) ;
246 if (!farg) {
247 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: associated workspace " << _ws->GetName()
248 << " does not contain a variable named " << pariter->first.c_str()
249 << " as specified in splitting rule of parameter " << pariter->first << " of p.d.f " << pdf << endl ;
250 return nullptr;
251 }
252
253 // Check that given variable is indeed related to given p.d.f
254 if (!pdf->dependsOn(*farg)) {
255 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: specified parameter " << pariter->first
256 << " in split is not function of p.d.f " << pdf->GetName() << endl ;
257 return nullptr;
258 }
259
260
261 RooArgSet splitCatSet ;
262 list<string>::iterator catiter ;
263 for (catiter = pariter->second.first.begin() ; catiter!=pariter->second.first.end() ; ++catiter) {
264 RooAbsCategory* cat = _ws->catfunc(*catiter) ;
265 if (!cat) {
266 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: associated workspace " << _ws->GetName()
267 << " does not contain a category named " << catiter->c_str()
268 << " as specified in splitting rule of parameter " << pariter->first << " of p.d.f " << pdf << endl ;
269 return nullptr;
270 }
271 splitCatSet.add(*cat) ;
272 }
273
274 // Check if composite splitCatSet does not contain category functions that depend on other categories used in the same split
275 for(RooAbsArg * arg : splitCatSet) {
276 RooArgSet tmp(splitCatSet) ;
277 tmp.remove(*arg) ;
278 if (arg->dependsOnValue(tmp)) {
279 oocoutE(nullptr, InputArguments) << "RooSimWSTool::build() ERROR: Ill defined split: splitting category function " << arg->GetName()
280 << " used in composite split " << splitCatSet << " of parameter " << farg->GetName() << " of pdf " << pdf->GetName()
281 << " depends on one or more of the other splitting categories in the composite split" << endl ;
282 return nullptr;
283 }
284 }
285
286 // If a constrained split is specified, check that split parameter is a real-valued type
287 if (!pariter->second.second.empty()) {
288 if (!dynamic_cast<RooAbsReal*>(farg)) {
289 oocoutE(nullptr, InputArguments) << "RooSimWSTool::build() ERROR: Constrained split specified in non real-valued parameter " << farg->GetName() << endl ;
290 return nullptr;
291 }
292 }
293
294 // Fill object build config with object split rule
295 osr._paramSplitMap[farg].first.add(splitCatSet) ;
296 osr._paramSplitMap[farg].second = pariter->second.second ;
297
298 // For multi-pdf configurations, check that the master index state name associated with this p.d.f exists as a state in the master category
299 if (obc->_masterCat) {
300 list<string>::iterator misi ;
301 for (misi=sr._miStateNameList.begin() ; misi!=sr._miStateNameList.end() ; ++misi) {
302 const RooCatType* ctype = obc->_masterCat->lookupType(misi->c_str(),false) ;
303 if (ctype==nullptr) {
304 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: master index category " << obc->_masterCat->GetName()
305 << " does not have a state named " << *misi << " which was specified as state associated with p.d.f "
306 << sr.GetName() << endl ;
307 return nullptr;
308 }
309 osr._miStateList.push_back(ctype) ;
310 }
311 }
312
313 // Add specified split cats to global list of all splitting categories
314 obc->_usedSplitCats.add(splitCatSet,true) ;
315
316 }
317 // Need to add clause here for SplitRules without any split (which can happen in MultiBuildConfigs)
318 if (sr._paramSplitMap.empty()) {
319
320 if (obc->_masterCat) {
321 list<string>::iterator misi ;
322 for (misi=sr._miStateNameList.begin() ; misi!=sr._miStateNameList.end() ; ++misi) {
323 const RooCatType* ctype = obc->_masterCat->lookupType(misi->c_str(),false) ;
324 if (ctype==nullptr) {
325 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: master index category " << obc->_masterCat->GetName()
326 << " does not have a state named " << *misi << " which was specified as state associated with p.d.f "
327 << sr.GetName() << endl ;
328 return nullptr;
329 }
330 osr._miStateList.push_back(ctype) ;
331 }
332 }
333 }
334
335 obc->_pdfmap[pdf] = osr ;
336
337 }
338
339 // Check validity of build restriction specifications, if any
340 map<string,string>::iterator riter ;
341 for (riter=bc._restr.begin() ; riter!=bc._restr.end() ; ++riter) {
342 RooCategory* cat = _ws->cat(riter->first) ;
343 if (!cat) {
344 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: associated workspace " << _ws->GetName()
345 << " does not contain a category named " << riter->first
346 << " for which build was requested to be restricted to states " << riter->second << endl ;
347 return nullptr;
348 }
349
350 char buf[4096] ;
351 list<const RooCatType*> rlist ;
352 strlcpy(buf,riter->second.c_str(),4096) ;
353
354 char* tok = strtok(buf,"{,}") ;
355 while(tok) {
356 const RooCatType* ctype = cat->lookupType(tok,false) ;
357 if (!ctype) {
358 oocoutE(nullptr, ObjectHandling) << "RooSimWSTool::build() ERROR: restricted build category " << cat->GetName()
359 << " does not have state " << tok << " as specified in restriction list" << endl ;
360 return nullptr;
361 }
362 rlist.push_back(ctype) ;
363 tok = strtok(nullptr,"{,}") ;
364 }
365
366 obc->_restr[cat] = rlist ;
367 }
368
369 return obc ;
370}
371
372
373
374
375////////////////////////////////////////////////////////////////////////////////
376/// Internal build driver from validation ObjBuildConfig.
377
378RooSimultaneous* RooSimWSTool::executeBuild(const char* simPdfName, ObjBuildConfig& obc, bool verbose)
379{
380 RooArgSet cleanupList ;
381
382 RooAbsCategoryLValue* physCat = obc._masterCat ;
383
384 RooArgSet physModelSet ;
385 map<string,RooAbsPdf*> stateMap ;
386
387 map<RooAbsPdf*,ObjSplitRule>::iterator physIter = obc._pdfmap.begin() ;
388 while(physIter!=obc._pdfmap.end()) {
389
390
391 RooAbsPdf* physModel = physIter->first ;
392 physModelSet.add(*physModel,true) ; // silence duplicate insertion warnings
393
394 list<const RooCatType*>::iterator stiter ;
395 for (stiter=physIter->second._miStateList.begin() ; stiter!=physIter->second._miStateList.end() ; ++stiter) {
396 stateMap[(*stiter)->GetName()] = physModel ;
397 }
398
399 // Continue with next mapping
400 ++physIter ;
401 }
402 if (verbose) {
403 oocoutI(nullptr, ObjectHandling) << "RooSimWSTool::executeBuild: list of prototype pdfs " << physModelSet << endl ;
404 }
405
406 RooArgSet splitCatSet(obc._usedSplitCats) ;
407 if (physCat) splitCatSet.add(*physCat) ;
408
409 RooArgSet splitCatSetFund ;
410 for(auto * scat : static_range_cast<RooAbsCategory*>(splitCatSet)) {
411 if (scat->isFundamental()) {
412 splitCatSetFund.add(*scat) ;
413 } else {
414 std::unique_ptr<RooArgSet> scatvars{scat->getVariables()};
415 splitCatSetFund.add(*scatvars) ;
416 }
417 }
418
419
420 RooAbsCategoryLValue* masterSplitCat = nullptr;
421 if (splitCatSetFund.size()>1) {
422 auto masterSplitCatOwner = std::make_unique<RooSuperCategory>("masterSplitCat","Master splitting category",splitCatSetFund);
423 masterSplitCat = masterSplitCatOwner.get();
424 cleanupList.addOwned(std::move(masterSplitCatOwner));
425 } else {
426 masterSplitCat = static_cast<RooAbsCategoryLValue*>(splitCatSetFund.first()) ;
427 }
428 if (verbose) {
429 oocoutI(nullptr, ObjectHandling) << "RooSimWSTool::executeBuild: list of splitting categories " << splitCatSet << endl ;
430 }
431
432 RooArgSet splitNodeListOwned ; // owns all newly created components
433 RooArgSet splitNodeListAll ; // all leaf nodes, preload with ws contents to auto-connect existing specializations
434 std::vector<std::unique_ptr<RooCustomizer>> customizerList ;
435
436 // Loop over requested physics models and build components
437 for(auto * physModel : static_range_cast<RooAbsPdf*>(physModelSet)) {
438 if (verbose) {
439 oocoutI(nullptr, ObjectHandling) << "RooSimPdfBuilder::executeBuild: processing prototype pdf " << physModel->GetName() << endl ;
440 }
441
442 customizerList.push_back(std::make_unique<RooCustomizer>(*physModel,*masterSplitCat,splitNodeListOwned,&splitNodeListAll));
443 RooCustomizer* physCustomizer = customizerList.back().get();
444
445 map<RooAbsArg*, pair<RooArgSet,string> >::iterator splitIter ;
446 for (splitIter = obc._pdfmap[physModel]._paramSplitMap.begin() ; splitIter != obc._pdfmap[physModel]._paramSplitMap.end() ; ++splitIter) {
447
448 // If split is composite, first make multicategory with name 'A,B,C' and insert in WS
449
450 // Construct name of (composite) split category (function)
451 RooArgSet& splitCatSetTmp = splitIter->second.first ;
452 string splitName = makeSplitName(splitCatSetTmp) ;
453
454 // If composite split object does not exist yet, create it now
455 RooAbsCategory* splitCat = _ws->catfunc(splitName) ;
456 if (!splitCat) {
457 auto splitCatOwner = std::make_unique<RooMultiCategory>(splitName.c_str(),splitName.c_str(),splitCatSetTmp);
458 splitCat = splitCatOwner.get();
459 _ws->import(*splitCat,RooFit::Silence(!verbose)) ;
460 cleanupList.addOwned(std::move(splitCatOwner)) ;
461 }
462
463 // If remainder category needs to be made, create RFV of appropriate for that and insert in WS
464 if(!splitIter->second.second.empty()) {
465
466 // Check that specified split name is in fact valid
467 if (!splitCat->hasLabel(splitIter->second.second)) {
468 oocoutE(nullptr, InputArguments) << "RooSimWSTool::executeBuild() ERROR: name of remainder state for constrained split, '"
469 << splitIter->second.second << "' , does not match any state name of (composite) split category " << splitCat->GetName() << endl ;
470 return nullptr;
471 }
472
473 // First build manually the specializations of all non-remainder states, as the remainder state depends on these
474 RooArgSet fracLeafList ;
475 for(auto const& type : *splitCat) {
476
477 std::string const& typeName = type.first;
478
479 // Skip remainder state
480 if (splitIter->second.second == typeName) continue ;
481
482 // Construct name of split leaf
483 std::string splitLeafName = std::string{splitIter->first->GetName()} + "_" + typeName;
484
485 // Check if split leaf already exists
486 RooAbsArg* splitLeaf = _ws->fundArg(splitLeafName) ;
487 if (!splitLeaf) {
488 // If not create it now
489 splitLeaf = static_cast<RooAbsArg*>(splitIter->first->clone(splitLeafName.c_str()));
490 _ws->import(*splitLeaf,RooFit::Silence(!verbose)) ;
491 }
492 fracLeafList.add(*splitLeaf) ;
493 }
494
495
496 // Build specialization for remainder state and insert in workspace
497 auto fracRem = std::make_unique<RooFracRemainder>(Form("%s_%s",splitIter->first->GetName(),splitIter->second.second.c_str()),"Remainder fraction",fracLeafList);
498 _ws->import(*fracRem) ;
499 cleanupList.addOwned(std::move(fracRem));
500
501 }
502
503
504 // Add split definition to customizer
505 physCustomizer->splitArgs(*splitIter->first,*splitCat) ;
506 }
507 }
508
509 // List all existing workspace components as prebuilt items for the customizers at this point
510 splitNodeListAll.add(_ws->components()) ;
511
512 if (verbose) {
513 oocoutI(nullptr, ObjectHandling) << "RooSimWSTool::executeBuild: configured customizers for all prototype pdfs" << endl ;
514 }
515
516 // Create fit category from physCat and splitCatList ;
517 RooArgSet fitCatList ;
518 if (physCat) fitCatList.add(*physCat) ;
519
520 // Add observables of splitCatSet members, rather than splitCatSet members directly
521 // as there may be cat->cat functions in here
522 for(auto * scat : static_range_cast<RooAbsCategory*>(splitCatSet)) {
523 if (scat->isFundamental()) {
524 fitCatList.add(*scat) ;
525 } else {
526 fitCatList.add(*std::unique_ptr<RooArgSet>{scat->getVariables()}) ;
527 }
528 }
529
530
531 string mcatname = string(simPdfName) + "_index" ;
532 RooAbsCategoryLValue* fitCat = nullptr;
533 if (fitCatList.size()>1) {
534 auto fitCatOwner = std::make_unique<RooSuperCategory>(mcatname.c_str(),mcatname.c_str(),fitCatList);
535 fitCat = fitCatOwner.get();
536 cleanupList.addOwned(std::move(fitCatOwner));
537 } else {
538 fitCat = static_cast<RooAbsCategoryLValue*>(fitCatList.first()) ;
539 }
540
541 // Create master PDF
542 auto simPdfOwner = std::make_unique<RooSimultaneous>(simPdfName,simPdfName,*fitCat);
543 RooSimultaneous* simPdf = simPdfOwner.get();
544 cleanupList.addOwned(std::move(simPdfOwner));
545
546 // Add component PDFs to master PDF
547 for (auto const& fcState : *fitCat) {
548 const std::string fcStateName = fcState.first;
549
550 // Select fitCat state
551 fitCat->setLabel(fcStateName.c_str());
552
553 // Check if this fitCat state is selected
554 bool select(false) ;
555 if (!obc._restr.empty()) {
556 for(auto * splitCat : static_range_cast<RooAbsCategory*>(fitCatList)) {
557 // Find selected state list
558
559 list<const RooCatType*> slist = obc._restr[splitCat] ;
560 if (slist.empty()) {
561 continue ;
562 }
563
564 list<const RooCatType*>::iterator sli ;
565 for (sli=slist.begin() ; sli!=slist.end() ; ++sli) {
566 if (string(splitCat->getCurrentLabel())==(*sli)->GetName()) {
567 select=true ;
568 }
569 }
570 }
571 if (!select) continue ;
572 } else {
573 select = true ;
574 }
575
576 // Select appropriate PDF for this physCat state
577 RooCustomizer* physCustomizer ;
578 if (physCat) {
579 RooAbsPdf* pdf = stateMap[physCat->getCurrentLabel()] ;
580 if (pdf==nullptr) {
581 continue ;
582 }
583 const std::string pdfName = pdf->GetName();
584 auto found = std::find_if(customizerList.begin(), customizerList.end(),
585 [&](auto const& c){ return pdfName == c->pdf().GetName(); });
586 physCustomizer = found != customizerList.end() ? found->get() : nullptr;
587 } else {
588 physCustomizer = customizerList.front().get();
589 }
590
591 if (verbose) {
592 oocoutI(nullptr, ObjectHandling) << "RooSimWSTool::executeBuild: Customizing prototype pdf " << physCustomizer->pdf().GetName()
593 << " for mode " << fcStateName << endl ;
594 }
595
596 // Customizer PDF for current state and add to master simPdf
597 RooAbsPdf* fcPdf = static_cast<RooAbsPdf*>(physCustomizer->build(masterSplitCat->getCurrentLabel(),false)) ;
598 simPdf->addPdf(*fcPdf,fcStateName.c_str()) ;
599 }
600
601 _ws->import(*simPdf,obc._conflProtocol,RooFit::Silence(!verbose)) ;
602
603 // Delete customizers
604 return static_cast<RooSimultaneous*>(_ws->pdf(simPdf->GetName())) ;
605}
606
607
608
609////////////////////////////////////////////////////////////////////////////////
610/// Construct name of composite split
611
612std::string RooSimWSTool::makeSplitName(const RooArgSet& splitCatSet)
613{
614 std::string name ;
615
616 bool first=true ;
617 for(RooAbsArg * arg : splitCatSet) {
618 if (first) {
619 first=false;
620 } else {
621 name += "," ;
622 }
623 name += arg->GetName() ;
624 }
625
626 return name ;
627}
628
629
630
631
632////////////////////////////////////////////////////////////////////////////////
633/// Specify that parameters names listed in paramNameList be split in (product of) category(s)
634/// listed in categoryNameList
635
636void RooSimWSTool::SplitRule::splitParameter(const char* paramNameList, const char* categoryNameList)
637{
638 char paramBuf[4096] ;
639 char catBuf[4096] ;
640 strlcpy(paramBuf,paramNameList,4096) ;
641 strlcpy(catBuf,categoryNameList,4096) ;
642
643 // First parse category list
644 list<string> catList ;
645 char* cat = strtok(catBuf,"{,}") ;
646 while(cat) {
647 catList.push_back(cat) ;
648 cat = strtok(nullptr,"{,}") ;
649 }
650
651 // Now parse parameter list
652 char* param = strtok(paramBuf,"{,}") ;
653 while(param) {
654 _paramSplitMap[param] = pair<list<string>,string>(catList,"") ;
655 param = strtok(nullptr,"{,}") ;
656 }
657}
658
659
660////////////////////////////////////////////////////////////////////////////////
661/// Specify that parameters names listed in paramNameList be split in constrained way in (product of) category(s)
662/// listed in categoryNameList and that remainder fraction formula be put in state with name remainderStateName
663
664void RooSimWSTool::SplitRule::splitParameterConstrained(const char* paramNameList, const char* categoryNameList, const char* remainderStateName)
665{
666 char paramBuf[4096] ;
667 char catBuf[4096] ;
668 strlcpy(paramBuf,paramNameList,4096) ;
669 strlcpy(catBuf,categoryNameList,4096) ;
670
671 // First parse category list
672 list<string> catList ;
673 char* cat = strtok(catBuf,"{,}") ;
674 while(cat) {
675 catList.push_back(cat) ;
676 cat = strtok(nullptr,"{,}") ;
677 }
678
679 // Now parse parameter list
680 char* param = strtok(paramBuf,"{,}") ;
681 while(param) {
682 _paramSplitMap[param] = pair<list<string>,string>(catList,remainderStateName) ;
683 param = strtok(nullptr,"{,}") ;
684 }
685}
686
687
688////////////////////////////////////////////////////////////////////////////////
689/// Construct the SplitRule object from a list of named arguments past to RooSimWSTool::build
690/// This method parses any SplitParam and SplitParamComstrained argument in the list
691
692void RooSimWSTool::SplitRule::configure(const RooCmdArg& arg1,const RooCmdArg& arg2,const RooCmdArg& arg3,
693 const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
694{
695 list<const RooCmdArg*> cmdList ;
696 cmdList.push_back(&arg1) ; cmdList.push_back(&arg2) ;
697 cmdList.push_back(&arg3) ; cmdList.push_back(&arg4) ;
698 cmdList.push_back(&arg5) ; cmdList.push_back(&arg6) ;
699
700 list<const RooCmdArg*>::iterator iter ;
701 for (iter=cmdList.begin() ; iter!=cmdList.end() ; ++iter) {
702
703 if ((*iter)->opcode()==nullptr) continue ;
704
705 string name = (*iter)->opcode() ;
706
707 if (name=="SplitParam") {
708 splitParameter((*iter)->getString(0),(*iter)->getString(1)) ;
709 } else if (name=="SplitParamConstrained") {
710 splitParameterConstrained((*iter)->getString(0),(*iter)->getString(1),(*iter)->getString(2)) ;
711 }
712 }
713}
714
715
716
717
718////////////////////////////////////////////////////////////////////////////////
719/// Add prototype p.d.f pdfName to build configuration with associated split rules 'sr'
720
722{
723 internalAddPdf(pdfName,"",sr) ;
724}
725
726
727////////////////////////////////////////////////////////////////////////////////
728/// Construct build configuration from single prototype 'pdfName' and list of arguments
729/// that can be passed to RooSimWSTool::build() method. This routine parses SplitParam()
730/// SplitParamConstrained() and Restrict() arguments.
731
732RooSimWSTool::BuildConfig::BuildConfig(const char* pdfName, const RooCmdArg& arg1,const RooCmdArg& arg2,
733 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
734{
735 SplitRule sr(pdfName) ;
736 sr.configure(arg1,arg2,arg3,arg4,arg5,arg6) ;
737 internalAddPdf(pdfName,"",sr) ;
738 _conflProtocol = RooFit::RenameConflictNodes(pdfName) ;
739
740 list<const RooCmdArg*> cmdList ;
741 cmdList.push_back(&arg1) ; cmdList.push_back(&arg2) ;
742 cmdList.push_back(&arg3) ; cmdList.push_back(&arg4) ;
743 cmdList.push_back(&arg5) ; cmdList.push_back(&arg6) ;
744
745 list<const RooCmdArg*>::iterator iter ;
746 for (iter=cmdList.begin() ; iter!=cmdList.end() ; ++iter) {
747 if ((*iter)->opcode()==nullptr) continue ;
748 string name = (*iter)->opcode() ;
749 if (name=="Restrict") {
750 restrictBuild((*iter)->getString(0),(*iter)->getString(1)) ;
751 }
752 if (name=="RenameConflictNodes") {
753 _conflProtocol = *(*iter) ;
754 }
755 }
756}
757
758
759////////////////////////////////////////////////////////////////////////////////
760/// Constructor to make BuildConfig from legacy RooSimPdfBuilder configuration
761/// Empty for now
762
764{
765}
766
767
768////////////////////////////////////////////////////////////////////////////////
769/// Internal routine to add prototype pdf 'pdfName' with list of associated master states 'miStateNameList
770/// and split rules 'sr' to configuration
771
772void RooSimWSTool::BuildConfig::internalAddPdf(const char* pdfName, const char* miStateNameList,SplitRule& sr)
773{
774 char buf[4096] ;
775 strlcpy(buf,miStateNameList,4096) ;
776
777 char* tok = strtok(buf,",") ;
778 while(tok) {
779 sr._miStateNameList.push_back(tok) ;
780 tok = strtok(nullptr,",") ;
781 }
782
783 _pdfmap[pdfName] = sr ;
784}
785
786
787////////////////////////////////////////////////////////////////////////////////
788/// Restrict build by only considering state names in stateList for split in category catName
789
790void RooSimWSTool::BuildConfig::restrictBuild(const char* catName, const char* stateList)
791{
792 _restr[catName] = stateList ;
793}
794
795
796
797
798////////////////////////////////////////////////////////////////////////////////
799/// Construct MultiBuildConfig for build configuration with multiple prototype p.d.f.s
800/// masterIndexCat is the name of the master index category that decides which
801/// prototype is used.
802
804{
805 _masterCatName = masterIndexCat ;
806}
807
808
809
810////////////////////////////////////////////////////////////////////////////////
811/// Add protytpe p.d.f 'pdfName' to MultiBuildConfig associated with master index states 'miStateList'. This
812/// method parses the SplitParam() and SplitParamConstrained() arguments
813
814void RooSimWSTool::MultiBuildConfig::addPdf(const char* miStateList, const char* pdfName, const RooCmdArg& arg1,const RooCmdArg& arg2,
815 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
816{
817 SplitRule sr(pdfName) ;
818 sr.configure(arg1,arg2,arg3,arg4,arg5,arg6) ;
819 internalAddPdf(pdfName,miStateList,sr) ;
820}
821
822
823
824////////////////////////////////////////////////////////////////////////////////
825/// Add protytpe p.d.f 'pdfName' to MultiBuildConfig associated with master index states 'miStateList'.
826
827void RooSimWSTool::MultiBuildConfig::addPdf(const char* miStateList, const char* pdfName, SplitRule& sr)
828{
829 internalAddPdf(pdfName,miStateList,sr) ;
830}
831
832
833
834
835////////////////////////////////////////////////////////////////////////////////
836/// Destructor
837
839{
840}
841
842
843
844
845////////////////////////////////////////////////////////////////////////////////
846/// Print details of a validated build configuration
847
849{
850 // --- Dump contents of object build config ---
851 map<RooAbsPdf*,ObjSplitRule>::iterator ri ;
852 for (ri = _pdfmap.begin() ; ri != _pdfmap.end() ; ++ri ) {
853 cout << "Splitrule for p.d.f " << ri->first->GetName() << " with state list " ;
854 for (std::list<const RooCatType*>::iterator misi= ri->second._miStateList.begin() ; misi!=ri->second._miStateList.end() ; ++misi) {
855 cout << (*misi)->GetName() << " " ;
856 }
857 cout << endl ;
858
859 map<RooAbsArg*,pair<RooArgSet,string> >::iterator csi ;
860 for (csi = ri->second._paramSplitMap.begin() ; csi != ri->second._paramSplitMap.end() ; ++csi ) {
861 if (csi->second.second.length()>0) {
862 cout << " parameter " << csi->first->GetName() << " is split with constraint in categories " << csi->second.first
863 << " with remainder in state " << csi->second.second << endl ;
864 } else {
865 cout << " parameter " << csi->first->GetName() << " is split with constraint in categories " << csi->second.first << endl ;
866 }
867 }
868 }
869
870 map<RooAbsCategory*,list<const RooCatType*> >::iterator riter ;
871 for (riter=_restr.begin() ; riter!=_restr.end() ; ++riter) {
872 cout << "Restricting build in category " << riter->first->GetName() << " to states " ;
873 list<const RooCatType*>::iterator i ;
874 for (i=riter->second.begin() ; i!=riter->second.end() ; ++i) {
875 if (i!=riter->second.begin()) cout << "," ;
876 cout << (*i)->GetName() ;
877 }
878 cout << endl ;
879 }
880
881}
882
883
884namespace {
885
886////////////////////////////////////////////////////////////////////////////////
887
888std::string SimWSIFace::create(RooFactoryWSTool& ft, const char* typeName, const char* instanceName, std::vector<std::string> args)
889{
890 string tn(typeName) ;
891 if (tn=="SIMCLONE") {
892
893 // Perform syntax check. Warn about any meta parameters other than $SplitParam, $SplitParamConstrained, $Restrict and $Verbose
894 for (unsigned int i=1 ; i<args.size() ; i++) {
895 if (args[i].find("$SplitParam(")!=0 &&
896 args[i].find("$SplitParamConstrained(")!=0 &&
897 args[i].find("$SplitRestrict(")!=0 &&
898 args[i].find("$Verbose(")!=0) {
899 throw string(Form("RooSimWSTool::SimWSIFace::create() ERROR: unknown token %s encountered",args[i].c_str())) ;
900 }
901 }
902
903 // Make SplitRule object from $SplitParam and $SplitParamConstrained arguments
904 RooSimWSTool::SplitRule sr(args[0].c_str()) ;
905 for (unsigned int i=1 ; i<args.size() ; i++) {
906 if (args[i].find("$SplitParam(")==0) {
907 vector<string> subargs = ft.splitFunctionArgs(args[i].c_str()) ;
908 if (subargs.size()!=2) {
909 throw string(Form("Incorrect number of arguments in $SplitParam, have %d, expect 2",(Int_t)subargs.size())) ;
910 }
911 sr.splitParameter(subargs[0].c_str(),subargs[1].c_str()) ;
912 } else if (args[i].find("$SplitParamConstrained(")==0) {
913 vector<string> subargs = ft.splitFunctionArgs(args[i].c_str()) ;
914 if (subargs.size()!=3) {
915 throw string(Form("Incorrect number of arguments in $SplitParamConstrained, have %d, expect 3",(Int_t)subargs.size())) ;
916 }
917 sr.splitParameterConstrained(subargs[0].c_str(), subargs[1].c_str(), subargs[2].c_str()) ;
918 }
919 }
920
921 // Make BuildConfig object
922 RooSimWSTool::BuildConfig bc(args[0].c_str(),sr) ;
923 for (unsigned int i=1 ; i<args.size() ; i++) {
924 if (args[i].find("$Restrict(")==0) {
925 vector<string> subargs = ft.splitFunctionArgs(args[i].c_str()) ;
926 if (subargs.size()!=2) {
927 throw string(Form("Incorrect number of arguments in $Restrict, have %d, expect 2",(Int_t)subargs.size())) ;
928 }
929 bc.restrictBuild(subargs[0].c_str(),subargs[1].c_str()) ;
930 }
931 }
932
933 // Look for verbose flag
934 bool verbose(false) ;
935 for (unsigned int i=1 ; i<args.size() ; i++) {
936 if (args[i].find("$Verbose(")==0) {
937 vector<string> subargs = ft.splitFunctionArgs(args[i].c_str()) ;
938 if (!subargs.empty()) {
939 verbose = atoi(subargs[0].c_str()) ;
940 }
941 }
942 }
943
944 // Build pdf clone
945 RooSimWSTool sct(ft.ws()) ;
946 RooAbsPdf* pdf = sct.build(instanceName,bc,verbose) ;
947 if (!pdf) {
948 throw string(Form("RooSimWSTool::SimWSIFace::create() error in RooSimWSTool::build() for %s",instanceName)) ;
949 }
950
951 // Import into workspace
952 ft.ws().import(*pdf,RooFit::Silence()) ;
953
954 } else if (tn=="MSIMCLONE") {
955
956 // First make a multibuild config from the master index cat
957 RooSimWSTool::MultiBuildConfig mbc(args[0].c_str()) ;
958
959 for (unsigned int i=1 ; i<args.size() ; i++) {
960 if (args[i].find("$AddPdf(")==0) {
961 // Process an add-pdf operation
962 vector<string> subargs = ft.splitFunctionArgs(args[i].c_str()) ;
963
964 // Make SplitRule object from $SplitParam and $SplitParamConstrained arguments
965 RooSimWSTool::SplitRule sr(subargs[1].c_str()) ;
966 for (unsigned int j=2 ; j<subargs.size() ; j++) {
967 if (subargs[j].find("$SplitParam(")==0) {
968 vector<string> subsubargs = ft.splitFunctionArgs(subargs[j].c_str()) ;
969 if (subsubargs.size()!=2) {
970 throw string(Form("Incorrect number of arguments in $SplitParam, have %d, expect 2",(Int_t)subsubargs.size())) ;
971 }
972 sr.splitParameter(subsubargs[0].c_str(),subsubargs[1].c_str()) ;
973 } else if (subargs[j].find("$SplitParamConstrained(")==0) {
974 vector<string> subsubargs = ft.splitFunctionArgs(subargs[j].c_str()) ;
975 if (subsubargs.size()!=3) {
976 throw string(Form("Incorrect number of arguments in $SplitParamConstrained, have %d, expect 3",(Int_t)subsubargs.size())) ;
977 }
978 sr.splitParameterConstrained(subsubargs[0].c_str(), subsubargs[1].c_str(), subsubargs[2].c_str()) ;
979 }
980 }
981 mbc.addPdf(subargs[0].c_str(),subargs[1].c_str(),sr) ;
982
983 } else if (args[i].find("$Restrict(")==0) {
984
985 // Process a restrict operation
986 vector<string> subargs = ft.splitFunctionArgs(args[i].c_str()) ;
987 if (subargs.size()!=2) {
988 throw string(Form("Incorrect number of arguments in $Restrict, have %d, expect 2",(Int_t)subargs.size())) ;
989 }
990 mbc.restrictBuild(subargs[0].c_str(),subargs[1].c_str()) ;
991
992 } else {
993 throw string(Form("RooSimWSTool::SimWSIFace::create() ERROR: unknown token in MSIMCLONE: %s",args[i].c_str())) ;
994 }
995 }
996
997 // Build pdf clone
998 RooSimWSTool sct(ft.ws()) ;
999 RooAbsPdf* pdf = sct.build(instanceName,mbc,false) ;
1000 if (!pdf) {
1001 throw string(Form("RooSimWSTool::SimWSIFace::create() error in RooSimWSTool::build() for %s",instanceName)) ;
1002 }
1003
1004 // Import into workspace
1005 ft.ws().import(*pdf,RooFit::Silence()) ;
1006
1007
1008 } else {
1009 throw string(Form("RooSimWSTool::SimWSIFace::create() ERROR: Unknown meta-type %s requested",typeName)) ;
1010 }
1011
1012 return string(instanceName) ;
1013}
1014
1015} // namespace
#define c(i)
Definition RSha256.hxx:101
#define oocoutE(o, a)
#define oocoutI(o, a)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
bool dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr, bool valueOnly=false) const
Test whether we depend on (ie, are served by) any object in the specified collection.
Abstract base class for objects that represent a discrete value that can be set from the outside,...
virtual bool setLabel(const char *label, bool printError=true)=0
Change category state by specifying a state name.
A space to attach TBranches.
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.
const RooCatType * lookupType(value_type index, bool printError=false) const
Find our type corresponding to the specified index, or return nullptr for no match.
const char * GetName() const override
Returns name of object.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
RooAbsArg * first() const
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:40
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooCatType is an auxiliary class for RooAbsCategory and defines a a single category state.
const Text_t * GetName() const override
Returns name of object.
Object to represent discrete states.
Definition RooCategory.h:28
Named container for two doubles, two integers two object points and three string pointers that can be...
Definition RooCmdArg.h:26
RooCustomizer is a factory class to produce clones of a prototype composite PDF object with the same ...
RooAbsArg * build(const char *masterCatState, bool verbose=false)
Build a clone of the prototype executing all registered 'replace' rules and 'split' rules for the mas...
void splitArgs(const RooArgSet &argSet, const RooAbsCategory &splitCat)
Split all arguments in 'set' into individualized clones for each defined state of 'splitCat'.
RooAbsPdf const & pdf() const
virtual std::string create(RooFactoryWSTool &ft, const char *typeName, const char *instanceName, std::vector< std::string > args)=0
Implementation detail of the RooWorkspace.
RooWorkspace & ws()
static void registerSpecial(const char *typeName, RooFactoryWSTool::IFace *iface)
Register foreign special objects in factory.
std::vector< std::string > splitFunctionArgs(const char *funcExpr)
Allocate and fill work buffer.
void restrictBuild(const char *catName, const char *stateList)
Restrict build by only considering state names in stateList for split in category catName.
std::map< std::string, SplitRule > _pdfmap
std::map< std::string, std::string > _restr
void internalAddPdf(const char *pdfName, const char *miStateList, SplitRule &sr)
Internal routine to add prototype pdf 'pdfName' with list of associated master states 'miStateNameLis...
void addPdf(const char *miStateList, const char *pdfName, SplitRule &sr)
Add protytpe p.d.f 'pdfName' to MultiBuildConfig associated with master index states 'miStateList'.
MultiBuildConfig(const char *masterIndexCat)
Construct MultiBuildConfig for build configuration with multiple prototype p.d.f.s masterIndexCat is ...
std::map< RooAbsPdf *, ObjSplitRule > _pdfmap
void print()
Print details of a validated build configuration.
std::map< RooAbsCategory *, std::list< const RooCatType * > > _restr
virtual ~ObjSplitRule()
Destructor.
std::map< RooAbsArg *, std::pair< RooArgSet, std::string > > _paramSplitMap
std::list< const RooCatType * > _miStateList
void splitParameter(const char *paramList, const char *categoryList)
Specify that parameters names listed in paramNameList be split in (product of) category(s) listed in ...
std::list< std::string > _miStateNameList
void splitParameterConstrained(const char *paramNameList, const char *categoryNameList, const char *remainderStateName)
Specify that parameters names listed in paramNameList be split in constrained way in (product of) cat...
std::map< std::string, std::pair< std::list< std::string >, std::string > > _paramSplitMap
void configure(const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={})
Construct the SplitRule object from a list of named arguments past to RooSimWSTool::build This method...
The RooSimWSTool is a tool operating on RooWorkspace objects that can clone PDFs into a series of var...
RooWorkspace * _ws
std::unique_ptr< ObjBuildConfig > validateConfig(BuildConfig &bc)
Validate build configuration.
RooSimWSTool(RooWorkspace &ws)
Constructor of SimWSTool on given workspace.
RooSimultaneous * executeBuild(const char *simPdfName, ObjBuildConfig &obc, bool verbose=true)
Internal build driver from validation ObjBuildConfig.
RooSimultaneous * 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={})
Build a RooSimultaneous PDF with name simPdfName from cloning specializations of protytpe PDF protoPd...
std::string makeSplitName(const RooArgSet &splitCatSet)
Construct name of composite split.
~RooSimWSTool()
Destructor.
Facilitates simultaneous fitting of multiple PDFs to subsets of a given dataset.
bool addPdf(const RooAbsPdf &pdf, const char *catLabel)
Associate given PDF with index category state label 'catLabel'.
Persistable container for RooFit projects.
RooAbsCategory * catfunc(RooStringView name) const
Retrieve discrete function (RooAbsCategory) with given name. A null pointer is returned if not found.
RooAbsPdf * pdf(RooStringView name) const
Retrieve p.d.f (RooAbsPdf) with given name. A null pointer is returned if not found.
RooCategory * cat(RooStringView name) const
Retrieve discrete variable (RooCategory) with given name. A null pointer is returned if not found.
RooAbsArg * fundArg(RooStringView name) const
Return fundamental (i.e.
bool import(const RooAbsArg &arg, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}, const RooCmdArg &arg9={})
Import a RooAbsArg object, e.g.
const RooArgSet & components() const
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
RooCmdArg Silence(bool flag=true)
RooCmdArg RenameConflictNodes(const char *suffix, bool renameOrigNodes=false)
void(off) SmallVectorTemplateBase< T