00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 #include "RooFit.h"
00107
00108 #include "TClass.h"
00109 #include "TStopwatch.h"
00110
00111 #include "RooAbsCategoryLValue.h"
00112 #include "RooAbsCategory.h"
00113 #include "RooAbsArg.h"
00114 #include "RooAbsPdf.h"
00115 #include "RooArgSet.h"
00116 #include "RooArgList.h"
00117 #include "RooMsgService.h"
00118
00119 #include "RooCustomizer.h"
00120
00121 #include "Riostream.h"
00122 #include "RooWorkspace.h"
00123 #include "RooGlobalFunc.h"
00124
00125 ClassImp(RooCustomizer)
00126 ;
00127
00128
00129 static Int_t init()
00130 {
00131 RooFactoryWSTool::IFace* iface = new RooCustomizer::CustIFace ;
00132 RooFactoryWSTool::registerSpecial("EDIT",iface) ;
00133 return 0 ;
00134 }
00135 static Int_t dummy = init() ;
00136
00137
00138
00139
00140 RooCustomizer::RooCustomizer(const RooAbsArg& pdf, const RooAbsCategoryLValue& masterCat, RooArgSet& splitLeafs, RooArgSet* splitLeafsAll) :
00141 TNamed(pdf.GetName(),pdf.GetTitle()),
00142 _sterile(kFALSE),
00143 _owning(kTRUE),
00144 _masterPdf((RooAbsArg*)&pdf),
00145 _masterCat((RooAbsCategoryLValue*)&masterCat),
00146 _masterBranchList("masterBranchList"),
00147 _masterLeafList("masterLeafList"),
00148 _internalCloneBranchList("cloneBranchList"),
00149 _cloneNodeListAll(splitLeafsAll),
00150 _cloneNodeListOwned(&splitLeafs)
00151 {
00152
00153
00154
00155
00156
00157
00158
00159
00160 _masterBranchList.setHashTableSize(1000) ;
00161 _masterLeafList.setHashTableSize(1000) ;
00162
00163 _cloneBranchList = &_internalCloneBranchList ;
00164 _cloneBranchList->setHashTableSize(1000) ;
00165
00166 initialize() ;
00167 }
00168
00169
00170
00171
00172 RooCustomizer::RooCustomizer(const RooAbsArg& pdf, const char* name) :
00173 TNamed(pdf.GetName(),pdf.GetTitle()),
00174 _sterile(kTRUE),
00175 _owning(kFALSE),
00176 _name(name),
00177 _masterPdf((RooAbsArg*)&pdf),
00178 _masterCat(0),
00179 _masterBranchList("masterBranchList"),
00180 _masterLeafList("masterLeafList"),
00181 _internalCloneBranchList("cloneBranchList"),
00182 _cloneNodeListAll(0),
00183 _cloneNodeListOwned(0)
00184 {
00185
00186
00187
00188
00189 _masterBranchList.setHashTableSize(1000) ;
00190 _masterLeafList.setHashTableSize(1000) ;
00191
00192 _cloneBranchList = &_internalCloneBranchList ;
00193 _cloneBranchList->setHashTableSize(1000) ;
00194
00195 initialize() ;
00196 }
00197
00198
00199
00200
00201
00202 void RooCustomizer::initialize()
00203 {
00204
00205
00206 _masterPdf->leafNodeServerList(&_masterLeafList) ;
00207 _masterPdf->branchNodeServerList(&_masterBranchList) ;
00208
00209 _masterLeafListIter = _masterLeafList.createIterator() ;
00210 _masterBranchListIter = _masterBranchList.createIterator() ;
00211 }
00212
00213
00214
00215
00216 RooCustomizer::~RooCustomizer()
00217 {
00218
00219
00220 delete _masterLeafListIter ;
00221 delete _masterBranchListIter ;
00222
00223 }
00224
00225
00226
00227
00228
00229 void RooCustomizer::splitArgs(const RooArgSet& set, const RooAbsCategory& splitCat)
00230 {
00231
00232
00233
00234
00235
00236
00237
00238 if (_sterile) {
00239 coutE(InputArguments) << "RooCustomizer::splitArgs(" << _name
00240 << ") ERROR cannot set spitting rules on this sterile customizer" << endl ;
00241 return ;
00242 }
00243 TIterator* iter = set.createIterator() ;
00244 RooAbsArg* arg ;
00245 while((arg=(RooAbsArg*)iter->Next())){
00246 splitArg(*arg,splitCat) ;
00247 }
00248 delete iter ;
00249 }
00250
00251
00252
00253
00254 void RooCustomizer::splitArg(const RooAbsArg& arg, const RooAbsCategory& splitCat)
00255 {
00256
00257
00258
00259
00260
00261
00262
00263 if (_splitArgList.FindObject(arg.GetName())) {
00264 coutE(InputArguments) << "RooCustomizer(" << GetName() << ") ERROR: multiple splitting rules defined for "
00265 << arg.GetName() << " only using first rule" << endl ;
00266 return ;
00267 }
00268
00269 if (_sterile) {
00270 coutE(InputArguments) << "RooCustomizer::splitArg(" << _name
00271 << ") ERROR cannot set spitting rules on this sterile customizer" << endl ;
00272 return ;
00273 }
00274
00275 _splitArgList.Add((RooAbsArg*)&arg) ;
00276 _splitCatList.Add((RooAbsCategory*)&splitCat) ;
00277 }
00278
00279
00280
00281
00282 void RooCustomizer::replaceArg(const RooAbsArg& orig, const RooAbsArg& subst)
00283 {
00284
00285
00286 if (_replaceArgList.FindObject(orig.GetName())) {
00287 coutE(InputArguments) << "RooCustomizer(" << GetName() << ") ERROR: multiple replacement rules defined for "
00288 << orig.GetName() << " only using first rule" << endl ;
00289 return ;
00290 }
00291
00292 _replaceArgList.Add((RooAbsArg*)&orig) ;
00293 _replaceSubList.Add((RooAbsArg*)&subst) ;
00294 }
00295
00296
00297
00298
00299 RooAbsArg* RooCustomizer::build(Bool_t verbose)
00300 {
00301
00302
00303
00304
00305
00306
00307 RooAbsArg* ret = doBuild(_name,verbose) ;
00308
00309
00310
00311
00312 RooArgSet allOwned ;
00313 if (_cloneNodeListOwned) {
00314 allOwned.add(*_cloneNodeListOwned) ;
00315 }
00316 allOwned.add(*_cloneBranchList) ;
00317
00318
00319 allOwned.remove(*ret) ;
00320
00321
00322
00323 if (allOwned.getSize()>0) {
00324 ret->addOwnedComponents(allOwned) ;
00325 }
00326
00327 return ret ;
00328 }
00329
00330
00331
00332
00333 RooAbsArg* RooCustomizer::build(const char* masterCatState, Bool_t verbose)
00334 {
00335
00336
00337
00338
00339
00340
00341
00342 if (_sterile) {
00343 coutE(InputArguments) << "RooCustomizer::build(" << _name
00344 << ") ERROR cannot use leaf spitting build() on this sterile customizer" << endl ;
00345 return 0 ;
00346 }
00347
00348
00349 if (_masterCat->setLabel(masterCatState)) {
00350 coutE(InputArguments) << "RooCustomizer::build(" << _masterPdf->GetName() << "): ERROR label '" << masterCatState
00351 << "' not defined for master splitting category " << _masterCat->GetName() << endl ;
00352 return 0 ;
00353 }
00354
00355 return doBuild(masterCatState,verbose) ;
00356 }
00357
00358
00359
00360
00361 RooAbsArg* RooCustomizer::doBuild(const char* masterCatState, Bool_t verbose)
00362 {
00363
00364
00365
00366 RooArgSet masterNodesToBeSplit("masterNodesToBeSplit") ;
00367 RooArgSet masterNodesToBeReplaced("masterNodesToBeReplaced") ;
00368 RooArgSet masterReplacementNodes("masterReplacementNodes") ;
00369 RooArgSet clonedMasterNodes("clonedMasterNodes") ;
00370
00371 masterNodesToBeSplit.setHashTableSize(1000) ;
00372 masterNodesToBeReplaced.setHashTableSize(1000) ;
00373 masterReplacementNodes.setHashTableSize(1000) ;
00374 clonedMasterNodes.setHashTableSize(1000) ;
00375
00376 _masterLeafListIter->Reset() ;
00377 RooAbsArg* node ;
00378
00379 RooArgSet nodeList(_masterLeafList) ;
00380 nodeList.setHashTableSize(1000) ;
00381
00382 nodeList.add(_masterBranchList) ;
00383 TIterator* nIter = nodeList.createIterator() ;
00384
00385
00386 while((node=(RooAbsArg*)nIter->Next())) {
00387 RooAbsArg* theSplitArg = !_sterile?(RooAbsArg*) _splitArgList.FindObject(node->GetName()):0 ;
00388 if (theSplitArg) {
00389 RooAbsCategory* splitCat = (RooAbsCategory*) _splitCatList.At(_splitArgList.IndexOf(theSplitArg)) ;
00390 if (verbose) {
00391 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName()
00392 << "): tree node " << node->GetName() << " is split by category " << splitCat->GetName() << endl ;
00393 }
00394
00395 TString newName(node->GetName()) ;
00396 newName.Append("_") ;
00397 newName.Append(splitCat->getLabel()) ;
00398
00399
00400 RooAbsArg* specNode = _cloneNodeListAll ? _cloneNodeListAll->find(newName) : _cloneNodeListOwned->find(newName) ;
00401 if (specNode) {
00402
00403
00404 clonedMasterNodes.add(*specNode) ;
00405 if (verbose) {
00406 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName()
00407 << ") Adding existing node specialization " << newName << " to clonedMasterNodes" << endl ;
00408 }
00409
00410
00411 TString nameAttrib("ORIGNAME:") ;
00412 nameAttrib.Append(node->GetName()) ;
00413 specNode->setAttribute(nameAttrib) ;
00414
00415 } else {
00416
00417 if (node->isDerived()) {
00418 coutW(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName()
00419 << "): WARNING: branch node " << node->GetName() << " is split but has no pre-defined specializations" << endl ;
00420 }
00421
00422 TString newTitle(node->GetTitle()) ;
00423 newTitle.Append(" (") ;
00424 newTitle.Append(splitCat->getLabel()) ;
00425 newTitle.Append(")") ;
00426
00427
00428 RooAbsArg* clone = (RooAbsArg*) node->Clone(newName.Data()) ;
00429 clone->SetTitle(newTitle) ;
00430
00431
00432 TString nameAttrib("ORIGNAME:") ;
00433 nameAttrib.Append(node->GetName()) ;
00434 clone->setAttribute(nameAttrib) ;
00435
00436
00437 clonedMasterNodes.add(*clone) ;
00438 if (_owning) {
00439 _cloneNodeListOwned->addOwned(*clone) ;
00440 } else {
00441 _cloneNodeListOwned->add(*clone) ;
00442 }
00443 if (_cloneNodeListAll) {
00444 _cloneNodeListAll->add(*clone) ;
00445 }
00446 }
00447 masterNodesToBeSplit.add(*node) ;
00448 }
00449
00450 RooAbsArg* ReplaceArg = (RooAbsArg*) _replaceArgList.FindObject(node->GetName()) ;
00451 if (ReplaceArg) {
00452 RooAbsArg* substArg = (RooAbsArg*) _replaceSubList.At(_replaceArgList.IndexOf(ReplaceArg)) ;
00453 if (verbose) {
00454 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName()
00455 << "): tree node " << node->GetName() << " will be replaced by " << substArg->GetName() << endl ;
00456 }
00457
00458
00459 TString nameAttrib("ORIGNAME:") ;
00460 nameAttrib.Append(node->GetName()) ;
00461 substArg->setAttribute(nameAttrib) ;
00462
00463
00464 masterNodesToBeReplaced.add(*node) ;
00465 masterReplacementNodes.add(*substArg) ;
00466 }
00467 }
00468 delete nIter ;
00469
00470
00471 RooArgSet masterBranchesToBeCloned("masterBranchesToBeCloned") ;
00472 masterBranchesToBeCloned.setHashTableSize(1000) ;
00473 _masterBranchListIter->Reset() ;
00474 RooAbsArg* branch ;
00475 while((branch=(RooAbsArg*)_masterBranchListIter->Next())) {
00476
00477
00478 if (masterNodesToBeSplit.find(branch->GetName())) {
00479 if (verbose) {
00480 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node " << branch->GetName() << " is already split" << endl ;
00481 }
00482 continue ;
00483 }
00484 if (masterNodesToBeReplaced.find(branch->GetName())) {
00485 if (verbose) {
00486 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node " << branch->GetName() << " is already replaced" << endl ;
00487 }
00488 continue ;
00489 }
00490
00491 if (branch->dependsOn(masterNodesToBeSplit)) {
00492 if (verbose) {
00493 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node "
00494 << branch->IsA()->GetName() << "::" << branch->GetName() << " cloned: depends on a split parameter" << endl ;
00495 }
00496 masterBranchesToBeCloned.add(*branch) ;
00497 } else if (branch->dependsOn(masterNodesToBeReplaced)) {
00498 if (verbose) {
00499 coutI(ObjectHandling) << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node "
00500 << branch->IsA()->GetName() << "::" << branch->GetName() << " cloned: depends on a replaced parameter" << endl ;
00501 }
00502 masterBranchesToBeCloned.add(*branch) ;
00503 }
00504 }
00505
00506
00507 RooAbsArg* cloneTopPdf = 0;
00508 RooArgSet clonedMasterBranches("clonedMasterBranches") ;
00509 clonedMasterBranches.setHashTableSize(1000) ;
00510 TIterator* iter = masterBranchesToBeCloned.createIterator() ;
00511 while((branch=(RooAbsArg*)iter->Next())) {
00512 TString newName(branch->GetName()) ;
00513 newName.Append("_") ;
00514 newName.Append(masterCatState) ;
00515
00516
00517 RooAbsArg* clone = (RooAbsArg*) branch->Clone(newName.Data()) ;
00518 TString nameAttrib("ORIGNAME:") ;
00519 nameAttrib.Append(branch->GetName()) ;
00520 clone->setAttribute(nameAttrib) ;
00521
00522 clonedMasterBranches.add(*clone) ;
00523
00524
00525 if (branch==_masterPdf) cloneTopPdf=(RooAbsArg*)clone ;
00526 }
00527 delete iter ;
00528 if (_owning) {
00529 _cloneBranchList->addOwned(clonedMasterBranches) ;
00530 } else {
00531 _cloneBranchList->add(clonedMasterBranches) ;
00532 }
00533
00534
00535 iter = clonedMasterBranches.createIterator() ;
00536 while((branch=(RooAbsArg*)iter->Next())) {
00537 branch->redirectServers(clonedMasterBranches,kFALSE,kTRUE) ;
00538 branch->redirectServers(clonedMasterNodes,kFALSE,kTRUE) ;
00539 branch->redirectServers(masterReplacementNodes,kFALSE,kTRUE) ;
00540 }
00541 delete iter ;
00542
00543 return cloneTopPdf?cloneTopPdf:_masterPdf ;
00544 }
00545
00546
00547
00548 void RooCustomizer::printName(ostream& os) const
00549 {
00550
00551 os << GetName() ;
00552 }
00553
00554
00555
00556 void RooCustomizer::printTitle(ostream& os) const
00557 {
00558
00559 os << GetTitle() ;
00560 }
00561
00562
00563
00564 void RooCustomizer::printClassName(ostream& os) const
00565 {
00566
00567 os << IsA()->GetName() ;
00568 }
00569
00570
00571
00572 void RooCustomizer::printArgs(ostream& os) const
00573 {
00574
00575 os << "[ masterPdf=" << _masterPdf->GetName() ;
00576 if (_masterCat) {
00577 os << " masterCat=" << _masterCat->GetName() ;
00578 }
00579 os << " ]" ;
00580 }
00581
00582
00583
00584
00585 void RooCustomizer::printMultiline(ostream& os, Int_t , Bool_t , TString indent) const
00586 {
00587
00588
00589 os << indent << "RooCustomizer for " << _masterPdf->GetName() << (_sterile?" (sterile)":"") << endl ;
00590
00591 Int_t i, nsplit = _splitArgList.GetSize() ;
00592 if (nsplit>0) {
00593 os << indent << " Splitting rules:" << endl ;
00594 for (i=0 ; i<nsplit ; i++) {
00595 os << indent << " " << _splitArgList.At(i)->GetName() << " is split by " << _splitCatList.At(i)->GetName() << endl ;
00596 }
00597 }
00598
00599 Int_t nrepl = _replaceArgList.GetSize() ;
00600 if (nrepl>0) {
00601 os << indent << " Replacement rules:" << endl ;
00602 for (i=0 ; i<nrepl ; i++) {
00603 os << indent << " " << _replaceSubList.At(i)->GetName() << " replaces " << _replaceArgList.At(i)->GetName() << endl ;
00604 }
00605 }
00606
00607 return ;
00608 }
00609
00610
00611
00612
00613 void RooCustomizer::setCloneBranchSet(RooArgSet& cloneBranchSet)
00614 {
00615
00616
00617
00618 _cloneBranchList = &cloneBranchSet ;
00619 _cloneBranchList->setHashTableSize(1000) ;
00620 }
00621
00622
00623
00624
00625
00626 std::string RooCustomizer::CustIFace::create(RooFactoryWSTool& ft, const char* typeName, const char* instanceName, std::vector<std::string> args)
00627 {
00628
00629 if (args.size()<2) {
00630 throw string(Form("RooCustomizer::CustIFace::create() ERROR: expect at least 2 arguments for EDIT: the input object and at least one $Replace() rule")) ;
00631 }
00632
00633 if (string(typeName)!="EDIT") {
00634 throw string(Form("RooCustomizer::CustIFace::create() ERROR: unknown type requested: %s",typeName)) ;
00635 }
00636
00637
00638
00639 RooAbsArg* arg = ft.ws().arg(args[0].c_str()) ;
00640 if (!arg) {
00641 throw string(Form("RooCustomizer::CustIFace::create() ERROR: input RooAbsArg %s does not exist",args[0].c_str())) ;
00642 }
00643
00644
00645 RooCustomizer cust(*arg,instanceName) ;
00646
00647 for (unsigned int i=1 ; i<args.size() ; i++) {
00648 char buf[1024] ;
00649 strlcpy(buf,args[i].c_str(),1024) ;
00650 char* sep = strchr(buf,'=') ;
00651 if (!sep) {
00652 throw string(Form("RooCustomizer::CustIFace::create() ERROR: unknown argument: %s, expect form orig=subst",args[i].c_str())) ;
00653 }
00654 *sep = 0 ;
00655 RooAbsArg* orig = ft.ws().arg(buf) ;
00656 RooAbsArg* subst = ft.ws().arg(sep+1) ;
00657 if (!orig) {
00658 throw string(Form("RooCustomizer::CustIFace::create() ERROR: $Replace() input RooAbsArg %s does not exist",buf)) ;
00659 }
00660 if (!subst) {
00661 throw string(Form("RooCustomizer::CustIFace::create() ERROR: $Replace() input RooAbsArg %s does not exist",sep+1)) ;
00662 }
00663 cust.replaceArg(*orig,*subst) ;
00664 }
00665
00666
00667 RooAbsArg* targ = cust.build(kFALSE) ;
00668 if (!targ) {
00669 throw string(Form("RooCustomizer::CustIFace::create() ERROR in customizer build, object %snot created",instanceName)) ;
00670 }
00671
00672
00673 targ->SetName(instanceName) ;
00674
00675
00676 ft.ws().import(*targ,RooFit::Silence()) ;
00677
00678 return string(instanceName) ;
00679 }