// RooAbsArg is the common abstract base class for objects that
// represent a value (of arbitrary type) and "shape" that in general
// depends on (is a client of) other RooAbsArg subclasses. The only
// state information about a value that is maintained in this base
// class consists of named attributes and flags that track when either
// the value or the shape of this object changes. The meaning of shape
// depends on the client implementation but could be, for example, the
// allowed range of a value. The base class is also responsible for
// managing client/server links and propagating value/shape changes
// through an expression tree. RooAbsArg implements public interfaces
// for inspecting client/server relationships and
// setting/clearing/testing named attributes.
// END_HTML
#include "RooFit.h"
#include "Riostream.h"
#include "TClass.h"
#include "TObjString.h"
#include "TVirtualStreamerInfo.h"
#include "RooSecondMoment.h"
#include "RooMsgService.h"
#include "RooAbsArg.h"
#include "RooArgSet.h"
#include "RooArgProxy.h"
#include "RooSetProxy.h"
#include "RooListProxy.h"
#include "RooAbsData.h"
#include "RooAbsCategoryLValue.h"
#include "RooAbsRealLValue.h"
#include "RooTrace.h"
#include "RooStringVar.h"
#include "RooRealIntegral.h"
#include "RooConstVar.h"
#include "RooMsgService.h"
#include "RooExpensiveObjectCache.h"
#include "RooAbsDataStore.h"
#include "RooResolutionModel.h"
#include "RooVectorDataStore.h"
#include "RooTreeDataStore.h"
#include <string.h>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <sstream>
using namespace std ;
#if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
char* operator+( streampos&, char* );
#endif
ClassImp(RooAbsArg)
;
Bool_t RooAbsArg::_verboseDirty(kFALSE) ;
Bool_t RooAbsArg::_inhibitDirty(kFALSE) ;
Bool_t RooAbsArg::inhibitDirty() const { return _inhibitDirty && !_localNoInhibitDirty; }
std::map<RooAbsArg*,TRefArray*> RooAbsArg::_ioEvoList ;
std::stack<RooAbsArg*> RooAbsArg::_ioReadStack ;
RooAbsArg::RooAbsArg() :
TNamed(),
_deleteWatch(kFALSE),
_operMode(Auto),
_fast(kFALSE),
_ownedComponents(0),
_prohibitServerRedirect(kFALSE),
_eocache(0),
_namePtr(0),
_isConstant(kFALSE),
_localNoInhibitDirty(kFALSE)
{
_clientShapeIter = _clientListShape.MakeIterator() ;
_clientValueIter = _clientListValue.MakeIterator() ;
_namePtr = (TNamed*) RooNameReg::instance().constPtr(GetName()) ;
}
RooAbsArg::RooAbsArg(const char *name, const char *title) :
TNamed(name,title),
_deleteWatch(kFALSE),
_valueDirty(kTRUE),
_shapeDirty(kTRUE),
_operMode(Auto),
_fast(kFALSE),
_ownedComponents(0),
_prohibitServerRedirect(kFALSE),
_eocache(0),
_namePtr(0),
_isConstant(kFALSE),
_localNoInhibitDirty(kFALSE)
{
_namePtr = (TNamed*) RooNameReg::instance().constPtr(GetName()) ;
_clientShapeIter = _clientListShape.MakeIterator() ;
_clientValueIter = _clientListValue.MakeIterator() ;
}
RooAbsArg::RooAbsArg(const RooAbsArg& other, const char* name)
: TNamed(other.GetName(),other.GetTitle()),
RooPrintable(other),
_boolAttrib(other._boolAttrib),
_stringAttrib(other._stringAttrib),
_deleteWatch(other._deleteWatch),
_operMode(Auto),
_fast(kFALSE),
_ownedComponents(0),
_prohibitServerRedirect(kFALSE),
_eocache(other._eocache),
_namePtr(other._namePtr),
_isConstant(other._isConstant),
_localNoInhibitDirty(other._localNoInhibitDirty)
{
if (name) {
TNamed::SetName(name) ;
_namePtr = (TNamed*) RooNameReg::instance().constPtr(name) ;
} else {
TNamed::SetName(other.GetName()) ;
_namePtr = other._namePtr ;
}
RooFIter sIter = other._serverList.fwdIterator() ;
RooAbsArg* server ;
Bool_t valueProp, shapeProp ;
while ((server = sIter.next())) {
valueProp = server->_clientListValue.findArg(&other)?kTRUE:kFALSE ;
shapeProp = server->_clientListShape.findArg(&other)?kTRUE:kFALSE ;
addServer(*server,valueProp,shapeProp) ;
}
_clientShapeIter = _clientListShape.MakeIterator() ;
_clientValueIter = _clientListValue.MakeIterator() ;
setValueDirty() ;
setShapeDirty() ;
}
RooAbsArg::~RooAbsArg()
{
RooFIter serverIter = _serverList.fwdIterator() ;
RooAbsArg* server ;
while ((server=serverIter.next())) {
removeServer(*server,kTRUE) ;
}
RooFIter clientIter = _clientList.fwdIterator() ;
RooAbsArg* client = 0;
Bool_t first(kTRUE) ;
while ((client=clientIter.next())) {
client->setAttribute("ServerDied") ;
TString attr("ServerDied:");
attr.Append(GetName());
attr.Append(Form("(%lx)",(ULong_t)this)) ;
client->setAttribute(attr.Data());
client->removeServer(*this,kTRUE);
if (_verboseDirty) {
if (first) {
cxcoutD(Tracing) << "RooAbsArg::dtor(" << GetName() << "," << this << ") DeleteWatch: object is being destroyed" << endl ;
first = kFALSE ;
}
cxcoutD(Tracing) << fName << "::" << ClassName() << ":~RooAbsArg: dependent \""
<< client->GetName() << "\" should have been deleted first" << endl ;
}
}
delete _clientShapeIter ;
delete _clientValueIter ;
if (_ownedComponents) {
delete _ownedComponents ;
_ownedComponents = 0 ;
}
}
void RooAbsArg::setDirtyInhibit(Bool_t flag)
{
_inhibitDirty = flag ;
}
void RooAbsArg::verboseDirty(Bool_t flag)
{
_verboseDirty = flag ;
}
Bool_t RooAbsArg::isCloneOf(const RooAbsArg& other) const
{
return (getAttribute(Form("CloneOf(%lx)",(ULong_t)&other)) ||
other.getAttribute(Form("CloneOf(%lx)",(ULong_t)this))) ;
}
void RooAbsArg::setAttribute(const Text_t* name, Bool_t value)
{
if(string("Constant")==name) {
_isConstant = value ;
}
if (value) {
_boolAttrib.insert(name) ;
} else {
set<string>::iterator iter = _boolAttrib.find(name) ;
if (iter != _boolAttrib.end()) {
_boolAttrib.erase(iter) ;
}
}
}
Bool_t RooAbsArg::getAttribute(const Text_t* name) const
{
return (_boolAttrib.find(name) != _boolAttrib.end()) ;
}
void RooAbsArg::setStringAttribute(const Text_t* key, const Text_t* value)
{
if (value) {
_stringAttrib[key] = value ;
} else {
if (_stringAttrib.find(key)!=_stringAttrib.end()) {
_stringAttrib.erase(key) ;
}
}
}
const Text_t* RooAbsArg::getStringAttribute(const Text_t* key) const
{
map<string,string>::const_iterator iter = _stringAttrib.find(key) ;
if (iter!=_stringAttrib.end()) {
return iter->second.c_str() ;
} else {
return 0 ;
}
}
void RooAbsArg::setTransientAttribute(const Text_t* name, Bool_t value)
{
if (value) {
_boolAttribTransient.insert(name) ;
} else {
set<string>::iterator iter = _boolAttribTransient.find(name) ;
if (iter != _boolAttribTransient.end()) {
_boolAttribTransient.erase(iter) ;
}
}
}
Bool_t RooAbsArg::getTransientAttribute(const Text_t* name) const
{
return (_boolAttribTransient.find(name) != _boolAttribTransient.end()) ;
}
void RooAbsArg::addServer(RooAbsArg& server, Bool_t valueProp, Bool_t shapeProp)
{
if (_prohibitServerRedirect) {
cxcoutF(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName()
<< "): PROHIBITED SERVER ADDITION REQUESTED: adding server " << server.GetName()
<< "(" << &server << ") for " << (valueProp?"value ":"") << (shapeProp?"shape":"") << endl ;
assert(0) ;
}
cxcoutD(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName() << "): adding server " << server.GetName()
<< "(" << &server << ") for " << (valueProp?"value ":"") << (shapeProp?"shape":"") << endl ;
if (server.operMode()==ADirty && operMode()!=ADirty && valueProp) {
setOperMode(ADirty) ;
}
if (_serverList.GetSize() > 999 && _serverList.getHashTableSize() == 0) _serverList.setHashTableSize(1000);
if (server._clientList.GetSize() > 999 && server._clientList.getHashTableSize() == 0) server._clientList.setHashTableSize(1000);
if (server._clientListValue.GetSize() > 999 && server._clientListValue.getHashTableSize() == 0) server._clientListValue.setHashTableSize(1000);
_serverList.Add(&server) ;
server._clientList.Add(this) ;
if (valueProp) server._clientListValue.Add(this) ;
if (shapeProp) server._clientListShape.Add(this) ;
}
void RooAbsArg::addServerList(RooAbsCollection& serverList, Bool_t valueProp, Bool_t shapeProp)
{
RooAbsArg* arg ;
RooFIter iter = serverList.fwdIterator() ;
while ((arg=iter.next())) {
addServer(*arg,valueProp,shapeProp) ;
}
}
void RooAbsArg::removeServer(RooAbsArg& server, Bool_t force)
{
if (_prohibitServerRedirect) {
cxcoutF(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName() << "): PROHIBITED SERVER REMOVAL REQUESTED: removing server "
<< server.GetName() << "(" << &server << ")" << endl ;
assert(0) ;
}
if (_verboseDirty) {
cxcoutD(LinkStateMgmt) << "RooAbsArg::removeServer(" << GetName() << "): removing server "
<< server.GetName() << "(" << &server << ")" << endl ;
}
if (!force) {
_serverList.Remove(&server) ;
server._clientList.Remove(this) ;
server._clientListValue.Remove(this) ;
server._clientListShape.Remove(this) ;
} else {
_serverList.RemoveAll(&server) ;
server._clientList.RemoveAll(this) ;
server._clientListValue.RemoveAll(this) ;
server._clientListShape.RemoveAll(this) ;
}
}
void RooAbsArg::replaceServer(RooAbsArg& oldServer, RooAbsArg& newServer, Bool_t propValue, Bool_t propShape)
{
Int_t count = _serverList.refCount(&oldServer) ;
removeServer(oldServer,kTRUE) ;
while(count--) {
addServer(newServer,propValue,propShape) ;
}
}
void RooAbsArg::changeServer(RooAbsArg& server, Bool_t valueProp, Bool_t shapeProp)
{
if (!_serverList.findArg(&server)) {
coutE(LinkStateMgmt) << "RooAbsArg::changeServer(" << GetName() << "): Server "
<< server.GetName() << " not registered" << endl ;
return ;
}
if (!server._clientList.findArg(this)) {
coutE(LinkStateMgmt) << "RooAbsArg::changeServer(" << GetName() << "): Server "
<< server.GetName() << " doesn't have us registered as client" << endl ;
return ;
}
Int_t vcount = server._clientListValue.refCount(this) ;
Int_t scount = server._clientListShape.refCount(this) ;
server._clientListValue.RemoveAll(this) ;
server._clientListShape.RemoveAll(this) ;
if (valueProp) {
while (vcount--) server._clientListValue.Add(this) ;
}
if (shapeProp) {
while(scount--) server._clientListShape.Add(this) ;
}
}
void RooAbsArg::leafNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t recurseNonDerived) const
{
treeNodeServerList(list,arg,kFALSE,kTRUE,kFALSE,recurseNonDerived) ;
}
void RooAbsArg::branchNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t recurseNonDerived) const
{
treeNodeServerList(list,arg,kTRUE,kFALSE,kFALSE,recurseNonDerived) ;
}
void RooAbsArg::treeNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t doBranch, Bool_t doLeaf, Bool_t valueOnly, Bool_t recurseFundamental) const
{
if (!arg) {
arg=this ;
}
if ((doBranch&&doLeaf) ||
(doBranch&&arg->isDerived()) ||
(doLeaf&&arg->isFundamental()&&(!(recurseFundamental&&arg->isDerived()))) ||
(doLeaf && !arg->isFundamental() && !arg->isDerived())) {
list->add(*arg,kTRUE) ;
}
if (arg->isDerived() && (!arg->isFundamental() || recurseFundamental)) {
RooAbsArg* server ;
RooFIter sIter = arg->serverMIterator() ;
while ((server=sIter.next())) {
Bool_t isValueSrv = server->_clientListValue.findArg(arg)?kTRUE:kFALSE ;
if (valueOnly && !isValueSrv) {
continue ;
}
treeNodeServerList(list,server,doBranch,doLeaf,valueOnly,recurseFundamental) ;
}
}
}
RooArgSet* RooAbsArg::getParameters(const RooAbsData* set, Bool_t stripDisconnected) const
{
return getParameters(set?set->get():0,stripDisconnected) ;
}
void RooAbsArg::addParameters(RooArgSet& params, const RooArgSet* nset,Bool_t stripDisconnected) const
{
RooFIter siter = serverMIterator() ;
RooAbsArg* server ;
RooArgSet nodeParamServers ;
RooArgSet nodeBranchServers ;
while((server=siter.next())) {
if (server->isValueServer(*this)) {
if (server->isFundamental()) {
if (!nset || !server->dependsOn(*nset)) {
nodeParamServers.add(*server) ;
}
} else {
nodeBranchServers.add(*server) ;
}
}
}
getParametersHook(nset,&nodeParamServers,stripDisconnected) ;
params.add(nodeParamServers,kTRUE) ;
RooFIter biter = nodeBranchServers.fwdIterator() ;
while((server=biter.next())) {
server->addParameters(params,nset) ;
}
}
RooArgSet* RooAbsArg::getParameters(const RooArgSet* nset, Bool_t stripDisconnected) const
{
RooArgSet* parList = new RooArgSet("parameters");
addParameters(*parList, nset, stripDisconnected);
parList->sort();
return parList;
}
RooArgSet* RooAbsArg::getObservables(const RooAbsData* set) const
{
if (!set) return new RooArgSet ;
return getObservables(set->get()) ;
}
RooArgSet* RooAbsArg::getObservables(const RooArgSet* dataList, Bool_t valueOnly) const
{
RooArgSet* depList = new RooArgSet("dependents") ;
if (!dataList) return depList ;
RooArgSet leafList("leafNodeServerList") ;
treeNodeServerList(&leafList,0,kFALSE,kTRUE,valueOnly) ;
RooFIter sIter = leafList.fwdIterator() ;
RooAbsArg* arg ;
if (valueOnly) {
while ((arg=sIter.next())) {
if (arg->dependsOnValue(*dataList) && arg->isLValue()) {
depList->add(*arg) ;
}
}
} else {
while ((arg=sIter.next())) {
if (arg->dependsOn(*dataList) && arg->isLValue()) {
depList->add(*arg) ;
}
}
}
return depList ;
}
RooArgSet* RooAbsArg::getComponents() const
{
TString name(GetName()) ;
name.Append("_components") ;
RooArgSet* set = new RooArgSet(name) ;
branchNodeServerList(set) ;
return set ;
}
Bool_t RooAbsArg::checkObservables(const RooArgSet*) const
{
return kFALSE ;
}
Bool_t RooAbsArg::recursiveCheckObservables(const RooArgSet* nset) const
{
RooArgSet nodeList ;
treeNodeServerList(&nodeList) ;
RooFIter iter = nodeList.fwdIterator() ;
RooAbsArg* arg ;
Bool_t ret(kFALSE) ;
while((arg=iter.next())) {
if (arg->getAttribute("ServerDied")) {
coutE(LinkStateMgmt) << "RooAbsArg::recursiveCheckObservables(" << GetName() << "): ERROR: one or more servers of node "
<< arg->GetName() << " no longer exists!" << endl ;
arg->Print("v") ;
ret = kTRUE ;
}
ret |= arg->checkObservables(nset) ;
}
return ret ;
}
Bool_t RooAbsArg::dependsOn(const RooAbsCollection& serverList, const RooAbsArg* ignoreArg, Bool_t valueOnly) const
{
RooFIter sIter = serverList.fwdIterator();
RooAbsArg* server ;
while ((server=sIter.next())) {
if (dependsOn(*server,ignoreArg,valueOnly)) {
return kTRUE;
}
}
return kFALSE;
}
Bool_t RooAbsArg::dependsOn(const RooAbsArg& testArg, const RooAbsArg* ignoreArg, Bool_t valueOnly) const
{
if (this==ignoreArg) return kFALSE ;
if (testArg.namePtr()==namePtr()) return kTRUE ;
RooAbsArg* server = findServer(testArg) ;
if (server!=0) {
if ( !valueOnly || server->isValueServer(*this)) {
return kTRUE ;
}
}
RooFIter sIter = serverMIterator() ;
while ((server=sIter.next())) {
if ( !valueOnly || server->isValueServer(*this)) {
if (server->dependsOn(testArg,ignoreArg,valueOnly)) {
return kTRUE ;
}
}
}
return kFALSE ;
}
Bool_t RooAbsArg::overlaps(const RooAbsArg& testArg, Bool_t valueOnly) const
{
RooArgSet list("treeNodeList") ;
treeNodeServerList(&list) ;
return valueOnly ? testArg.dependsOnValue(list) : testArg.dependsOn(list) ;
}
Bool_t RooAbsArg::observableOverlaps(const RooAbsData* dset, const RooAbsArg& testArg) const
{
return observableOverlaps(dset->get(),testArg) ;
}
Bool_t RooAbsArg::observableOverlaps(const RooArgSet* nset, const RooAbsArg& testArg) const
{
RooArgSet* depList = getObservables(nset) ;
Bool_t ret = testArg.dependsOn(*depList) ;
delete depList ;
return ret ;
}
void RooAbsArg::setValueDirty(const RooAbsArg* source) const
{
if (_operMode!=Auto || _inhibitDirty) return ;
if (_clientListValue.GetSize()==0) {
_valueDirty = kTRUE ;
return ;
}
if (source==0) {
source=this ;
} else if (source==this) {
coutE(LinkStateMgmt) << "RooAbsArg::setValueDirty(" << GetName()
<< "): cyclical dependency detected, source = " << source->GetName() << endl ;
return ;
}
if (_verboseDirty) {
cxcoutD(LinkStateMgmt) << "RooAbsArg::setValueDirty(" << (source?source->GetName():"self") << "->" << GetName() << "," << this
<< "): dirty flag " << (_valueDirty?"already ":"") << "raised" << endl ;
}
_valueDirty = kTRUE ;
RooFIter clientValueIter = _clientListValue.fwdIterator() ;
RooAbsArg* client ;
while ((client=clientValueIter.next())) {
client->setValueDirty(source) ;
}
}
void RooAbsArg::setShapeDirty(const RooAbsArg* source) const
{
if (_verboseDirty) {
cxcoutD(LinkStateMgmt) << "RooAbsArg::setShapeDirty(" << GetName()
<< "): dirty flag " << (_shapeDirty?"already ":"") << "raised" << endl ;
}
if (_clientListShape.GetSize()==0) {
_shapeDirty = kTRUE ;
return ;
}
if (source==0) {
source=this ;
} else if (source==this) {
coutE(LinkStateMgmt) << "RooAbsArg::setShapeDirty(" << GetName()
<< "): cyclical dependency detected" << endl ;
return ;
}
_shapeDirty=kTRUE ;
RooFIter clientShapeIter = _clientListShape.fwdIterator() ;
RooAbsArg* client ;
while ((client=clientShapeIter.next())) {
client->setShapeDirty(source) ;
client->setValueDirty(source) ;
}
}
Bool_t RooAbsArg::redirectServers(const RooAbsCollection& newSetOrig, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursionStep)
{
if (!_serverList.First()) return kFALSE ;
if (newSetOrig.getSize()==0) return kFALSE ;
RooAbsCollection* newSet ;
if (nameChange) {
newSet = new RooArgSet ;
RooFIter iter = newSetOrig.fwdIterator() ;
RooAbsArg* arg ;
while((arg=iter.next())) {
if (string("REMOVAL_DUMMY")==arg->GetName()) {
if (arg->getAttribute("REMOVE_ALL")) {
newSet->add(*arg) ;
} else if (arg->getAttribute(Form("REMOVE_FROM_%s",getStringAttribute("ORIGNAME")))) {
newSet->add(*arg) ;
}
} else {
newSet->add(*arg) ;
}
}
} else {
newSet = (RooAbsCollection*) &newSetOrig ;
}
Bool_t ret(kFALSE) ;
RooLinkedList origServerList, origServerValue, origServerShape ;
RooAbsArg *oldServer, *newServer ;
RooFIter sIter = _serverList.fwdIterator() ;
while ((oldServer=sIter.next())) {
origServerList.Add(oldServer) ;
if (oldServer->_clientListValue.findArg(this)) {
origServerValue.Add(oldServer) ;
}
if (oldServer->_clientListShape.findArg(this)) {
origServerShape.Add(oldServer) ;
}
}
sIter = origServerList.fwdIterator() ;
Bool_t propValue, propShape ;
while ((oldServer=sIter.next())) {
newServer= oldServer->findNewServer(*newSet, nameChange);
if (newServer && _verboseDirty) {
cxcoutD(LinkStateMgmt) << "RooAbsArg::redirectServers(" << (void*)this << "," << GetName() << "): server " << oldServer->GetName()
<< " redirected from " << oldServer << " to " << newServer << endl ;
}
if (!newServer) {
if (mustReplaceAll) {
cxcoutD(LinkStateMgmt) << "RooAbsArg::redirectServers(" << (void*)this << "," << GetName() << "): server " << oldServer->GetName()
<< " (" << (void*)oldServer << ") not redirected" << (nameChange?"[nameChange]":"") << endl ;
ret = kTRUE ;
}
continue ;
}
propValue=origServerValue.findArg(oldServer)?kTRUE:kFALSE ;
propShape=origServerShape.findArg(oldServer)?kTRUE:kFALSE ;
if (newServer != this) {
replaceServer(*oldServer,*newServer,propValue,propShape) ;
}
}
setValueDirty() ;
setShapeDirty() ;
Bool_t allReplaced=kTRUE ;
for (int i=0 ; i<numProxies() ; i++) {
RooAbsProxy* p = getProxy(i) ;
if (!p) continue ;
Bool_t ret2 = p->changePointer(*newSet,nameChange,kFALSE) ;
allReplaced &= ret2 ;
}
if (mustReplaceAll && !allReplaced) {
coutE(LinkStateMgmt) << "RooAbsArg::redirectServers(" << GetName()
<< "): ERROR, some proxies could not be adjusted" << endl ;
ret = kTRUE ;
}
for (Int_t i=0 ;i<numCaches() ; i++) {
ret |= getCache(i)->redirectServersHook(*newSet,mustReplaceAll,nameChange,isRecursionStep) ;
}
ret |= redirectServersHook(*newSet,mustReplaceAll,nameChange,isRecursionStep) ;
if (nameChange) {
delete newSet ;
}
return ret ;
}
RooAbsArg *RooAbsArg::findNewServer(const RooAbsCollection &newSet, Bool_t nameChange) const
{
RooAbsArg *newServer = 0;
if (!nameChange) {
newServer = newSet.find(*this) ;
}
else {
TString nameAttrib("ORIGNAME:") ;
nameAttrib.Append(GetName()) ;
RooArgSet* tmp = (RooArgSet*) newSet.selectByAttrib(nameAttrib,kTRUE) ;
if(0 != tmp) {
if (tmp->getSize()==0) {
delete tmp ;
return 0 ;
}
if(tmp->getSize()>1) {
coutF(LinkStateMgmt) << "RooAbsArg::redirectServers(" << GetName() << "): FATAL Error, " << tmp->getSize() << " servers with "
<< nameAttrib << " attribute" << endl ;
tmp->Print("v") ;
assert(0) ;
}
newServer= tmp->first();
delete tmp ;
}
}
return newServer;
}
Bool_t RooAbsArg::recursiveRedirectServers(const RooAbsCollection& newSet, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t recurseInNewSet)
{
static std::set<const RooAbsArg*> callStack;
{
std::set<const RooAbsArg*>::iterator it = callStack.lower_bound(this);
if (it != callStack.end() && this == *it) {
return kFALSE;
} else {
callStack.insert(it, this);
}
}
Bool_t ret(kFALSE) ;
cxcoutD(LinkStateMgmt) << "RooAbsArg::recursiveRedirectServers(" << this << "," << GetName() << ") newSet = " << newSet << " mustReplaceAll = "
<< (mustReplaceAll?"T":"F") << " nameChange = " << (nameChange?"T":"F") << " recurseInNewSet = " << (recurseInNewSet?"T":"F") << endl ;
ret |= redirectServers(newSet,mustReplaceAll,nameChange,kTRUE) ;
RooFIter sIter = serverMIterator() ;
RooAbsArg* server ;
while((server=sIter.next())) {
ret |= server->recursiveRedirectServers(newSet,mustReplaceAll,nameChange,recurseInNewSet) ;
}
callStack.erase(this);
return ret ;
}
void RooAbsArg::registerProxy(RooArgProxy& proxy)
{
if (_proxyList.FindObject(&proxy)) {
coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
<< proxy.GetName() << " for arg " << proxy.absArg()->GetName()
<< " already registered" << endl ;
return ;
}
if (proxy.absArg()) {
addServer(*proxy.absArg(),proxy.isValueServer(),proxy.isShapeServer()) ;
}
_proxyList.Add(&proxy) ;
}
void RooAbsArg::unRegisterProxy(RooArgProxy& proxy)
{
_proxyList.Remove(&proxy) ;
_proxyList.Compress() ;
}
void RooAbsArg::registerProxy(RooSetProxy& proxy)
{
if (_proxyList.FindObject(&proxy)) {
coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
<< proxy.GetName() << " already registered" << endl ;
return ;
}
_proxyList.Add(&proxy) ;
}
void RooAbsArg::unRegisterProxy(RooSetProxy& proxy)
{
_proxyList.Remove(&proxy) ;
_proxyList.Compress() ;
}
void RooAbsArg::registerProxy(RooListProxy& proxy)
{
if (_proxyList.FindObject(&proxy)) {
coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
<< proxy.GetName() << " already registered" << endl ;
return ;
}
Int_t nProxyOld = _proxyList.GetEntries() ;
_proxyList.Add(&proxy) ;
if (_proxyList.GetEntries()!=nProxyOld+1) {
cout << "RooAbsArg::registerProxy(" << GetName() << ") proxy registration failure! nold=" << nProxyOld << " nnew=" << _proxyList.GetEntries() << endl ;
}
}
void RooAbsArg::unRegisterProxy(RooListProxy& proxy)
{
_proxyList.Remove(&proxy) ;
_proxyList.Compress() ;
}
RooAbsProxy* RooAbsArg::getProxy(Int_t index) const
{
return dynamic_cast<RooAbsProxy*> (_proxyList.At(index)) ;
}
Int_t RooAbsArg::numProxies() const
{
return _proxyList.GetEntries() ;
}
void RooAbsArg::setProxyNormSet(const RooArgSet* nset)
{
for (int i=0 ; i<numProxies() ; i++) {
RooAbsProxy* p = getProxy(i) ;
if (!p) continue ;
getProxy(i)->changeNormSet(nset) ;
}
}
void RooAbsArg::attachToTree(TTree& ,Int_t)
{
coutE(Contents) << "RooAbsArg::attachToTree(" << GetName()
<< "): Cannot be attached to a TTree" << endl ;
}
Bool_t RooAbsArg::isValid() const
{
return kTRUE ;
}
void RooAbsArg::printName(ostream& os) const
{
os << GetName() ;
}
void RooAbsArg::printTitle(ostream& os) const
{
os << GetTitle() ;
}
void RooAbsArg::printClassName(ostream& os) const
{
os << IsA()->GetName() ;
}
void RooAbsArg::printAddress(ostream& os) const
{
os << this ;
}
void RooAbsArg::printArgs(ostream& os) const
{
if (numProxies()==0) return ;
os << "[ " ;
for (Int_t i=0 ; i<numProxies() ; i++) {
RooAbsProxy* p = getProxy(i) ;
if (p==0) continue ;
if (!TString(p->name()).BeginsWith("!")) {
p->print(os) ;
os << " " ;
}
}
printMetaArgs(os) ;
os << "]" ;
}
Int_t RooAbsArg::defaultPrintContents(Option_t* ) const
{
return kName|kClassName|kValue|kArgs ;
}
void RooAbsArg::printMultiline(ostream& os, Int_t , Bool_t , TString indent) const
{
os << indent << "--- RooAbsArg ---" << endl;
os << indent << " Value State: " ;
switch(_operMode) {
case ADirty: os << "FORCED DIRTY" ; break ;
case AClean: os << "FORCED clean" ; break ;
case Auto: os << (isValueDirty() ? "DIRTY":"clean") ; break ;
}
os << endl
<< indent << " Shape State: " << (isShapeDirty() ? "DIRTY":"clean") << endl;
os << indent << " Attributes: " ;
printAttribList(os) ;
os << endl ;
os << indent << " Address: " << (void*)this << endl;
os << indent << " Clients: " << endl;
RooFIter clientIter= _clientList.fwdIterator();
RooAbsArg* client ;
while ((client=clientIter.next())) {
os << indent << " (" << (void*)client << ","
<< (_clientListValue.findArg(client)?"V":"-")
<< (_clientListShape.findArg(client)?"S":"-")
<< ") " ;
client->printStream(os,kClassName|kTitle|kName,kSingleLine);
}
os << indent << " Servers: " << endl;
RooFIter serverIter= _serverList.fwdIterator();
RooAbsArg* server ;
while ((server=serverIter.next())) {
os << indent << " (" << (void*)server << ","
<< (server->_clientListValue.findArg(this)?"V":"-")
<< (server->_clientListShape.findArg(this)?"S":"-")
<< ") " ;
server->printStream(os,kClassName|kName|kTitle,kSingleLine);
}
os << indent << " Proxies: " << endl ;
for (int i=0 ; i<numProxies() ; i++) {
RooAbsProxy* proxy=getProxy(i) ;
if (!proxy) continue ;
if (proxy->IsA()->InheritsFrom(RooArgProxy::Class())) {
os << indent << " " << proxy->name() << " -> " ;
RooAbsArg* parg = ((RooArgProxy*)proxy)->absArg() ;
if (parg) {
parg->printStream(os,kName,kSingleLine) ;
} else {
os << " (empty)" << endl ; ;
}
} else {
os << indent << " " << proxy->name() << " -> " ;
os << endl ;
TString moreIndent(indent) ;
moreIndent.Append(" ") ;
((RooSetProxy*)proxy)->printStream(os,kName,kStandard,moreIndent.Data()) ;
}
}
}
void RooAbsArg::printTree(ostream& os, TString ) const
{
const_cast<RooAbsArg*>(this)->printCompactTree(os) ;
}
ostream& operator<<(ostream& os, RooAbsArg &arg)
{
arg.writeToStream(os,kTRUE) ;
return os ;
}
istream& operator>>(istream& is, RooAbsArg &arg)
{
arg.readFromStream(is,kTRUE,kFALSE) ;
return is ;
}
void RooAbsArg::printAttribList(ostream& os) const
{
set<string>::const_iterator iter = _boolAttrib.begin() ;
Bool_t first(kTRUE) ;
while (iter != _boolAttrib.end()) {
os << (first?" [":",") << *iter ;
first=kFALSE ;
++iter ;
}
if (!first) os << "] " ;
}
void RooAbsArg::attachDataSet(const RooAbsData &data)
{
const RooArgSet* set = data.get() ;
RooArgSet branches ;
branchNodeServerList(&branches,0,kTRUE) ;
RooFIter iter = branches.fwdIterator() ;
RooAbsArg* branch ;
while((branch=iter.next())) {
branch->redirectServers(*set,kFALSE,kFALSE) ;
}
}
void RooAbsArg::attachDataStore(const RooAbsDataStore &dstore)
{
const RooArgSet* set = dstore.get() ;
RooArgSet branches ;
branchNodeServerList(&branches,0,kTRUE) ;
RooFIter iter = branches.fwdIterator() ;
RooAbsArg* branch ;
while((branch=iter.next())) {
branch->redirectServers(*set,kFALSE,kFALSE) ;
}
}
Int_t RooAbsArg::Compare(const TObject* other) const
{
return strcmp(GetName(),other->GetName()) ;
}
void RooAbsArg::printDirty(Bool_t depth) const
{
if (depth) {
RooArgSet branchList ;
branchNodeServerList(&branchList) ;
RooFIter bIter = branchList.fwdIterator() ;
RooAbsArg* branch ;
while((branch=bIter.next())) {
branch->printDirty(kFALSE) ;
}
} else {
cout << GetName() << " : " ;
switch (_operMode) {
case AClean: cout << "FORCED clean" ; break ;
case ADirty: cout << "FORCED DIRTY" ; break ;
case Auto: cout << "Auto " << (isValueDirty()?"DIRTY":"clean") ;
}
cout << endl ;
}
}
void RooAbsArg::optimizeCacheMode(const RooArgSet& observables)
{
RooLinkedList proc;
RooArgSet opt ;
optimizeCacheMode(observables,opt,proc) ;
coutI(Optimization) << "RooAbsArg::optimizeCacheMode(" << GetName() << ") nodes " << opt << " depend on observables, "
<< "changing cache operation mode from change tracking to unconditional evaluation" << endl ;
}
void RooAbsArg::optimizeCacheMode(const RooArgSet& observables, RooArgSet& optimizedNodes, RooLinkedList& processedNodes)
{
if (!isDerived()) {
return ;
}
if (processedNodes.findArg(this)) {
return ;
} else {
processedNodes.Add(this) ;
}
if (dependsOnValue(observables)) {
if (dynamic_cast<RooRealIntegral*>(this)) {
cxcoutI(Integration) << "RooAbsArg::optimizeCacheMode(" << GetName() << ") integral depends on value of one or more observables and will be evaluated for every event" << endl ;
}
optimizedNodes.add(*this,kTRUE) ;
if (operMode()==AClean) {
} else {
setOperMode(ADirty,kTRUE) ;
}
} else {
}
for (Int_t i=0 ;i<numCaches() ; i++) {
getCache(i)->optimizeCacheMode(observables,optimizedNodes,processedNodes) ;
}
RooFIter sIter = serverMIterator() ;
RooAbsArg* server ;
while((server=sIter.next())) {
server->optimizeCacheMode(observables,optimizedNodes,processedNodes) ;
}
}
Bool_t RooAbsArg::findConstantNodes(const RooArgSet& observables, RooArgSet& cacheList)
{
RooLinkedList proc ;
Bool_t ret = findConstantNodes(observables,cacheList,proc) ;
coutI(Optimization) << "RooAbsArg::findConstantNodes(" << GetName() << "): components "
<< cacheList << " depend exclusively on constant parameters and will be precalculated and cached" << endl ;
return ret ;
}
Bool_t RooAbsArg::findConstantNodes(const RooArgSet& observables, RooArgSet& cacheList, RooLinkedList& processedNodes)
{
if (!isDerived()) {
return kFALSE;
}
if (processedNodes.findArg(this)) {
return kFALSE ;
} else {
processedNodes.Add(this) ;
}
Bool_t canOpt(kTRUE) ;
RooArgSet* paramSet = getParameters(observables) ;
RooFIter iter = paramSet->fwdIterator() ;
RooAbsArg* param ;
while((param = iter.next())) {
if (!param->isConstant()) {
canOpt=kFALSE ;
break ;
}
}
delete paramSet ;
if (getAttribute("NeverConstant")) {
canOpt = kFALSE ;
}
if (canOpt) {
setAttribute("ConstantExpression") ;
}
if (canOpt||getAttribute("CacheAndTrack")) {
if (!cacheList.find(*this) && dependsOnValue(observables) && !observables.find(*this) ) {
cxcoutD(Optimization) << "RooAbsArg::findConstantNodes(" << GetName() << ") adding self to list of constant nodes" << endl ;
if (canOpt) setAttribute("ConstantExpressionCached") ;
cacheList.add(*this,kFALSE) ;
}
}
if (!canOpt) {
RooFIter sIter = serverMIterator() ;
RooAbsArg* server ;
while((server=sIter.next())) {
if (server->isDerived()) {
server->findConstantNodes(observables,cacheList,processedNodes) ;
}
}
}
for (Int_t i=0 ;i<numCaches() ; i++) {
getCache(i)->findConstantNodes(observables,cacheList,processedNodes) ;
}
return kFALSE ;
}
void RooAbsArg::constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt)
{
RooFIter sIter = serverMIterator() ;
RooAbsArg* server ;
while((server=sIter.next())) {
server->constOptimizeTestStatistic(opcode,doAlsoTrackingOpt) ;
}
}
void RooAbsArg::setOperMode(OperMode mode, Bool_t recurseADirty)
{
if (mode==_operMode) return ;
_operMode = mode ;
_fast = ((mode==AClean) || dynamic_cast<RooRealVar*>(this)!=0 || dynamic_cast<RooConstVar*>(this)!=0 ) ;
for (Int_t i=0 ;i<numCaches() ; i++) {
getCache(i)->operModeHook() ;
}
operModeHook() ;
if (mode==ADirty && recurseADirty) {
RooFIter iter = valueClientMIterator() ;
RooAbsArg* client ;
while((client=iter.next())) {
client->setOperMode(mode) ;
}
}
}
void RooAbsArg::printCompactTree(const char* indent, const char* filename, const char* namePat, RooAbsArg* client)
{
if (filename) {
ofstream ofs(filename) ;
printCompactTree(ofs,indent,namePat,client) ;
} else {
printCompactTree(cout,indent,namePat,client) ;
}
}
void RooAbsArg::printCompactTree(ostream& os, const char* indent, const char* namePat, RooAbsArg* client)
{
if ( !namePat || TString(GetName()).Contains(namePat)) {
os << indent << this ;
if (client) {
os << "/" ;
if (isValueServer(*client)) os << "V" ; else os << "-" ;
if (isShapeServer(*client)) os << "S" ; else os << "-" ;
}
os << " " ;
os << IsA()->GetName() << "::" << GetName() << " = " ;
printValue(os) ;
if (_serverList.GetSize()>0) {
switch(operMode()) {
case Auto: os << " [Auto," << (isValueDirty()?"Dirty":"Clean") << "] " ; break ;
case AClean: os << " [ACLEAN] " ; break ;
case ADirty: os << " [ADIRTY] " ; break ;
}
}
os << endl ;
for (Int_t i=0 ;i<numCaches() ; i++) {
getCache(i)->printCompactTreeHook(os,indent) ;
}
printCompactTreeHook(os,indent) ;
}
TString indent2(indent) ;
indent2 += " " ;
RooFIter iter = serverMIterator() ;
RooAbsArg* arg ;
while((arg=iter.next())) {
arg->printCompactTree(os,indent2,namePat,this) ;
}
}
void RooAbsArg::printComponentTree(const char* indent, const char* namePat, Int_t nLevel)
{
if (nLevel==0) return ;
if (isFundamental()) return ;
RooResolutionModel* rmodel = dynamic_cast<RooResolutionModel*>(this) ;
if (rmodel && rmodel->isConvolved()) return ;
if (InheritsFrom("RooConstVar")) return ;
if ( !namePat || TString(GetName()).Contains(namePat)) {
cout << indent ;
Print() ;
}
TString indent2(indent) ;
indent2 += " " ;
RooFIter iter = serverMIterator() ;
RooAbsArg* arg ;
while((arg=iter.next())) {
arg->printComponentTree(indent2.Data(),namePat,nLevel-1) ;
}
}
TString RooAbsArg::cleanBranchName() const
{
TString rawBranchName = GetName() ;
if (getStringAttribute("BranchName")) {
rawBranchName = getStringAttribute("BranchName") ;
}
TString cleanName(rawBranchName) ;
cleanName.ReplaceAll("/","D") ;
cleanName.ReplaceAll("-","M") ;
cleanName.ReplaceAll("+","P") ;
cleanName.ReplaceAll("*","X") ;
cleanName.ReplaceAll("[","L") ;
cleanName.ReplaceAll("]","R") ;
cleanName.ReplaceAll("(","L") ;
cleanName.ReplaceAll(")","R") ;
cleanName.ReplaceAll("{","L") ;
cleanName.ReplaceAll("}","R") ;
if (cleanName.Length()<=60) return cleanName ;
static char buf[1024] ;
strlcpy(buf,cleanName.Data(),1024) ;
snprintf(buf+46,1024-46,"_CRC%08x",crc32(cleanName.Data())) ;
return TString(buf) ;
}
UInt_t RooAbsArg::crc32(const char* data)
{
unsigned long sz = strlen(data);
switch (strlen(data)) {
case 0:
return 0;
case 1:
return data[0];
case 2:
return (data[0] << 8) | data[1];
case 3:
return (data[0] << 16) | (data[1] << 8) | data[2];
case 4:
return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
default:
return crc32(data + 4, sz - 4, (data[0] << 24) | (data[1] << 16) |
(data[2] << 8) | data[3]);
}
}
UInt_t RooAbsArg::crc32(const char* data, ULong_t sz, UInt_t crc)
{
static const UInt_t crctab[256] = { 0x00000000,
0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
};
crc = ~crc;
while (sz--) crc = (crc << 8) ^ UInt_t(*data++) ^ crctab[crc >> 24];
return ~crc;
}
UInt_t RooAbsArg::fnv1a32(const char* data)
{
return fnv1a32(data, strlen(data));
}
UInt_t RooAbsArg::fnv1a32(const char* data, ULong_t sz, UInt_t hash)
{
const UInt_t fnv1a32mult = 16777619u;
while (sz--) {
hash ^= *data++;
hash *= fnv1a32mult;
}
return hash;
}
ULong64_t RooAbsArg::fnv1a64(const char* data)
{
return fnv1a64(data, strlen(data));
}
ULong64_t RooAbsArg::fnv1a64(const char* data, ULong_t sz, ULong64_t hash)
{
const ULong64_t fnv1a64mult = (ULong64_t(1) << 40) | ULong64_t(435);
while (sz--) {
hash ^= *data++;
hash *= fnv1a64mult;
}
return hash;
}
void RooAbsArg::printCompactTreeHook(ostream&, const char *)
{
}
void RooAbsArg::registerCache(RooAbsCache& cache)
{
_cacheList.push_back(&cache) ;
}
void RooAbsArg::unRegisterCache(RooAbsCache& cache)
{
_cacheList.erase(std::remove(_cacheList.begin(), _cacheList.end(), &cache),
_cacheList.end());
}
Int_t RooAbsArg::numCaches() const
{
return _cacheList.size() ;
}
RooAbsCache* RooAbsArg::getCache(Int_t index) const
{
return _cacheList[index] ;
}
RooArgSet* RooAbsArg::getVariables(Bool_t stripDisconnected) const
{
return getParameters(RooArgSet(),stripDisconnected) ;
}
RooLinkedList RooAbsArg::getCloningAncestors() const
{
RooLinkedList retVal ;
set<string>::const_iterator iter= _boolAttrib.begin() ;
while(iter != _boolAttrib.end()) {
if (TString(*iter).BeginsWith("CloneOf(")) {
char buf[128] ;
strlcpy(buf,iter->c_str(),128) ;
strtok(buf,"(") ;
char* ptrToken = strtok(0,")") ;
RooAbsArg* ptr = (RooAbsArg*) strtol(ptrToken,0,16) ;
retVal.Add(ptr) ;
}
}
return retVal ;
}
void RooAbsArg::graphVizTree(const char* fileName, const char* delimiter, bool useTitle, bool useLatex)
{
ofstream ofs(fileName) ;
if (!ofs) {
coutE(InputArguments) << "RooAbsArg::graphVizTree() ERROR: Cannot open graphViz output file with name " << fileName << endl ;
return ;
}
graphVizTree(ofs, delimiter, useTitle, useLatex) ;
}
void RooAbsArg::graphVizTree(ostream& os, const char* delimiter, bool useTitle, bool useLatex)
{
if (!os) {
coutE(InputArguments) << "RooAbsArg::graphVizTree() ERROR: output stream provided as input argument is in invalid state" << endl ;
}
os << "digraph " << GetName() << "{" << endl ;
RooArgSet nodeSet ;
treeNodeServerList(&nodeSet) ;
RooFIter iter = nodeSet.fwdIterator() ;
RooAbsArg* node ;
while((node=iter.next())) {
string nodeName = node->GetName();
string nodeTitle = node->GetTitle();
string nodeLabel = (useTitle && !nodeTitle.empty()) ? nodeTitle : nodeName;
string::size_type position = nodeLabel.find("#") ;
while(useLatex && position!=nodeLabel.npos){
nodeLabel.replace(position, 1, "\\");
}
string typeFormat = "\\texttt{";
string nodeType = (useLatex) ? typeFormat+node->IsA()->GetName()+"}" : node->IsA()->GetName();
os << "\"" << nodeName << "\" [ color=" << (node->isFundamental()?"blue":"red")
<< ", label=\"" << nodeType << delimiter << nodeLabel << "\"];" << endl ;
}
set<pair<RooAbsArg*,RooAbsArg*> > links ;
graphVizAddConnections(links) ;
set<pair<RooAbsArg*,RooAbsArg*> >::iterator liter = links.begin() ;
for( ; liter != links.end() ; ++liter ) {
os << "\"" << liter->first->GetName() << "\" -> \"" << liter->second->GetName() << "\";" << endl ;
}
os << "}" << endl ;
}
void RooAbsArg::graphVizAddConnections(set<pair<RooAbsArg*,RooAbsArg*> >& linkSet)
{
RooFIter sIter = serverMIterator() ;
RooAbsArg* server ;
while((server=sIter.next())) {
linkSet.insert(make_pair(this,server)) ;
server->graphVizAddConnections(linkSet) ;
}
}
Bool_t RooAbsArg::addOwnedComponents(const RooArgSet& comps)
{
if (!_ownedComponents) {
_ownedComponents = new RooArgSet("owned components") ;
}
return _ownedComponents->addOwned(comps) ;
}
RooAbsArg* RooAbsArg::cloneTree(const char* newname) const
{
RooArgSet* clonedNodes = (RooArgSet*) RooArgSet(*this).snapshot(kTRUE) ;
RooAbsArg* head = clonedNodes->find(*this) ;
clonedNodes->remove(*head) ;
head->addOwnedComponents(*clonedNodes) ;
clonedNodes->releaseOwnership() ;
delete clonedNodes ;
if (newname) {
head->TNamed::SetName(newname) ;
head->_namePtr = (TNamed*) RooNameReg::instance().constPtr(newname) ;
}
return head ;
}
void RooAbsArg::attachToStore(RooAbsDataStore& store)
{
if (dynamic_cast<RooTreeDataStore*>(&store)) {
attachToTree(((RooTreeDataStore&)store).tree()) ;
} else if (dynamic_cast<RooVectorDataStore*>(&store)) {
attachToVStore((RooVectorDataStore&)store) ;
}
}
RooExpensiveObjectCache& RooAbsArg::expensiveObjectCache() const
{
if (_eocache) {
return *_eocache ;
} else {
return RooExpensiveObjectCache::instance() ;
}
}
const char* RooAbsArg::aggregateCacheUniqueSuffix() const
{
string suffix ;
RooArgSet branches ;
branchNodeServerList(&branches) ;
RooFIter iter = branches.fwdIterator();
RooAbsArg* arg ;
while((arg=iter.next())) {
const char* tmp = arg->cacheUniqueSuffix() ;
if (tmp) suffix += tmp ;
}
return Form("%s",suffix.c_str()) ;
}
void RooAbsArg::wireAllCaches()
{
RooArgSet branches ;
branchNodeServerList(&branches) ;
RooFIter iter = branches.fwdIterator() ;
RooAbsArg* arg ;
while((arg=iter.next())) {
for (deque<RooAbsCache*>::iterator iter2 = arg->_cacheList.begin() ; iter2 != arg->_cacheList.end() ; ++iter2) {
(*iter2)->wireCache() ;
}
}
}
void RooAbsArg::SetName(const char* name)
{
TNamed::SetName(name) ;
TNamed* newPtr = (TNamed*) RooNameReg::instance().constPtr(GetName()) ;
if (newPtr != _namePtr) {
_namePtr = newPtr;
_namePtr->SetBit(RooNameReg::kRenamedArg);
}
}
void RooAbsArg::SetNameTitle(const char *name, const char *title)
{
TNamed::SetNameTitle(name,title) ;
TNamed* newPtr = (TNamed*) RooNameReg::instance().constPtr(GetName()) ;
if (newPtr != _namePtr) {
_namePtr = newPtr;
_namePtr->SetBit(RooNameReg::kRenamedArg);
}
}
void RooAbsArg::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
_ioReadStack.push(this) ;
R__b.ReadClassBuffer(RooAbsArg::Class(),this);
_ioReadStack.pop() ;
_namePtr = (TNamed*) RooNameReg::instance().constPtr(GetName()) ;
_isConstant = getAttribute("Constant") ;
} else {
R__b.WriteClassBuffer(RooAbsArg::Class(),this);
}
}
void RooAbsArg::ioStreamerPass2()
{
map<RooAbsArg*,TRefArray*>::iterator iter = _ioEvoList.find(this) ;
if (iter != _ioEvoList.end()) {
for (int i=0 ; i < iter->second->GetEntries() ; i++) {
_proxyList.Add(iter->second->At(i)) ;
}
delete iter->second ;
_ioEvoList.erase(iter) ;
}
}
void RooAbsArg::ioStreamerPass2Finalize()
{
map<RooAbsArg*,TRefArray*>::iterator iter = _ioEvoList.begin() ;
while (iter != _ioEvoList.end()) {
for (int i=0 ; i < iter->second->GetEntries() ; i++) {
iter->first->_proxyList.Add(iter->second->At(i)) ;
}
map<RooAbsArg*,TRefArray*>::iterator iter_tmp = iter ;
iter++ ;
delete iter_tmp->second ;
_ioEvoList.erase(iter_tmp) ;
}
}
void RooRefArray::Streamer(TBuffer &R__b)
{
UInt_t R__s, R__c;
if (R__b.IsReading()) {
Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
TRefArray* refArray = new TRefArray ;
refArray->Streamer(R__b) ;
R__b.CheckByteCount(R__s, R__c, refArray->IsA());
RooAbsArg::_ioEvoList[RooAbsArg::_ioReadStack.top()] = refArray ;
} else {
R__c = R__b.WriteVersion(RooRefArray::IsA(), kTRUE);
TRefArray refArray ;
TIterator* iter = MakeIterator() ;
TObject* tmpObj ; while ((tmpObj = iter->Next())) {
refArray.Add(tmpObj) ;
}
delete iter ;
refArray.Streamer(R__b) ;
R__b.SetByteCount(R__c, kTRUE) ;
}
}