#include "RooFit.h"
#include "TClass.h"
#include "TStopwatch.h"
#include "RooAbsCategoryLValue.h" 
#include "RooAbsCategory.h"
#include "RooAbsArg.h"
#include "RooAbsPdf.h"
#include "RooArgSet.h"
#include "RooArgList.h"
#include "RooCustomizer.h"
ClassImp(RooCustomizer) 
;
RooCustomizer::RooCustomizer(const RooAbsArg& pdf, const RooAbsCategoryLValue& masterCat, RooArgSet& splitLeafs) :
  TNamed(pdf.GetName(),pdf.GetTitle()),
  _sterile(kFALSE),
  _masterPdf((RooAbsArg*)&pdf), 
  _masterCat((RooAbsCategoryLValue*)&masterCat), 
  _masterBranchList("masterBranchList"), 
  _masterLeafList("masterLeafList"), 
  _internalCloneBranchList("cloneBranchList"),
  _cloneNodeList(&splitLeafs)
{
  
  _masterBranchList.setHashTableSize(1000) ;
  _masterLeafList.setHashTableSize(1000) ;
  _cloneBranchList = &_internalCloneBranchList ;
  _cloneBranchList->setHashTableSize(1000) ;
  initialize() ;
}
RooCustomizer::RooCustomizer(const RooAbsArg& pdf, const char* name) :
  TNamed(pdf.GetName(),pdf.GetTitle()),
  _sterile(kTRUE), 
  _name(name),
  _masterPdf((RooAbsArg*)&pdf), 
  _masterCat(0), 
  _masterBranchList("masterBranchList"), 
  _masterLeafList("masterLeafList"), 
  _internalCloneBranchList("cloneBranchList"),
  _cloneNodeList(0)
{
  
  
  _masterBranchList.setHashTableSize(1000) ;
  _masterLeafList.setHashTableSize(1000) ;
  _cloneBranchList = &_internalCloneBranchList ;
  _cloneBranchList->setHashTableSize(1000) ;
  initialize() ;
}
void RooCustomizer::initialize() 
{
  
  _masterPdf->leafNodeServerList(&_masterLeafList) ;
  _masterPdf->branchNodeServerList(&_masterBranchList) ;
  _masterLeafListIter = _masterLeafList.createIterator() ;
  _masterBranchListIter = _masterBranchList.createIterator() ;
}
RooCustomizer::~RooCustomizer() 
{
  
  delete _masterLeafListIter ;
  delete _masterBranchListIter ;
}
  
