Logo ROOT   6.16/01
Reference Guide
RooCustomizer.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//
19// RooCustomizer is a factory class to produce clones
20// of a prototype composite PDF object with the same structure but
21// different leaf servers (parameters or dependents)
22//
23// RooCustomizer supports two kinds of modifications:
24//
25// -> replace(leaf_arg,repl_arg)
26// replaces each occurence of leaf_arg with repl_arg in the composite pdf.
27//
28// -> split(split_arg)
29// is used when building multiple clones of the same prototype. Each
30// occurrence of split_arg is replaceed with a clone of split_arg
31// named split_arg_[MCstate], where [MCstate] is the name of the
32// 'master category state' that indexes the clones to be built.
33//
34//
35// [Example]
36//
37// Splitting is particularly useful when building simultaneous fits to
38// subsets of the data sample with different background properties.
39// In such a case, the user builds a single prototype PDF representing
40// the structure of the signal and background and splits the dataset
41// into categories with different background properties. Using
42// RooCustomizer a PDF for each subfit can be constructed from the
43// prototype that has same structure and signal parameters, but
44// different instances of the background parameters: e.g.
45//
46// ...
47// RooExponential bg("bg","background",x,alpha) ;
48// RooGaussian sig("sig","signal",x,mean,sigma) ;
49// RooAddPdf pdf("pdf","pdf",sig,bg,sigfrac) ;
50//
51// RooDataSet data("data","dataset",RooArgSet(x,runblock),...)
52//
53// RooCategory runblock("runblock","run block") ;
54// runblock.defineType("run1") ;
55// runblock.defineType("run2") ;
56//
57// RooArgSet splitLeafs
58// RooCustomizer cust(pdf,runblock,splitLeafs)
59// cust.split(alpha,runblock)
60//
61// RooAbsPdf* pdf_run1 = cust.build("run1") ;
62// RooAbsPdf* pdf_run2 = cust.build("run2") ;
63//
64// RooSimultaneous simpdf("simpdf","simpdf",RooArgSet(*pdf_run1,*pdf_run2))
65//
66// If the master category state is a super category, leafs may be split
67// by any subset of that master category. E.g. if the master category
68// is 'A x B', leafs may be split by A, B or AxB.
69//
70// In addition to replacing leaf nodes, RooCustomizer clones all branch
71// nodes that depend directly or indirectly on modified leaf nodes, so
72// that the input pdf is untouched by each build operation.
73//
74// The customizer owns all the branch nodes including the returned top
75// level node, so the customizer should live as longs as the cloned
76// composites are needed.
77//
78// Any leaf nodes that are created by the customizer will be put into
79// the leaf list that is passed into the customizers constructor (splitLeafs in
80// the above example. The list owner is responsible for deleting these leaf
81// nodes after the customizer is deleted.
82//
83//
84// [Advanced techniques]
85//
86// By default the customizer clones the prototype leaf node when splitting a leaf,
87// but the user can feed pre-defined split leafs in leaf list. These leafs
88// must have the name <split_leaf>_<splitcat_label> to be picked up. The list
89// of pre-supplied leafs may be partial, any missing split leafs will be auto
90// generated.
91//
92// Another common construction is to have two prototype PDFs, each to be customized
93// by a separate customizer instance, that share parameters. To ensure that
94// the customized clones also share their respective split leafs, i.e.
95//
96// PDF1(x,y;A) and PDF2(z,A) ---> PDF1_run1(x,y,A_run1) and PDF2_run1(x,y,A_run1)
97// PDF1_run2(x,y,A_run2) and PDF2_run2(x,y,A_run2)
98//
99// feed the same split leaf list into both customizers. In that case the second customizer
100// will pick up the split leafs instantiated by the first customizer and the link between
101// the two PDFs is retained
102//
103//
104
105
106#include "RooFit.h"
107
108#include "TClass.h"
109#include "TStopwatch.h"
110
111#include "RooAbsCategoryLValue.h"
112#include "RooAbsCategory.h"
113#include "RooAbsArg.h"
114#include "RooAbsPdf.h"
115#include "RooArgSet.h"
116#include "RooArgList.h"
117#include "RooMsgService.h"
118
119#include "RooCustomizer.h"
120
121#include "Riostream.h"
122#include "RooWorkspace.h"
123#include "RooGlobalFunc.h"
124#include "RooConstVar.h"
125#include "RooRealConstant.h"
126
127
128#ifndef _WIN32
129#include <strings.h>
130#endif
131
132
133using namespace std;
134
136;
137
138
139static Int_t init();
140
141static Int_t dummy = init() ;
142
143static Int_t init()
144{
147 (void) dummy;
148 return 0 ;
149}
150
151
152////////////////////////////////////////////////////////////////////////////////
153/// Constructor with a prototype and masterCat index category.
154/// Customizers created by this constructor offer offer both the
155/// replaceArg() and splitArg() functionality. All nodes created in
156/// the customization process are added to the splitLeafs set.
157/// If the customizer is owning, the splitLeafs set will become
158/// owner of all created objects by the customizer
159///
160
161RooCustomizer::RooCustomizer(const RooAbsArg& pdf, const RooAbsCategoryLValue& masterCat, RooArgSet& splitLeafs, RooArgSet* splitLeafsAll) :
162 TNamed(pdf.GetName(),pdf.GetTitle()),
163 _sterile(kFALSE),
164 _owning(kTRUE),
165 _masterPdf((RooAbsArg*)&pdf),
166 _masterCat((RooAbsCategoryLValue*)&masterCat),
167 _masterBranchList("masterBranchList"),
168 _masterLeafList("masterLeafList"),
169 _internalCloneBranchList("cloneBranchList"),
170 _cloneNodeListAll(splitLeafsAll),
171 _cloneNodeListOwned(&splitLeafs)
172{
175
178
179 initialize() ;
180}
181
182
183
184////////////////////////////////////////////////////////////////////////////////
185/// Sterile Constructor. Customizers created by this constructor
186/// offer only the replace() method. The supplied 'name' is used as
187/// suffix for any cloned branch nodes
188
190 TNamed(pdf.GetName(),pdf.GetTitle()),
191 _sterile(kTRUE),
192 _owning(kFALSE),
193 _name(name),
194 _masterPdf((RooAbsArg*)&pdf),
195 _masterCat(0),
196 _masterBranchList("masterBranchList"),
197 _masterLeafList("masterLeafList"),
198 _internalCloneBranchList("cloneBranchList"),
199 _cloneNodeListAll(0),
200 _cloneNodeListOwned(0)
201{
204
207
208 initialize() ;
209}
210
211
212
213
214////////////////////////////////////////////////////////////////////////////////
215/// Initialize the customizer
216
218{
221
224}
225
226
227
228////////////////////////////////////////////////////////////////////////////////
229/// Destructor
230
232{
233 delete _masterLeafListIter ;
234 delete _masterBranchListIter ;
235
236}
237
238
239
240
241////////////////////////////////////////////////////////////////////////////////
242/// Split all arguments in 'set' into individualized clones for each
243/// defined state of 'splitCat'. The 'splitCats' category must be
244/// subset of or equal to the master category supplied in the
245/// customizer constructor.
246///
247/// Splitting is only available on customizers created with a master index category
248
249void RooCustomizer::splitArgs(const RooArgSet& set, const RooAbsCategory& splitCat)
250{
251 if (_sterile) {
252 coutE(InputArguments) << "RooCustomizer::splitArgs(" << _name
253 << ") ERROR cannot set spitting rules on this sterile customizer" << endl ;
254 return ;
255 }
256 TIterator* iter = set.createIterator() ;
257 RooAbsArg* arg ;
258 while((arg=(RooAbsArg*)iter->Next())){
259 splitArg(*arg,splitCat) ;
260 }
261 delete iter ;
262}
263
264
265
266////////////////////////////////////////////////////////////////////////////////
267/// Split all argument 'arg' into individualized clones for each
268/// defined state of 'splitCat'. The 'splitCats' category must be
269/// subset of or equal to the master category supplied in the
270/// customizer constructor.
271///
272/// Splitting is only available on customizers created with a master index category
273
274void RooCustomizer::splitArg(const RooAbsArg& arg, const RooAbsCategory& splitCat)
275{
276 if (_splitArgList.FindObject(arg.GetName())) {
277 coutE(InputArguments) << "RooCustomizer(" << GetName() << ") ERROR: multiple splitting rules defined for "
278 << arg.GetName() << " only using first rule" << endl ;
279 return ;
280 }
281
282 if (_sterile) {
283 coutE(InputArguments) << "RooCustomizer::splitArg(" << _name
284 << ") ERROR cannot set spitting rules on this sterile customizer" << endl ;
285 return ;
286 }
287
288 _splitArgList.Add((RooAbsArg*)&arg) ;
289 _splitCatList.Add((RooAbsCategory*)&splitCat) ;
290}
291
292
293
294////////////////////////////////////////////////////////////////////////////////
295/// Replace any occurence of arg 'orig' with arg 'subst'
296
297void RooCustomizer::replaceArg(const RooAbsArg& orig, const RooAbsArg& subst)
298{
299 if (_replaceArgList.FindObject(orig.GetName())) {
300 coutE(InputArguments) << "RooCustomizer(" << GetName() << ") ERROR: multiple replacement rules defined for "
301 << orig.GetName() << " only using first rule" << endl ;
302 return ;
303 }
304
305 _replaceArgList.Add((RooAbsArg*)&orig) ;
306 _replaceSubList.Add((RooAbsArg*)&subst) ;
307}
308
309
310
311////////////////////////////////////////////////////////////////////////////////
312/// Build a clone of the prototype executing all registered 'replace' rules
313/// If verbose is set a message is printed for each leaf or branch node
314/// modification. The returned head node owns all cloned branch nodes
315/// that were created in the cloning proces
316
318{
319 // Execute build
320 RooAbsArg* ret = doBuild(_name.Length()>0?_name.Data():0,verbose) ;
321
322 // Make root object own all cloned nodes
323
324 // First make list of all objects that were created
325 RooArgSet allOwned ;
327 allOwned.add(*_cloneNodeListOwned) ;
328 }
329 allOwned.add(*_cloneBranchList) ;
330
331 // Remove head node from list
332 allOwned.remove(*ret) ;
333
334 // If list with owned objects is not empty, assign
335 // head node as owner
336 if (allOwned.getSize()>0) {
337 ret->addOwnedComponents(allOwned) ;
338 }
339
340 return ret ;
341}
342
343
344
345////////////////////////////////////////////////////////////////////////////////
346/// Build a clone of the prototype executing all registered 'replace'
347/// rules and 'split' rules for the masterCat state named
348/// 'masterCatState'. If verbose is set a message is printed for
349/// each leaf or branch node modification. The returned composite arg
350/// is owned by the customizer. This function cannot be called on
351/// customizer build with the sterile constructor.
352
353RooAbsArg* RooCustomizer::build(const char* masterCatState, Bool_t verbose)
354{
355 if (_sterile) {
356 coutE(InputArguments) << "RooCustomizer::build(" << _name
357 << ") ERROR cannot use leaf spitting build() on this sterile customizer" << endl ;
358 return 0 ;
359 }
360
361 // Set masterCat to given state
362 if (_masterCat->setLabel(masterCatState)) {
363 coutE(InputArguments) << "RooCustomizer::build(" << _masterPdf->GetName() << "): ERROR label '" << masterCatState
364 << "' not defined for master splitting category " << _masterCat->GetName() << endl ;
365 return 0 ;
366 }
367
368 return doBuild(masterCatState,verbose) ;
369}
370
371
372
373////////////////////////////////////////////////////////////////////////////////
374/// Back-end implementation of the p.d.f building functionality
375
376RooAbsArg* RooCustomizer::doBuild(const char* masterCatState, Bool_t verbose)
377{
378 // Find nodes that must be split according to provided description, Clone nodes, change their names
379 RooArgSet masterNodesToBeSplit("masterNodesToBeSplit") ;
380 RooArgSet masterNodesToBeReplaced("masterNodesToBeReplaced") ;
381 RooArgSet masterReplacementNodes("masterReplacementNodes") ;
382 RooArgSet clonedMasterNodes("clonedMasterNodes") ;
383
384 masterNodesToBeSplit.setHashTableSize(1000) ;
385 masterNodesToBeReplaced.setHashTableSize(1000) ;
386 masterReplacementNodes.setHashTableSize(1000) ;
387 clonedMasterNodes.setHashTableSize(1000) ;
388
390 RooAbsArg* node ;
391
392 RooArgSet nodeList(_masterLeafList) ;
393 nodeList.setHashTableSize(1000) ;
394
395 nodeList.add(_masterBranchList) ;
396 TIterator* nIter = nodeList.createIterator() ;
397
398 // cout << "loop over " << nodeList.getSize() << " nodes" << endl ;
399 while((node=(RooAbsArg*)nIter->Next())) {
400 RooAbsArg* theSplitArg = !_sterile?(RooAbsArg*) _splitArgList.FindObject(node->GetName()):0 ;
401 if (theSplitArg) {
403 if (verbose) {
404 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName()
405 << "): tree node " << node->GetName() << " is split by category " << splitCat->GetName() << endl ;
406 }
407
408 TString newName(node->GetName()) ;
409 if (masterCatState) {
410 newName.Append("_") ;
411 newName.Append(splitCat->getLabel()) ;
412 }
413
414 // Check if this node instance already exists
415 RooAbsArg* specNode = _cloneNodeListAll ? _cloneNodeListAll->find(newName) : _cloneNodeListOwned->find(newName) ;
416 if (specNode) {
417
418 // Copy instance to one-time use list for this build
419 clonedMasterNodes.add(*specNode) ;
420 if (verbose) {
421 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName()
422 << ") Adding existing node specialization " << newName << " to clonedMasterNodes" << endl ;
423 }
424
425 // Affix attribute with old name to clone to support name changing server redirect
426 TString nameAttrib("ORIGNAME:") ;
427 nameAttrib.Append(node->GetName()) ;
428 specNode->setAttribute(nameAttrib) ;
429
430 if (!specNode->getStringAttribute("origName")) {
431 specNode->setStringAttribute("origName",node->GetName()) ;
432 }
433
434
435
436 } else {
437
438 if (node->isDerived()) {
439 coutW(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName()
440 << "): WARNING: branch node " << node->GetName() << " is split but has no pre-defined specializations" << endl ;
441 }
442
443 TString newTitle(node->GetTitle()) ;
444 newTitle.Append(" (") ;
445 newTitle.Append(splitCat->getLabel()) ;
446 newTitle.Append(")") ;
447
448 // Create a new clone
449 RooAbsArg* clone = (RooAbsArg*) node->Clone(newName.Data()) ;
450 clone->setStringAttribute("factory_tag",0) ;
451 clone->SetTitle(newTitle) ;
452
453 // Affix attribute with old name to clone to support name changing server redirect
454 TString nameAttrib("ORIGNAME:") ;
455 nameAttrib.Append(node->GetName()) ;
456 clone->setAttribute(nameAttrib) ;
457
458 if (!clone->getStringAttribute("origName")) {
459 clone->setStringAttribute("origName",node->GetName()) ;
460 }
461
462 // Add to one-time use list and life-time use list
463 clonedMasterNodes.add(*clone) ;
464 if (_owning) {
465 _cloneNodeListOwned->addOwned(*clone) ;
466 } else {
467 _cloneNodeListOwned->add(*clone) ;
468 }
469 if (_cloneNodeListAll) {
470 _cloneNodeListAll->add(*clone) ;
471 }
472 }
473 masterNodesToBeSplit.add(*node) ;
474 }
475
476 RooAbsArg* ReplaceArg = (RooAbsArg*) _replaceArgList.FindObject(node->GetName()) ;
477 if (ReplaceArg) {
478 RooAbsArg* substArg = (RooAbsArg*) _replaceSubList.At(_replaceArgList.IndexOf(ReplaceArg)) ;
479 if (verbose) {
480 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName()
481 << "): tree node " << node->GetName() << " will be replaced by " << substArg->GetName() << endl ;
482 }
483
484 // Affix attribute with old name to support name changing server redirect
485 TString nameAttrib("ORIGNAME:") ;
486 nameAttrib.Append(node->GetName()) ;
487 substArg->setAttribute(nameAttrib) ;
488
489 // Add to list
490 masterNodesToBeReplaced.add(*node) ;
491 masterReplacementNodes.add(*substArg) ;
492 }
493 }
494 delete nIter ;
495
496 // Find branches that are affected by splitting and must be cloned
497 RooArgSet masterBranchesToBeCloned("masterBranchesToBeCloned") ;
498 masterBranchesToBeCloned.setHashTableSize(1000) ;
500 RooAbsArg* branch ;
501 while((branch=(RooAbsArg*)_masterBranchListIter->Next())) {
502
503 // If branch is split itself, don't handle here
504 if (masterNodesToBeSplit.find(branch->GetName())) {
505 if (verbose) {
506 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node " << branch->GetName() << " is already split" << endl ;
507 }
508 continue ;
509 }
510 if (masterNodesToBeReplaced.find(branch->GetName())) {
511 if (verbose) {
512 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node " << branch->GetName() << " is already replaced" << endl ;
513 }
514 continue ;
515 }
516
517 if (branch->dependsOn(masterNodesToBeSplit)) {
518 if (verbose) {
519 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node "
520 << branch->IsA()->GetName() << "::" << branch->GetName() << " cloned: depends on a split parameter" << endl ;
521 }
522 masterBranchesToBeCloned.add(*branch) ;
523 } else if (branch->dependsOn(masterNodesToBeReplaced)) {
524 if (verbose) {
525 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node "
526 << branch->IsA()->GetName() << "::" << branch->GetName() << " cloned: depends on a replaced parameter" << endl ;
527 }
528 masterBranchesToBeCloned.add(*branch) ;
529 }
530 }
531
532 // Clone branches, changes their names
533 RooAbsArg* cloneTopPdf = 0;
534 RooArgSet clonedMasterBranches("clonedMasterBranches") ;
535 clonedMasterBranches.setHashTableSize(1000) ;
536 TIterator* iter = masterBranchesToBeCloned.createIterator() ;
537 while((branch=(RooAbsArg*)iter->Next())) {
538 TString newName(branch->GetName()) ;
539 if (masterCatState) {
540 newName.Append("_") ;
541 newName.Append(masterCatState) ;
542 }
543
544 // Affix attribute with old name to clone to support name changing server redirect
545 RooAbsArg* clone = (RooAbsArg*) branch->Clone(newName.Data()) ;
546 clone->setStringAttribute("factory_tag",0) ;
547 TString nameAttrib("ORIGNAME:") ;
548 nameAttrib.Append(branch->GetName()) ;
549 clone->setAttribute(nameAttrib) ;
550
551 if (!clone->getStringAttribute("origName")) {
552 clone->setStringAttribute("origName",branch->GetName()) ;
553 }
554
555 clonedMasterBranches.add(*clone) ;
556
557 // Save pointer to clone of top-level pdf
558 if (branch==_masterPdf) cloneTopPdf=(RooAbsArg*)clone ;
559 }
560 delete iter ;
561 if (_owning) {
562 _cloneBranchList->addOwned(clonedMasterBranches) ;
563 } else {
564 _cloneBranchList->add(clonedMasterBranches) ;
565 }
566
567 // Reconnect cloned branches to each other and to cloned nodess
568 iter = clonedMasterBranches.createIterator() ;
569 while((branch=(RooAbsArg*)iter->Next())) {
570 branch->redirectServers(clonedMasterBranches,kFALSE,kTRUE) ;
571 branch->redirectServers(clonedMasterNodes,kFALSE,kTRUE) ;
572 branch->redirectServers(masterReplacementNodes,kFALSE,kTRUE) ;
573 }
574 delete iter ;
575
576 return cloneTopPdf?cloneTopPdf:_masterPdf ;
577}
578
579
580////////////////////////////////////////////////////////////////////////////////
581/// Print name of customizer
582
583void RooCustomizer::printName(ostream& os) const
584{
585 os << GetName() ;
586}
587
588
589////////////////////////////////////////////////////////////////////////////////
590/// Print title of customizer
591
592void RooCustomizer::printTitle(ostream& os) const
593{
594 os << GetTitle() ;
595}
596
597
598////////////////////////////////////////////////////////////////////////////////
599/// Print class name of customizer
600
601void RooCustomizer::printClassName(ostream& os) const
602{
603 os << IsA()->GetName() ;
604}
605
606
607////////////////////////////////////////////////////////////////////////////////
608/// Print arguments of customizer, i.e. input p.d.f and input master category (if any)
609
610void RooCustomizer::printArgs(ostream& os) const
611{
612 os << "[ masterPdf=" << _masterPdf->GetName() ;
613 if (_masterCat) {
614 os << " masterCat=" << _masterCat->GetName() ;
615 }
616 os << " ]" ;
617}
618
619
620
621////////////////////////////////////////////////////////////////////////////////
622/// Print customizer configuration details
623
624void RooCustomizer::printMultiline(ostream& os, Int_t /*content*/, Bool_t /*verbose*/, TString indent) const
625{
626 os << indent << "RooCustomizer for " << _masterPdf->GetName() << (_sterile?" (sterile)":"") << endl ;
627
628 Int_t i, nsplit = _splitArgList.GetSize() ;
629 if (nsplit>0) {
630 os << indent << " Splitting rules:" << endl ;
631 for (i=0 ; i<nsplit ; i++) {
632 os << indent << " " << _splitArgList.At(i)->GetName() << " is split by " << _splitCatList.At(i)->GetName() << endl ;
633 }
634 }
635
636 Int_t nrepl = _replaceArgList.GetSize() ;
637 if (nrepl>0) {
638 os << indent << " Replacement rules:" << endl ;
639 for (i=0 ; i<nrepl ; i++) {
640 os << indent << " " << _replaceSubList.At(i)->GetName() << " replaces " << _replaceArgList.At(i)->GetName() << endl ;
641 }
642 }
643
644 return ;
645}
646
647
648
649////////////////////////////////////////////////////////////////////////////////
650/// Install the input RooArgSet as container in which all cloned branches
651/// will be stored
652
654{
655 _cloneBranchList = &cloneBranchSet ;
657}
658
659
660
661
662////////////////////////////////////////////////////////////////////////////////
663
664std::string RooCustomizer::CustIFace::create(RooFactoryWSTool& ft, const char* typeName, const char* instanceName, std::vector<std::string> args)
665{
666 // Check number of arguments
667 if (args.size()<2) {
668 throw string(Form("RooCustomizer::CustIFace::create() ERROR: expect at least 2 arguments for EDIT: the input object and at least one $Replace() rule")) ;
669 }
670
671 if (string(typeName)!="EDIT") {
672 throw string(Form("RooCustomizer::CustIFace::create() ERROR: unknown type requested: %s",typeName)) ;
673 }
674
675 // Check that first arg exists as RooAbsArg
676 RooAbsArg* arg = ft.ws().arg(args[0].c_str()) ;
677 if (!arg) {
678 throw string(Form("RooCustomizer::CustIFace::create() ERROR: input RooAbsArg %s does not exist",args[0].c_str())) ;
679 }
680
681 // If name of new object is same as original, execute in sterile mode (i.e no suffixes attached), and rename original nodes in workspace upon import
682 if (args[0]==instanceName) {
683 instanceName=0 ;
684 }
685
686 // Create a customizer
687 RooCustomizer cust(*arg,instanceName) ;
688
689 for (unsigned int i=1 ; i<args.size() ; i++) {
690 char buf[1024] ;
691 strlcpy(buf,args[i].c_str(),1024) ;
692 char* sep = strchr(buf,'=') ;
693 if (!sep) {
694 throw string(Form("RooCustomizer::CustIFace::create() ERROR: unknown argument: %s, expect form orig=subst",args[i].c_str())) ;
695 }
696 *sep = 0 ;
697 RooAbsArg* orig = ft.ws().arg(buf) ;
698 RooAbsArg* subst(0) ;
699 if (string(sep+1).find("$REMOVE")==0) {
700
701 // Create a removal dummy ;
703
704 // If removal instructed was annotated with target node, encode these in removal dummy
705 char* sep2 = strchr(sep+1,'(') ;
706 if (sep2) {
707 char buf2[1024] ;
708 strlcpy(buf2,sep2+1,1024) ;
709 char* saveptr ;
710 char* tok = R__STRTOK_R(buf2,",)",&saveptr) ;
711 while(tok) {
712 //cout << "$REMOVE is restricted to " << tok << endl ;
713 subst->setAttribute(Form("REMOVE_FROM_%s",tok)) ;
714 tok = R__STRTOK_R(0,",)",&saveptr) ;
715 }
716 } else {
717 // Otherwise mark as universal removal node
718 subst->setAttribute("REMOVE_ALL") ;
719 }
720
721 } else {
722 subst = ft.ws().arg(sep+1) ;
723 }
724// if (!orig) {
725// throw string(Form("RooCustomizer::CustIFace::create() ERROR: $Replace() input RooAbsArg %s does not exist",buf)) ;
726// }
727// if (!subst) {
728// throw string(Form("RooCustomizer::CustIFace::create() ERROR: $Replace() replacement RooAbsArg %s does not exist",sep+1)) ;
729// }
730 if (orig && subst) {
731 cust.replaceArg(*orig,*subst) ;
732 } else {
733 oocoutW((TObject*)0,ObjectHandling) << "RooCustomizer::CustIFace::create() WARNING: input or replacement of a replacement operation not found, operation ignored"<< endl ;
734 }
735 }
736
737 // Build the desired edited object
738 RooAbsArg* targ = cust.build(kFALSE) ;
739 if (!targ) {
740 throw string(Form("RooCustomizer::CustIFace::create() ERROR in customizer build, object %snot created",instanceName)) ;
741 }
742
743 // Import the object into the workspace
744 if (instanceName) {
745 // Set the desired name of the top level node
746 targ->SetName(instanceName) ;
748 } else {
750 }
751
752 return string(instanceName?instanceName:targ->GetName()) ;
753}
static Int_t dummy
static Int_t init()
#define coutI(a)
Definition: RooMsgService.h:31
#define oocoutW(o, a)
Definition: RooMsgService.h:46
#define coutW(a)
Definition: RooMsgService.h:33
#define coutE(a)
Definition: RooMsgService.h:34
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
char * R__STRTOK_R(char *str, const char *delim, char **saveptr)
Definition: Rtypes.h:484
char * Form(const char *fmt,...)
typedef void((*Func_t)())
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
Bool_t redirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t isRecursionStep=kFALSE)
Iterator over _clientListValue.
Definition: RooAbsArg.cxx:921
Bool_t dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=0, Bool_t valueOnly=kFALSE) const
Test whether we depend on (ie, are served by) any object in the specified collection.
Definition: RooAbsArg.cxx:736
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
Definition: RooAbsArg.cxx:273
void leafNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=0, Bool_t recurseNonDerived=kFALSE) const
Fill supplied list with all leaf nodes of the arg tree, starting with ourself as top node.
Definition: RooAbsArg.cxx:466
virtual TObject * Clone(const char *newname=0) const
Make a clone of an object using the Streamer facility.
Definition: RooAbsArg.h:75
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
Definition: RooAbsArg.cxx:286
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
Definition: RooAbsArg.cxx:241
virtual Bool_t isDerived() const
Definition: RooAbsArg.h:81
Bool_t addOwnedComponents(const RooArgSet &comps)
Take ownership of the contents of 'comps'.
Definition: RooAbsArg.cxx:2274
void branchNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=0, Bool_t recurseNonDerived=kFALSE) const
Fill supplied list with all branch nodes of the arg tree starting with ourself as top node.
Definition: RooAbsArg.cxx:477
void SetName(const char *name)
Set the name of the TNamed.
Definition: RooAbsArg.cxx:2382
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
virtual Bool_t setLabel(const char *label, Bool_t printError=kTRUE)=0
RooAbsCategory is the common abstract base class for objects that represent a discrete value with a f...
virtual const char * getLabel() const
Return label string of current state.
Int_t getSize() const
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
void setHashTableSize(Int_t i)
TIterator * createIterator(Bool_t dir=kIterForward) const
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
virtual Bool_t addOwned(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling addOwned() for each element in the source...
Definition: RooArgSet.h:92
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:88
std::string create(RooFactoryWSTool &ft, const char *typeName, const char *instanceName, std::vector< std::string > args)
TList _splitArgList
Definition: RooCustomizer.h:94
void splitArg(const RooAbsArg &arg, const RooAbsCategory &splitCat)
Split all argument 'arg' into individualized clones for each defined state of 'splitCat'.
void setCloneBranchSet(RooArgSet &cloneBranchSet)
Install the input RooArgSet as container in which all cloned branches will be stored.
RooArgSet * _cloneNodeListAll
void replaceArg(const RooAbsArg &orig, const RooAbsArg &subst)
Replace any occurence of arg 'orig' with arg 'subst'.
RooAbsArg * _masterPdf
TList _replaceSubList
Definition: RooCustomizer.h:98
const RooArgSet & cloneBranchList() const
Definition: RooCustomizer.h:52
RooArgSet * _cloneBranchList
virtual void printName(std::ostream &os) const
Print name of customizer.
TIterator * _masterLeafListIter
virtual void printTitle(std::ostream &os) const
Print title of customizer.
RooCustomizer(const RooAbsArg &pdf, const RooAbsCategoryLValue &masterCat, RooArgSet &splitLeafListOwned, RooArgSet *splitLeafListAll=0)
Constructor with a prototype and masterCat index category.
virtual void printMultiline(std::ostream &os, Int_t content, Bool_t verbose=kFALSE, TString indent="") const
Print customizer configuration details.
RooArgSet _masterBranchList
RooAbsArg * doBuild(const char *masterCatState, Bool_t verbose)
Back-end implementation of the p.d.f building functionality.
RooArgSet _masterLeafList
virtual void printClassName(std::ostream &os) const
Print class name of customizer.
virtual ~RooCustomizer()
Destructor.
RooArgSet _internalCloneBranchList
void initialize()
Initialize the customizer.
TIterator * _masterBranchListIter
RooAbsCategoryLValue * _masterCat
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...
TList _replaceArgList
Definition: RooCustomizer.h:97
TList _splitCatList
Definition: RooCustomizer.h:95
RooArgSet * _cloneNodeListOwned
virtual void printArgs(std::ostream &os) const
Print arguments of customizer, i.e. input p.d.f and input master category (if any)
RooFactoryWSTool is a clase like TTree::MakeClass() that generates skeleton code for RooAbsPdf and Ro...
RooWorkspace & ws()
static void registerSpecial(const char *typeName, RooFactoryWSTool::IFace *iface)
Register foreign special objects in factory.
static RooConstVar & removalDummy()
Create a dummy node used in node-removal operations.
RooAbsArg * arg(const char *name) const
Return RooAbsArg with given name. A null pointer is returned if none is found.
Bool_t import(const RooAbsArg &arg, const RooCmdArg &arg1=RooCmdArg(), const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg(), const RooCmdArg &arg7=RooCmdArg(), const RooCmdArg &arg8=RooCmdArg(), const RooCmdArg &arg9=RooCmdArg())
Import a RooAbsArg object, e.g.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Iterator abstract base class.
Definition: TIterator.h:30
virtual void Reset()=0
virtual TObject * Next()=0
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Definition: TList.cxx:574
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:357
virtual Int_t IndexOf(const TObject *obj) const
Return index of object in collection.
std::string GetName(const std::string &scope_name)
Definition: Cppyy.cxx:146
RooCmdArg NoRecursion(Bool_t flag=kTRUE)
RooCmdArg RenameConflictNodes(const char *suffix, Bool_t renameOrigNodes=kFALSE)
@ InputArguments
Definition: RooGlobalFunc.h:58
@ ObjectHandling
Definition: RooGlobalFunc.h:58
RooCmdArg Silence(Bool_t flag=kTRUE)
STL namespace.