void RooCustomizer::splitArgs(const RooArgSet& set, const RooAbsCategory& splitCat) 
{
  
  
  
  
  if (_sterile) {
    cout << "RooCustomizer::splitArgs(" << _name 
	 << ") ERROR cannot set spitting rules on this sterile customizer" << endl ;
    return ;
  }
  TIterator* iter = set.createIterator() ;
  RooAbsArg* arg ;
  while((arg=(RooAbsArg*)iter->Next())){
    splitArg(*arg,splitCat) ;
  }
  delete iter ;
}
void RooCustomizer::splitArg(const RooAbsArg& arg, const RooAbsCategory& splitCat) 
{
  
  
  
  
  if (_splitArgList.FindObject(arg.GetName())) {
    cout << "RooCustomizer(" << GetName() << ") ERROR: multiple splitting rules defined for " 
	 << arg.GetName() << " only using first rule" << endl ;
    return ;
  }
  if (_sterile) {
    cout << "RooCustomizer::splitArg(" << _name 
	 << ") ERROR cannot set spitting rules on this sterile customizer" << endl ;
    return ;
  }
  _splitArgList.Add((RooAbsArg*)&arg) ;
  _splitCatList.Add((RooAbsCategory*)&splitCat) ;
}
void RooCustomizer::replaceArg(const RooAbsArg& orig, const RooAbsArg& subst) 
{
  
  if (_replaceArgList.FindObject(orig.GetName())) {
    cout << "RooCustomizer(" << GetName() << ") ERROR: multiple replacement rules defined for " 
	 << orig.GetName() << " only using first rule" << endl ;
    return ;
  }
  _replaceArgList.Add((RooAbsArg*)&orig) ;
  _replaceSubList.Add((RooAbsArg*)&subst) ;
}
RooAbsArg* RooCustomizer::build(Bool_t verbose) 
{
  
  
  
  return doBuild(_name,verbose) ;
}
RooAbsArg* RooCustomizer::build(const char* masterCatState, Bool_t verbose) 
{
  
  
  
  
  
  if (_sterile) {
    cout << "RooCustomizer::build(" << _name 
	 << ") ERROR cannot use leaf spitting build() on this sterile customizer" << endl ;
    return 0 ;
  }
  
  if (_masterCat->setLabel(masterCatState)) {
    cout << "RooCustomizer::build(" << _masterPdf->GetName() << "): ERROR label '" << masterCatState 
	 << "' not defined for master splitting category " << _masterCat->GetName() << endl ;
    return 0 ;
  }
  return doBuild(masterCatState,verbose) ;
}
RooAbsArg* RooCustomizer::doBuild(const char* masterCatState, Bool_t verbose) 
{
  
  TStopwatch t1 ;
  t1.Start() ;
  
  RooArgSet masterNodesToBeSplit("masterNodesToBeSplit") ;
  RooArgSet masterNodesToBeReplaced("masterNodesToBeReplaced") ;
  RooArgSet masterReplacementNodes("masterReplacementNodes") ;
  RooArgSet clonedMasterNodes("clonedMasterNodes") ;
  masterNodesToBeSplit.setHashTableSize(1000) ;
  masterNodesToBeReplaced.setHashTableSize(1000) ;
  masterReplacementNodes.setHashTableSize(1000) ;
  clonedMasterNodes.setHashTableSize(1000) ;
  _masterLeafListIter->Reset() ;
  RooAbsArg* node ;
  RooArgSet nodeList(_masterLeafList) ;
  nodeList.setHashTableSize(1000) ;
  nodeList.add(_masterBranchList) ;
  TIterator* nIter = nodeList.createIterator() ;
  while((node=(RooAbsArg*)nIter->Next())) {
    RooAbsArg* splitArg = !_sterile?(RooAbsArg*) _splitArgList.FindObject(node->GetName()):0 ;
    if (splitArg) {
      RooAbsCategory* splitCat = (RooAbsCategory*) _splitCatList.At(_splitArgList.IndexOf(splitArg)) ;
      if (verbose) {
	cout << "RooCustomizer::build(" << _masterPdf->GetName() 
	     << "): tree node " << node->GetName() << " is split by category " << splitCat->GetName() << endl ;
      }
      
      TString newName(node->GetName()) ;
      newName.Append("_") ;
      newName.Append(splitCat->getLabel()) ;	
      
      RooAbsArg* specNode = _cloneNodeList->find(newName) ;
      if (specNode) {
	
	clonedMasterNodes.add(*specNode) ;
	if (verbose) {
	  cout << "RooCustomizer::build(" << _masterPdf->GetName() 
	       << ") Adding existing node specialization " << newName << " to clonedMasterNodes" << endl ;
	}
	
	TString nameAttrib("ORIGNAME:") ;
	nameAttrib.Append(node->GetName()) ;
	specNode->setAttribute(nameAttrib) ;
      } else {
	if (node->isDerived()) {
	  cout << "RooCustomizer::build(" << _masterPdf->GetName() 
	       << "): WARNING: branch node " << node->GetName() << " is split but has no pre-defined specializations" << endl ;
	}
	TString newTitle(node->GetTitle()) ;
	newTitle.Append(" (") ;
	newTitle.Append(splitCat->getLabel()) ;
	newTitle.Append(")") ;
      
	
	RooAbsArg* clone = (RooAbsArg*) node->Clone(newName.Data()) ;
	clone->SetTitle(newTitle) ;
	
	TString nameAttrib("ORIGNAME:") ;
	nameAttrib.Append(node->GetName()) ;
	clone->setAttribute(nameAttrib) ;
	
	clonedMasterNodes.add(*clone) ;
	_cloneNodeList->addOwned(*clone) ;	
      }
      masterNodesToBeSplit.add(*node) ;     
    }
    RooAbsArg* replaceArg = (RooAbsArg*) _replaceArgList.FindObject(node->GetName()) ;
    if (replaceArg) {
      RooAbsArg* substArg = (RooAbsArg*) _replaceSubList.At(_replaceArgList.IndexOf(replaceArg)) ;
      if (verbose) {
	cout << "RooCustomizer::build(" << _masterPdf->GetName() 
	     << "): tree node " << node->GetName() << " will be replaced by " << substArg->GetName() << endl ;
      }
      
      TString nameAttrib("ORIGNAME:") ;
      nameAttrib.Append(node->GetName()) ;
      substArg->setAttribute(nameAttrib) ;
      
      masterNodesToBeReplaced.add(*node) ;
      masterReplacementNodes.add(*substArg) ;
    }
  }
  delete nIter ;
  if (!_sterile) _cloneNodeList->addOwned(clonedMasterNodes) ;
  
  RooArgSet masterBranchesToBeCloned("masterBranchesToBeCloned") ;
  masterBranchesToBeCloned.setHashTableSize(1000) ;
  _masterBranchListIter->Reset() ;
  RooAbsArg* branch ;
  while((branch=(RooAbsArg*)_masterBranchListIter->Next())) {
    
    
    if (masterNodesToBeSplit.find(branch->GetName())) {
      if (verbose) {
	cout << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node " << branch->GetName() << " is already split" << endl ;
      }
      continue ;
    }
    if (masterNodesToBeReplaced.find(branch->GetName())) {
      if (verbose) {
	cout << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node " << branch->GetName() << " is already replaced" << endl ;
      }
      continue ;
    }
    if (branch->dependsOn(masterNodesToBeSplit)) {
      if (verbose) {
	cout << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node " 
	     << branch->IsA()->GetName() << "::" << branch->GetName() << " cloned: depends on a split parameter" << endl ;
      }
      masterBranchesToBeCloned.add(*branch) ;
    } else if (branch->dependsOn(masterNodesToBeReplaced)) {
      if (verbose) {
	cout << "RooCustomizer::build(" << _masterPdf->GetName() << ") Branch node " 
	     << branch->IsA()->GetName() << "::" << branch->GetName() << " cloned: depends on a replaced parameter" << endl ;
      }
      masterBranchesToBeCloned.add(*branch) ;
    }
  }
  
  RooAbsArg* cloneTopPdf = 0;
  RooArgSet clonedMasterBranches("clonedMasterBranches") ;
  clonedMasterBranches.setHashTableSize(1000) ;
  TIterator* iter = masterBranchesToBeCloned.createIterator() ;
  while((branch=(RooAbsArg*)iter->Next())) {
    TString newName(branch->GetName()) ;
    newName.Append("_") ;
    newName.Append(masterCatState) ;
    
    RooAbsArg* clone = (RooAbsArg*) branch->Clone(newName.Data()) ;
    TString nameAttrib("ORIGNAME:") ;
    nameAttrib.Append(branch->GetName()) ;
    clone->setAttribute(nameAttrib) ;
    clonedMasterBranches.add(*clone) ;      
    
    if (branch==_masterPdf) cloneTopPdf=(RooAbsArg*)clone ;
  }
  delete iter ;
  _cloneBranchList->addOwned(clonedMasterBranches) ;
  
  iter = clonedMasterBranches.createIterator() ;
  while((branch=(RooAbsArg*)iter->Next())) {
    branch->redirectServers(clonedMasterBranches,kFALSE,kTRUE) ;
    branch->redirectServers(clonedMasterNodes,kFALSE,kTRUE) ;
    branch->redirectServers(masterReplacementNodes,kFALSE,kTRUE) ;
  }
  delete iter ;  
  return cloneTopPdf?cloneTopPdf:_masterPdf ;
}
void RooCustomizer::printToStream(ostream& os, PrintOption , TString indent) const
{
  os << indent << "RooCustomizer for " << _masterPdf->GetName() << (_sterile?" (sterile)":"") << endl ;
  Int_t i, nsplit = _splitArgList.GetSize() ;
  if (nsplit>0) {
    os << indent << "  Splitting rules:" << endl ;
    for (i=0 ; i<nsplit ; i++) {
      os << indent << "   " << _splitArgList.At(i)->GetName() << " is split by " << _splitCatList.At(i)->GetName() << endl ;
    }
  }
  Int_t nrepl = _replaceArgList.GetSize() ;
  if (nrepl>0) {
    os << indent << "  Replacement rules:" << endl ;
    for (i=0 ; i<nrepl ; i++) {
      os << indent << "   " << _replaceSubList.At(i)->GetName() << " replaces " << _replaceArgList.At(i)->GetName() << endl ;
    }
  }
  
  return ;
}
void RooCustomizer::setCloneBranchSet(RooArgSet& cloneBranchSet) 
{
  _cloneBranchList = &cloneBranchSet ;
  _cloneBranchList->setHashTableSize(1000) ;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.