Logo ROOT   6.10/09
Reference Guide
RooAbsArg.cxx
Go to the documentation of this file.
1 /******************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * @(#)root/roofitcore:$Id$
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2005, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 //////////////////////////////////////////////////////////////////////////////
18 /** \class RooAbsArg
19  \ingroup Roofitcore
20 
21 RooAbsArg is the common abstract base class for objects that
22 represent a value (of arbitrary type) and "shape" that in general
23 depends on (is a client of) other RooAbsArg subclasses. The only
24 state information about a value that is maintained in this base
25 class consists of named attributes and flags that track when either
26 the value or the shape of this object changes. The meaning of shape
27 depends on the client implementation but could be, for example, the
28 allowed range of a value. The base class is also responsible for
29 managing client/server links and propagating value/shape changes
30 through an expression tree. RooAbsArg implements public interfaces
31 for inspecting client/server relationships and
32 setting/clearing/testing named attributes.
33 
34 */
35 
36 #include "RooFit.h"
37 #include "Riostream.h"
38 
39 #include "TBuffer.h"
40 #include "TClass.h"
41 #include "TObjString.h"
42 #include "TVirtualStreamerInfo.h"
43 // #include "TGraphStruct.h"
44 
45 #include "RooSecondMoment.h"
46 
47 #include "RooMsgService.h"
48 #include "RooAbsArg.h"
49 #include "RooArgSet.h"
50 #include "RooArgProxy.h"
51 #include "RooSetProxy.h"
52 #include "RooListProxy.h"
53 #include "RooAbsData.h"
54 #include "RooAbsCategoryLValue.h"
55 #include "RooAbsRealLValue.h"
56 #include "RooTrace.h"
57 #include "RooStringVar.h"
58 #include "RooRealIntegral.h"
59 #include "RooConstVar.h"
60 #include "RooMsgService.h"
62 #include "RooAbsDataStore.h"
63 #include "RooResolutionModel.h"
64 #include "RooVectorDataStore.h"
65 #include "RooTreeDataStore.h"
66 
67 #include <string.h>
68 #include <iomanip>
69 #include <fstream>
70 #include <algorithm>
71 #include <sstream>
72 
73 using namespace std ;
74 
75 #if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
76 char* operator+( streampos&, char* );
77 #endif
78 
80 ;
81 
84 Bool_t RooAbsArg::inhibitDirty() const { return _inhibitDirty && !_localNoInhibitDirty; }
85 
86 std::map<RooAbsArg*,TRefArray*> RooAbsArg::_ioEvoList ;
87 std::stack<RooAbsArg*> RooAbsArg::_ioReadStack ;
88 
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Default constructor
92 
94  TNamed(),
95  _deleteWatch(kFALSE),
96  _operMode(Auto),
97  _fast(kFALSE),
98  _ownedComponents(0),
99  _prohibitServerRedirect(kFALSE),
100  _eocache(0),
101  _namePtr(0),
102  _isConstant(kFALSE),
103  _localNoInhibitDirty(kFALSE)
104 {
107 
109 
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// Create an object with the specified name and descriptive title.
114 /// The newly created object has no clients or servers and has its
115 /// dirty flags set.
116 
117 RooAbsArg::RooAbsArg(const char *name, const char *title) :
118  TNamed(name,title),
122  _operMode(Auto),
123  _fast(kFALSE),
124  _ownedComponents(0),
126  _eocache(0),
127  _namePtr(0),
130 {
132 
135 
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// Copy constructor transfers all boolean and string properties of the original
140 /// object. Transient properties and client-server links are not copied
141 
142 RooAbsArg::RooAbsArg(const RooAbsArg& other, const char* name)
143  : TNamed(other.GetName(),other.GetTitle()),
144  RooPrintable(other),
145  _boolAttrib(other._boolAttrib),
147  _deleteWatch(other._deleteWatch),
148  _operMode(Auto),
149  _fast(kFALSE),
150  _ownedComponents(0),
152  _eocache(other._eocache),
153  _namePtr(other._namePtr),
154  _isConstant(other._isConstant),
156 {
157  // Use name in argument, if supplied
158  if (name) {
159  TNamed::SetName(name) ;
161  } else {
162  // Same name, Ddon't recalculate name pointer (expensive)
163  TNamed::SetName(other.GetName()) ;
164  _namePtr = other._namePtr ;
165  }
166 
167  // Copy server list by hand
168  RooFIter sIter = other._serverList.fwdIterator() ;
169  RooAbsArg* server ;
170  Bool_t valueProp, shapeProp ;
171  while ((server = sIter.next())) {
172  valueProp = server->_clientListValue.findArg(&other)?kTRUE:kFALSE ;
173  shapeProp = server->_clientListShape.findArg(&other)?kTRUE:kFALSE ;
174  addServer(*server,valueProp,shapeProp) ;
175  }
176 
179 
180  setValueDirty() ;
181  setShapeDirty() ;
182 
183  //setAttribute(Form("CloneOf(%08x)",&other)) ;
184  //cout << "RooAbsArg::cctor(" << this << ") #bools = " << _boolAttrib.size() << " #strings = " << _stringAttrib.size() << endl ;
185 
186 }
187 
188 
189 ////////////////////////////////////////////////////////////////////////////////
190 /// Destructor.
191 
193 {
194  // Notify all servers that they no longer need to serve us
195  while (_serverList.GetSize() > 0) {
196  removeServer(*static_cast<RooAbsArg*>(_serverList.First()), kTRUE) ;
197  }
198 
199  // Notify all client that they are in limbo
200  RooRefCountList tmpclientList(_clientList); // have to copy, as we invalidate iterators
201  RooFIter clientIter = tmpclientList.fwdIterator() ;
202  RooAbsArg* client = 0;
203  Bool_t first(kTRUE) ;
204  while ((client=clientIter.next())) {
205  client->setAttribute("ServerDied") ;
206  TString attr("ServerDied:");
207  attr.Append(GetName());
208  attr.Append(Form("(%lx)",(ULong_t)this)) ;
209  client->setAttribute(attr.Data());
210  client->removeServer(*this,kTRUE);
211 
212  if (_verboseDirty) {
213 
214  if (first) {
215  cxcoutD(Tracing) << "RooAbsArg::dtor(" << GetName() << "," << this << ") DeleteWatch: object is being destroyed" << endl ;
216  first = kFALSE ;
217  }
218 
219  cxcoutD(Tracing) << fName << "::" << ClassName() << ":~RooAbsArg: dependent \""
220  << client->GetName() << "\" should have been deleted first" << endl ;
221  }
222  }
223 
224  delete _clientShapeIter ;
225  delete _clientValueIter ;
226 
227  if (_ownedComponents) {
228  delete _ownedComponents ;
229  _ownedComponents = 0 ;
230  }
231 
232 }
233 
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 /// Control global dirty inhibit mode. When set to true no value or shape dirty
237 /// flags are propagated and cache is always considered to be dirty.
238 
240 {
241  _inhibitDirty = flag ;
242 }
243 
244 
245 ////////////////////////////////////////////////////////////////////////////////
246 /// Activate verbose messaging related to dirty flag propagation
247 
249 {
250  _verboseDirty = flag ;
251 }
252 
253 ////////////////////////////////////////////////////////////////////////////////
254 /// Check if this object was created as a clone of 'other'
255 
257 {
258  return (getAttribute(Form("CloneOf(%lx)",(ULong_t)&other)) ||
259  other.getAttribute(Form("CloneOf(%lx)",(ULong_t)this))) ;
260 }
261 
262 
263 ////////////////////////////////////////////////////////////////////////////////
264 /// Set (default) or clear a named boolean attribute of this object.
265 
267 {
268  // Preserve backward compatibility - any strong
269  if(string("Constant")==name) {
270  _isConstant = value ;
271  }
272 
273  if (value) {
274  _boolAttrib.insert(name) ;
275  } else {
276  set<string>::iterator iter = _boolAttrib.find(name) ;
277  if (iter != _boolAttrib.end()) {
278  _boolAttrib.erase(iter) ;
279  }
280 
281  }
282 
283 }
284 
285 
286 ////////////////////////////////////////////////////////////////////////////////
287 /// Check if a named attribute is set. By default, all attributes are unset.
288 
290 {
291  return (_boolAttrib.find(name) != _boolAttrib.end()) ;
292 }
293 
294 
295 ////////////////////////////////////////////////////////////////////////////////
296 /// Associate string 'value' to this object under key 'key'
297 
298 void RooAbsArg::setStringAttribute(const Text_t* key, const Text_t* value)
299 {
300  if (value) {
301  _stringAttrib[key] = value ;
302  } else {
303  if (_stringAttrib.find(key)!=_stringAttrib.end()) {
304  _stringAttrib.erase(key) ;
305  }
306  }
307 }
308 
309 ////////////////////////////////////////////////////////////////////////////////
310 /// Get string attribute mapped under key 'key'. Returns null pointer
311 /// if no attribute exists under that key
312 
314 {
315  map<string,string>::const_iterator iter = _stringAttrib.find(key) ;
316  if (iter!=_stringAttrib.end()) {
317  return iter->second.c_str() ;
318  } else {
319  return 0 ;
320  }
321 }
322 
323 
324 ////////////////////////////////////////////////////////////////////////////////
325 /// Set (default) or clear a named boolean attribute of this object.
326 
328 {
329  if (value) {
330 
331  _boolAttribTransient.insert(name) ;
332 
333  } else {
334 
335  set<string>::iterator iter = _boolAttribTransient.find(name) ;
336  if (iter != _boolAttribTransient.end()) {
337  _boolAttribTransient.erase(iter) ;
338  }
339 
340  }
341 
342 }
343 
344 
345 ////////////////////////////////////////////////////////////////////////////////
346 /// Check if a named attribute is set. By default, all attributes
347 /// are unset.
348 
350 {
351  return (_boolAttribTransient.find(name) != _boolAttribTransient.end()) ;
352 }
353 
354 
355 
356 
357 ////////////////////////////////////////////////////////////////////////////////
358 /// Register another RooAbsArg as a server to us, ie, declare that
359 /// we depend on it. In addition to the basic client-server relationship,
360 /// we can declare dependence on the server's value and/or shape.
361 
362 void RooAbsArg::addServer(RooAbsArg& server, Bool_t valueProp, Bool_t shapeProp)
363 {
365  cxcoutF(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName()
366  << "): PROHIBITED SERVER ADDITION REQUESTED: adding server " << server.GetName()
367  << "(" << &server << ") for " << (valueProp?"value ":"") << (shapeProp?"shape":"") << endl ;
368  assert(0) ;
369  }
370 
371  cxcoutD(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName() << "): adding server " << server.GetName()
372  << "(" << &server << ") for " << (valueProp?"value ":"") << (shapeProp?"shape":"") << endl ;
373 
374  if (server.operMode()==ADirty && operMode()!=ADirty && valueProp) {
376  }
377 
378 
379  // LM: use hash tables for larger lists
381  if (server._clientList.GetSize() > 999 && server._clientList.getHashTableSize() == 0) server._clientList.setHashTableSize(1000);
382  if (server._clientListValue.GetSize() > 999 && server._clientListValue.getHashTableSize() == 0) server._clientListValue.setHashTableSize(1000);
383 
384  // Add server link to given server
385  _serverList.Add(&server) ;
386 
387  server._clientList.Add(this) ;
388  if (valueProp) server._clientListValue.Add(this) ;
389  if (shapeProp) server._clientListShape.Add(this) ;
390 }
391 
392 
393 
394 ////////////////////////////////////////////////////////////////////////////////
395 /// Register a list of RooAbsArg as servers to us by calls
396 /// addServer() for each arg in the list
397 
398 void RooAbsArg::addServerList(RooAbsCollection& serverList, Bool_t valueProp, Bool_t shapeProp)
399 {
400  RooAbsArg* arg ;
401  RooFIter iter = serverList.fwdIterator() ;
402  while ((arg=iter.next())) {
403  addServer(*arg,valueProp,shapeProp) ;
404  }
405 }
406 
407 
408 
409 ////////////////////////////////////////////////////////////////////////////////
410 /// Unregister another RooAbsArg as a server to us, ie, declare that
411 /// we no longer depend on its value and shape.
412 
414 {
416  cxcoutF(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName() << "): PROHIBITED SERVER REMOVAL REQUESTED: removing server "
417  << server.GetName() << "(" << &server << ")" << endl ;
418  assert(0) ;
419  }
420 
421  if (_verboseDirty) {
422  cxcoutD(LinkStateMgmt) << "RooAbsArg::removeServer(" << GetName() << "): removing server "
423  << server.GetName() << "(" << &server << ")" << endl ;
424  }
425 
426  // Remove server link to given server
427  if (!force) {
428  _serverList.Remove(&server) ;
429 
430  server._clientList.Remove(this) ;
431  server._clientListValue.Remove(this) ;
432  server._clientListShape.Remove(this) ;
433  } else {
434  _serverList.RemoveAll(&server) ;
435 
436  server._clientList.RemoveAll(this) ;
437  server._clientListValue.RemoveAll(this) ;
438  server._clientListShape.RemoveAll(this) ;
439  }
440 }
441 
442 
443 ////////////////////////////////////////////////////////////////////////////////
444 /// Replace 'oldServer' with 'newServer'
445 
446 void RooAbsArg::replaceServer(RooAbsArg& oldServer, RooAbsArg& newServer, Bool_t propValue, Bool_t propShape)
447 {
448  Int_t count = _serverList.refCount(&oldServer);
449  removeServer(oldServer, kTRUE);
450  while (count--) {
451  addServer(newServer, propValue, propShape);
452  }
453 }
454 
455 
456 ////////////////////////////////////////////////////////////////////////////////
457 /// Change dirty flag propagation mask for specified server
458 
459 void RooAbsArg::changeServer(RooAbsArg& server, Bool_t valueProp, Bool_t shapeProp)
460 {
461  if (!_serverList.findArg(&server)) {
462  coutE(LinkStateMgmt) << "RooAbsArg::changeServer(" << GetName() << "): Server "
463  << server.GetName() << " not registered" << endl ;
464  return ;
465  }
466 
467  // This condition should not happen, but check anyway
468  if (!server._clientList.findArg(this)) {
469  coutE(LinkStateMgmt) << "RooAbsArg::changeServer(" << GetName() << "): Server "
470  << server.GetName() << " doesn't have us registered as client" << endl ;
471  return ;
472  }
473 
474  // Remove all propagation links, then reinstall requested ones ;
475  Int_t vcount = server._clientListValue.refCount(this) ;
476  Int_t scount = server._clientListShape.refCount(this) ;
477  server._clientListValue.RemoveAll(this) ;
478  server._clientListShape.RemoveAll(this) ;
479  if (valueProp) {
480  server._clientListValue.Add(this, vcount) ;
481  }
482  if (shapeProp) {
483  server._clientListShape.Add(this, scount) ;
484  }
485 }
486 
487 
488 
489 ////////////////////////////////////////////////////////////////////////////////
490 /// Fill supplied list with all leaf nodes of the arg tree, starting with
491 /// ourself as top node. A leaf node is node that has no servers declared.
492 
493 void RooAbsArg::leafNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t recurseNonDerived) const
494 {
495  treeNodeServerList(list,arg,kFALSE,kTRUE,kFALSE,recurseNonDerived) ;
496 }
497 
498 
499 
500 ////////////////////////////////////////////////////////////////////////////////
501 /// Fill supplied list with all branch nodes of the arg tree starting with
502 /// ourself as top node. A branch node is node that has one or more servers declared.
503 
504 void RooAbsArg::branchNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t recurseNonDerived) const
505 {
506  treeNodeServerList(list,arg,kTRUE,kFALSE,kFALSE,recurseNonDerived) ;
507 }
508 
509 
510 ////////////////////////////////////////////////////////////////////////////////
511 /// Fill supplied list with nodes of the arg tree, following all server links,
512 /// starting with ourself as top node.
513 
514 void RooAbsArg::treeNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t doBranch, Bool_t doLeaf, Bool_t valueOnly, Bool_t recurseFundamental) const
515 {
516 // if (arg==0) {
517 // cout << "treeNodeServerList(" << GetName() << ") doBranch=" << (doBranch?"T":"F") << " doLeaf = " << (doLeaf?"T":"F") << " valueOnly=" << (valueOnly?"T":"F") << endl ;
518 // }
519 
520  if (!arg) {
521 // if (list->getHashTableSize()==0) {
522 // list->setHashTableSize(1000) ;
523 // }
524  arg=this ;
525  }
526 
527  // Decide if to add current node
528  if ((doBranch&&doLeaf) ||
529  (doBranch&&arg->isDerived()) ||
530  (doLeaf&&arg->isFundamental()&&(!(recurseFundamental&&arg->isDerived()))) ||
531  (doLeaf && !arg->isFundamental() && !arg->isDerived())) {
532 
533  list->add(*arg,kTRUE) ;
534  }
535 
536  // Recurse if current node is derived
537  if (arg->isDerived() && (!arg->isFundamental() || recurseFundamental)) {
538  RooAbsArg* server ;
539  RooFIter sIter = arg->serverMIterator() ;
540  while ((server=sIter.next())) {
541 
542  // Skip non-value server nodes if requested
543  Bool_t isValueSrv = server->_clientListValue.findArg(arg)?kTRUE:kFALSE ;
544  if (valueOnly && !isValueSrv) {
545  continue ;
546  }
547  treeNodeServerList(list,server,doBranch,doLeaf,valueOnly,recurseFundamental) ;
548  }
549  }
550 }
551 
552 
553 ////////////////////////////////////////////////////////////////////////////////
554 /// Create a list of leaf nodes in the arg tree starting with
555 /// ourself as top node that don't match any of the names of the variable list
556 /// of the supplied data set (the dependents). The caller of this
557 /// function is responsible for deleting the returned argset.
558 /// The complement of this function is getObservables()
559 
560 RooArgSet* RooAbsArg::getParameters(const RooAbsData* set, Bool_t stripDisconnected) const
561 {
562  return getParameters(set?set->get():0,stripDisconnected) ;
563 }
564 
565 
566 ////////////////////////////////////////////////////////////////////////////////
567 /// INTERNAL helper function for getParameters()
568 
569 void RooAbsArg::addParameters(RooArgSet& params, const RooArgSet* nset,Bool_t stripDisconnected) const
570 {
571  // INTERNAL helper function for getParameters()
572  RooFIter siter = serverMIterator() ;
573  RooAbsArg* server ;
574 
575  RooArgSet nodeParamServers ;
576  RooArgSet nodeBranchServers ;
577  while((server=siter.next())) {
578  if (server->isValueServer(*this)) {
579  if (server->isFundamental()) {
580  if (!nset || !server->dependsOn(*nset)) {
581  nodeParamServers.add(*server) ;
582  }
583  } else {
584  nodeBranchServers.add(*server) ;
585  }
586  }
587  }
588 
589  // Allow pdf to strip parameters from list before adding it
590  getParametersHook(nset,&nodeParamServers,stripDisconnected) ;
591 
592  // Add parameters of this node to the combined list
593  params.add(nodeParamServers,kTRUE) ;
594 
595  // Now recurse into branch servers
596  RooFIter biter = nodeBranchServers.fwdIterator() ;
597  while((server=biter.next())) {
598  server->addParameters(params,nset) ;
599  }
600 }
601 
602 
603 ////////////////////////////////////////////////////////////////////////////////
604 /// Create a list of leaf nodes in the arg tree starting with
605 /// ourself as top node that don't match any of the names the args in the
606 /// supplied argset. The caller of this function is responsible
607 /// for deleting the returned argset. The complement of this function
608 /// is getObservables()
609 
610 RooArgSet* RooAbsArg::getParameters(const RooArgSet* nset, Bool_t stripDisconnected) const
611 {
612 
613  RooArgSet* parList = new RooArgSet("parameters");
614 
615  addParameters(*parList, nset, stripDisconnected);
616 
617  parList->sort();
618  return parList;
619 }
620 
621 
622 
623 ////////////////////////////////////////////////////////////////////////////////
624 /// Create a list of leaf nodes in the arg tree starting with
625 /// ourself as top node that match any of the names of the variable list
626 /// of the supplied data set (the dependents). The caller of this
627 /// function is responsible for deleting the returned argset.
628 /// The complement of this function is getObservables()
629 
631 {
632  if (!set) return new RooArgSet ;
633 
634  return getObservables(set->get()) ;
635 }
636 
637 
638 ////////////////////////////////////////////////////////////////////////////////
639 /// Create a list of leaf nodes in the arg tree starting with
640 /// ourself as top node that match any of the names the args in the
641 /// supplied argset. The caller of this function is responsible
642 /// for deleting the returned argset. The complement of this function
643 /// is getObservables()
644 
645 RooArgSet* RooAbsArg::getObservables(const RooArgSet* dataList, Bool_t valueOnly) const
646 {
647  //cout << "RooAbsArg::getObservables(" << GetName() << ")" << endl ;
648 
649  RooArgSet* depList = new RooArgSet("dependents") ;
650  if (!dataList) return depList ;
651 
652  // Make iterator over tree leaf node list
653  RooArgSet leafList("leafNodeServerList") ;
654  treeNodeServerList(&leafList,0,kFALSE,kTRUE,valueOnly) ;
655  //leafNodeServerList(&leafList) ;
656  RooFIter sIter = leafList.fwdIterator() ;
657 
658  RooAbsArg* arg ;
659  if (valueOnly) {
660  while ((arg=sIter.next())) {
661  if (arg->dependsOnValue(*dataList) && arg->isLValue()) {
662  depList->add(*arg) ;
663  }
664  }
665  } else {
666  while ((arg=sIter.next())) {
667  if (arg->dependsOn(*dataList) && arg->isLValue()) {
668  depList->add(*arg) ;
669  }
670  }
671  }
672  //delete sIter ;
673 
674 // // Call hook function for all branch nodes
675 // RooArgSet branchList ;
676 // branchNodeServerList(&branchList) ;
677 // RooAbsArg* branch ;
678 // RooLinkedListIter bIter = branchList.iterator() ;
679 // while((branch=(RooAbsArg*)bIter.Next())) {
680 // branch->getObservablesHook(dataList, depList) ;
681 // }
682 // //delete bIter ;
683 
684  return depList ;
685 }
686 
687 
689 {
690  // Return a RooArgSet with all component (branch nodes) of the
691  // expression tree headed by this object
692 
693  TString name(GetName()) ;
694  name.Append("_components") ;
695 
696  RooArgSet* set = new RooArgSet(name) ;
697  branchNodeServerList(set) ;
698 
699  return set ;
700 }
701 
702 
703 
704 ////////////////////////////////////////////////////////////////////////////////
705 /// Overloadable function in which derived classes can implement
706 /// consistency checks of the variables. If this function returns
707 /// true, indicating an error, the fitter or generator will abort.
708 
710 {
711  return kFALSE ;
712 }
713 
714 
715 ////////////////////////////////////////////////////////////////////////////////
716 /// Recursively call checkObservables on all nodes in the expression tree
717 
719 {
720  RooArgSet nodeList ;
721  treeNodeServerList(&nodeList) ;
722  RooFIter iter = nodeList.fwdIterator() ;
723 
724  RooAbsArg* arg ;
725  Bool_t ret(kFALSE) ;
726  while((arg=iter.next())) {
727  if (arg->getAttribute("ServerDied")) {
728  coutE(LinkStateMgmt) << "RooAbsArg::recursiveCheckObservables(" << GetName() << "): ERROR: one or more servers of node "
729  << arg->GetName() << " no longer exists!" << endl ;
730  arg->Print("v") ;
731  ret = kTRUE ;
732  }
733  ret |= arg->checkObservables(nset) ;
734  }
735 
736  return ret ;
737 }
738 
739 
740 ////////////////////////////////////////////////////////////////////////////////
741 /// Test whether we depend on (ie, are served by) any object in the
742 /// specified collection. Uses the dependsOn(RooAbsArg&) member function.
743 
744 Bool_t RooAbsArg::dependsOn(const RooAbsCollection& serverList, const RooAbsArg* ignoreArg, Bool_t valueOnly) const
745 {
746  // Test whether we depend on (ie, are served by) any object in the
747  // specified collection. Uses the dependsOn(RooAbsArg&) member function.
748 
749  RooFIter sIter = serverList.fwdIterator();
750  RooAbsArg* server ;
751  while ((server=sIter.next())) {
752  if (dependsOn(*server,ignoreArg,valueOnly)) {
753  return kTRUE;
754  }
755  }
756  return kFALSE;
757 }
758 
759 
760 ////////////////////////////////////////////////////////////////////////////////
761 /// Test whether we depend on (ie, are served by) the specified object.
762 /// Note that RooAbsArg objects are considered equivalent if they have
763 /// the same name.
764 
765 Bool_t RooAbsArg::dependsOn(const RooAbsArg& testArg, const RooAbsArg* ignoreArg, Bool_t valueOnly) const
766 {
767  if (this==ignoreArg) return kFALSE ;
768 
769  // First check if testArg is self
770  //if (!TString(testArg.GetName()).CompareTo(GetName())) return kTRUE ;
771  if (testArg.namePtr()==namePtr()) return kTRUE ;
772 
773 
774  // Next test direct dependence
775  RooAbsArg* server = findServer(testArg) ;
776  if (server!=0) {
777 
778  // Return true if valueOnly is FALSE or if server is value server, otherwise keep looking
779  if ( !valueOnly || server->isValueServer(*this)) {
780  return kTRUE ;
781  }
782  }
783 
784  // If not, recurse
785  RooFIter sIter = serverMIterator() ;
786  while ((server=sIter.next())) {
787 
788  if ( !valueOnly || server->isValueServer(*this)) {
789  if (server->dependsOn(testArg,ignoreArg,valueOnly)) {
790  return kTRUE ;
791  }
792  }
793  }
794 
795  return kFALSE ;
796 }
797 
798 
799 
800 ////////////////////////////////////////////////////////////////////////////////
801 /// Test if any of the nodes of tree are shared with that of the given tree
802 
803 Bool_t RooAbsArg::overlaps(const RooAbsArg& testArg, Bool_t valueOnly) const
804 {
805  RooArgSet list("treeNodeList") ;
806  treeNodeServerList(&list) ;
807 
808  return valueOnly ? testArg.dependsOnValue(list) : testArg.dependsOn(list) ;
809 }
810 
811 
812 
813 ////////////////////////////////////////////////////////////////////////////////
814 /// Test if any of the dependents of the arg tree (as determined by getObservables)
815 /// overlaps with those of the testArg.
816 
817 Bool_t RooAbsArg::observableOverlaps(const RooAbsData* dset, const RooAbsArg& testArg) const
818 {
819  return observableOverlaps(dset->get(),testArg) ;
820 }
821 
822 
823 ////////////////////////////////////////////////////////////////////////////////
824 /// Test if any of the dependents of the arg tree (as determined by getObservables)
825 /// overlaps with those of the testArg.
826 
827 Bool_t RooAbsArg::observableOverlaps(const RooArgSet* nset, const RooAbsArg& testArg) const
828 {
829  RooArgSet* depList = getObservables(nset) ;
830  Bool_t ret = testArg.dependsOn(*depList) ;
831  delete depList ;
832  return ret ;
833 }
834 
835 
836 
837 ////////////////////////////////////////////////////////////////////////////////
838 /// Mark this object as having changed its value, and propagate this status
839 /// change to all of our clients. If the object is not in automatic dirty
840 /// state propagation mode, this call has no effect
841 
842 void RooAbsArg::setValueDirty(const RooAbsArg* source) const
843 {
844  if (_operMode!=Auto || _inhibitDirty) return ;
845 
846  // Handle no-propagation scenarios first
847  if (_clientListValue.GetSize()==0) {
848  _valueDirty = kTRUE ;
849  return ;
850  }
851 
852  // Cyclical dependency interception
853  if (source==0) {
854  source=this ;
855  } else if (source==this) {
856  // Cyclical dependency, abort
857  coutE(LinkStateMgmt) << "RooAbsArg::setValueDirty(" << GetName()
858  << "): cyclical dependency detected, source = " << source->GetName() << endl ;
859  //assert(0) ;
860  return ;
861  }
862 
863  // Propagate dirty flag to all clients if this is a down->up transition
864  if (_verboseDirty) {
865  cxcoutD(LinkStateMgmt) << "RooAbsArg::setValueDirty(" << (source?source->GetName():"self") << "->" << GetName() << "," << this
866  << "): dirty flag " << (_valueDirty?"already ":"") << "raised" << endl ;
867  }
868 
869  _valueDirty = kTRUE ;
870 
871 
872  RooFIter clientValueIter = _clientListValue.fwdIterator() ;
873  RooAbsArg* client ;
874  while ((client=clientValueIter.next())) {
875  client->setValueDirty(source) ;
876  }
877 
878 
879 }
880 
881 
882 ////////////////////////////////////////////////////////////////////////////////
883 /// Mark this object as having changed its shape, and propagate this status
884 /// change to all of our clients.
885 
886 void RooAbsArg::setShapeDirty(const RooAbsArg* source) const
887 {
888  if (_verboseDirty) {
889  cxcoutD(LinkStateMgmt) << "RooAbsArg::setShapeDirty(" << GetName()
890  << "): dirty flag " << (_shapeDirty?"already ":"") << "raised" << endl ;
891  }
892 
893  if (_clientListShape.GetSize()==0) {
894  _shapeDirty = kTRUE ;
895  return ;
896  }
897 
898  // Set 'dirty' shape state for this object and propagate flag to all its clients
899  if (source==0) {
900  source=this ;
901  } else if (source==this) {
902  // Cyclical dependency, abort
903  coutE(LinkStateMgmt) << "RooAbsArg::setShapeDirty(" << GetName()
904  << "): cyclical dependency detected" << endl ;
905  return ;
906  }
907 
908  // Propagate dirty flag to all clients if this is a down->up transition
910 
911  RooFIter clientShapeIter = _clientListShape.fwdIterator() ;
912  RooAbsArg* client ;
913  while ((client=clientShapeIter.next())) {
914  client->setShapeDirty(source) ;
915  client->setValueDirty(source) ;
916  }
917 
918 }
919 
920 
921 
922 ////////////////////////////////////////////////////////////////////////////////
923 /// Substitute our servers with those listed in newSet. If nameChange is false, servers and
924 /// and substitutes are matched by name. If nameChange is true, servers are matched to args
925 /// in newSet that have the 'ORIGNAME:<servername>' attribute set. If mustReplaceAll is set,
926 /// a warning is printed and error status is returned if not all servers could be sucessfully
927 /// substituted.
928 
929 Bool_t RooAbsArg::redirectServers(const RooAbsCollection& newSetOrig, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursionStep)
930 {
931  // Trivial case, no servers
932  if (!_serverList.First()) return kFALSE ;
933  if (newSetOrig.getSize()==0) return kFALSE ;
934 
935  // Strip any non-matchin removal nodes from newSetOrig
936  RooAbsCollection* newSet ;
937 
938  if (nameChange) {
939 
940  newSet = new RooArgSet ;
941  RooFIter iter = newSetOrig.fwdIterator() ;
942  RooAbsArg* arg ;
943  while((arg=iter.next())) {
944 
945  if (string("REMOVAL_DUMMY")==arg->GetName()) {
946 
947  if (arg->getAttribute("REMOVE_ALL")) {
948 // cout << "RooAbsArg::redir including remove_all node " << arg->GetName() << endl ;
949  newSet->add(*arg) ;
950  } else if (arg->getAttribute(Form("REMOVE_FROM_%s",getStringAttribute("ORIGNAME")))) {
951 // cout << "RooAbsArg::redir including remove_from_" << GetName() << " node " << arg->GetName() << endl ;
952  newSet->add(*arg) ;
953  }
954  } else {
955  newSet->add(*arg) ;
956  }
957  }
958 
959 // cout << "RooAbsArg::redirect with name change(" << GetName() << ") newSet = " << newSet << " origSet = " << newSetOrig << endl ;
960 
961  } else {
962  newSet = (RooAbsCollection*) &newSetOrig ;
963  }
964 
965  // Replace current servers with new servers with the same name from the given list
966  Bool_t ret(kFALSE) ;
967 
968  //Copy original server list to not confuse the iterator while deleting
969  RooLinkedList origServerList, origServerValue, origServerShape ;
970  RooAbsArg *oldServer, *newServer ;
971  RooFIter sIter = _serverList.fwdIterator() ;
972  while ((oldServer=sIter.next())) {
973  origServerList.Add(oldServer) ;
974 
975  // Retrieve server side link state information
976  if (oldServer->_clientListValue.findArg(this)) {
977  origServerValue.Add(oldServer) ;
978  }
979  if (oldServer->_clientListShape.findArg(this)) {
980  origServerShape.Add(oldServer) ;
981  }
982  }
983 
984  // Delete all previously registered servers
985  sIter = origServerList.fwdIterator() ;
986  Bool_t propValue, propShape ;
987  while ((oldServer=sIter.next())) {
988 
989  newServer= oldServer->findNewServer(*newSet, nameChange);
990 
991  if (newServer && _verboseDirty) {
992  cxcoutD(LinkStateMgmt) << "RooAbsArg::redirectServers(" << (void*)this << "," << GetName() << "): server " << oldServer->GetName()
993  << " redirected from " << oldServer << " to " << newServer << endl ;
994  }
995 
996  if (!newServer) {
997  if (mustReplaceAll) {
998  cxcoutD(LinkStateMgmt) << "RooAbsArg::redirectServers(" << (void*)this << "," << GetName() << "): server " << oldServer->GetName()
999  << " (" << (void*)oldServer << ") not redirected" << (nameChange?"[nameChange]":"") << endl ;
1000  ret = kTRUE ;
1001  }
1002  continue ;
1003  }
1004 
1005  propValue=origServerValue.findArg(oldServer)?kTRUE:kFALSE ;
1006  propShape=origServerShape.findArg(oldServer)?kTRUE:kFALSE ;
1007  // cout << "replaceServer with name " << oldServer->GetName() << " old=" << oldServer << " new=" << newServer << endl ;
1008  if (newServer != this) {
1009  replaceServer(*oldServer,*newServer,propValue,propShape) ;
1010  }
1011  }
1012 
1013 
1014  setValueDirty() ;
1015  setShapeDirty() ;
1016 
1017  // Process the proxies
1018  Bool_t allReplaced=kTRUE ;
1019  for (int i=0 ; i<numProxies() ; i++) {
1020  RooAbsProxy* p = getProxy(i) ;
1021  if (!p) continue ;
1022  Bool_t ret2 = p->changePointer(*newSet,nameChange,kFALSE) ;
1023  allReplaced &= ret2 ;
1024  }
1025 
1026  if (mustReplaceAll && !allReplaced) {
1027  coutE(LinkStateMgmt) << "RooAbsArg::redirectServers(" << GetName()
1028  << "): ERROR, some proxies could not be adjusted" << endl ;
1029  ret = kTRUE ;
1030  }
1031 
1032  // Optional subclass post-processing
1033  for (Int_t i=0 ;i<numCaches() ; i++) {
1034  ret |= getCache(i)->redirectServersHook(*newSet,mustReplaceAll,nameChange,isRecursionStep) ;
1035  }
1036  ret |= redirectServersHook(*newSet,mustReplaceAll,nameChange,isRecursionStep) ;
1037 
1038  if (nameChange) {
1039  delete newSet ;
1040  }
1041 
1042  return ret ;
1043 }
1044 
1045 ////////////////////////////////////////////////////////////////////////////////
1046 /// Find the new server in the specified set that matches the old server.
1047 /// Allow a name change if nameChange is kTRUE, in which case the new
1048 /// server is selected by searching for a new server with an attribute
1049 /// of "ORIGNAME:<oldName>". Return zero if there is not a unique match.
1050 
1052 {
1053  RooAbsArg *newServer = 0;
1054  if (!nameChange) {
1055  newServer = newSet.find(*this) ;
1056  }
1057  else {
1058  // Name changing server redirect:
1059  // use 'ORIGNAME:<oldName>' attribute instead of name of new server
1060  TString nameAttrib("ORIGNAME:") ;
1061  nameAttrib.Append(GetName()) ;
1062 
1063  RooArgSet* tmp = (RooArgSet*) newSet.selectByAttrib(nameAttrib,kTRUE) ;
1064  if(0 != tmp) {
1065 
1066  // Check if any match was found
1067  if (tmp->getSize()==0) {
1068  delete tmp ;
1069  return 0 ;
1070  }
1071 
1072  // Check if match is unique
1073  if(tmp->getSize()>1) {
1074  coutF(LinkStateMgmt) << "RooAbsArg::redirectServers(" << GetName() << "): FATAL Error, " << tmp->getSize() << " servers with "
1075  << nameAttrib << " attribute" << endl ;
1076  tmp->Print("v") ;
1077  assert(0) ;
1078  }
1079 
1080  // use the unique element in the set
1081  newServer= tmp->first();
1082  delete tmp ;
1083  }
1084  }
1085  return newServer;
1086 }
1087 
1088 Bool_t RooAbsArg::recursiveRedirectServers(const RooAbsCollection& newSet, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t recurseInNewSet)
1089 {
1090  // Recursively redirect all servers with new server in collection 'newSet'.
1091  // Substitute our servers with those listed in newSet. If nameChange is false, servers and
1092  // and substitutes are matched by name. If nameChange is true, servers are matched to args
1093  // in newSet that have the 'ORIGNAME:<servername>' attribute set. If mustReplaceAll is set,
1094  // a warning is printed and error status is returned if not all servers could be sucessfully
1095  // substituted. If recurseInNewSet is true, the recursion algorithm also recursion into
1096  // expression trees under the arguments in the new servers (i.e. those in newset)
1097 
1098 
1099  // Cyclic recursion protection
1100  static std::set<const RooAbsArg*> callStack;
1101  {
1102  std::set<const RooAbsArg*>::iterator it = callStack.lower_bound(this);
1103  if (it != callStack.end() && this == *it) {
1104  return kFALSE;
1105  } else {
1106  callStack.insert(it, this);
1107  }
1108  }
1109 
1110  // Do not recurse into newset if not so specified
1111 // if (!recurseInNewSet && newSet.contains(*this)) {
1112 // return kFALSE ;
1113 // }
1114 
1115 
1116  // Apply the redirectServers function recursively on all branch nodes in this argument tree.
1117  Bool_t ret(kFALSE) ;
1118 
1119  cxcoutD(LinkStateMgmt) << "RooAbsArg::recursiveRedirectServers(" << this << "," << GetName() << ") newSet = " << newSet << " mustReplaceAll = "
1120  << (mustReplaceAll?"T":"F") << " nameChange = " << (nameChange?"T":"F") << " recurseInNewSet = " << (recurseInNewSet?"T":"F") << endl ;
1121 
1122  // Do redirect on self (identify operation as recursion step)
1123  ret |= redirectServers(newSet,mustReplaceAll,nameChange,kTRUE) ;
1124 
1125  // Do redirect on servers
1126  RooFIter sIter = serverMIterator() ;
1127  RooAbsArg* server ;
1128  while((server=sIter.next())) {
1129  ret |= server->recursiveRedirectServers(newSet,mustReplaceAll,nameChange,recurseInNewSet) ;
1130  }
1131 
1132  callStack.erase(this);
1133  return ret ;
1134 }
1135 
1136 
1137 
1138 ////////////////////////////////////////////////////////////////////////////////
1139 /// Register an RooArgProxy in the proxy list. This function is called by owned
1140 /// proxies upon creation. After registration, this arg wil forward pointer
1141 /// changes from serverRedirects and updates in cached normalization sets
1142 /// to the proxies immediately after they occur. The proxied argument is
1143 /// also added as value and/or shape server
1144 
1146 {
1147  // Every proxy can be registered only once
1148  if (_proxyList.FindObject(&proxy)) {
1149  coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
1150  << proxy.GetName() << " for arg " << proxy.absArg()->GetName()
1151  << " already registered" << endl ;
1152  return ;
1153  }
1154 
1155 // cout << (void*)this << " " << GetName() << ": registering proxy "
1156 // << (void*)&proxy << " with name " << proxy.name() << " in mode "
1157 // << (proxy.isValueServer()?"V":"-") << (proxy.isShapeServer()?"S":"-") << endl ;
1158 
1159  // Register proxied object as server
1160  if (proxy.absArg()) {
1161  addServer(*proxy.absArg(),proxy.isValueServer(),proxy.isShapeServer()) ;
1162  }
1163 
1164  // Register proxy itself
1165  _proxyList.Add(&proxy) ;
1166 }
1167 
1168 
1169 ////////////////////////////////////////////////////////////////////////////////
1170 /// Remove proxy from proxy list. This functions is called by owned proxies
1171 /// upon their destruction.
1172 
1174 {
1175  _proxyList.Remove(&proxy) ;
1176  _proxyList.Compress() ;
1177 }
1178 
1179 
1180 
1181 ////////////////////////////////////////////////////////////////////////////////
1182 /// Register an RooSetProxy in the proxy list. This function is called by owned
1183 /// proxies upon creation. After registration, this arg wil forward pointer
1184 /// changes from serverRedirects and updates in cached normalization sets
1185 /// to the proxies immediately after they occur.
1186 
1188 {
1189  // Every proxy can be registered only once
1190  if (_proxyList.FindObject(&proxy)) {
1191  coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
1192  << proxy.GetName() << " already registered" << endl ;
1193  return ;
1194  }
1195 
1196  // Register proxy itself
1197  _proxyList.Add(&proxy) ;
1198 }
1199 
1200 
1201 
1202 ////////////////////////////////////////////////////////////////////////////////
1203 /// Remove proxy from proxy list. This functions is called by owned proxies
1204 /// upon their destruction.
1205 
1207 {
1208  _proxyList.Remove(&proxy) ;
1209  _proxyList.Compress() ;
1210 }
1211 
1212 
1213 
1214 ////////////////////////////////////////////////////////////////////////////////
1215 /// Register an RooListProxy in the proxy list. This function is called by owned
1216 /// proxies upon creation. After registration, this arg wil forward pointer
1217 /// changes from serverRedirects and updates in cached normalization sets
1218 /// to the proxies immediately after they occur.
1219 
1221 {
1222  // Every proxy can be registered only once
1223  if (_proxyList.FindObject(&proxy)) {
1224  coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
1225  << proxy.GetName() << " already registered" << endl ;
1226  return ;
1227  }
1228 
1229  // Register proxy itself
1230  Int_t nProxyOld = _proxyList.GetEntries() ;
1231  _proxyList.Add(&proxy) ;
1232  if (_proxyList.GetEntries()!=nProxyOld+1) {
1233  cout << "RooAbsArg::registerProxy(" << GetName() << ") proxy registration failure! nold=" << nProxyOld << " nnew=" << _proxyList.GetEntries() << endl ;
1234  }
1235 }
1236 
1237 
1238 
1239 ////////////////////////////////////////////////////////////////////////////////
1240 /// Remove proxy from proxy list. This functions is called by owned proxies
1241 /// upon their destruction.
1242 
1244 {
1245  _proxyList.Remove(&proxy) ;
1246  _proxyList.Compress() ;
1247 }
1248 
1249 
1250 
1251 ////////////////////////////////////////////////////////////////////////////////
1252 /// Return the nth proxy from the proxy list.
1253 
1255 {
1256  // Cross cast: proxy list returns TObject base pointer, we need
1257  // a RooAbsProxy base pointer. C++ standard requires
1258  // a dynamic_cast for this.
1259  return dynamic_cast<RooAbsProxy*> (_proxyList.At(index)) ;
1260 }
1261 
1262 
1263 
1264 ////////////////////////////////////////////////////////////////////////////////
1265 /// Return the number of registered proxies.
1266 
1268 {
1269  return _proxyList.GetEntries() ;
1270 }
1271 
1272 
1273 
1274 ////////////////////////////////////////////////////////////////////////////////
1275 /// Forward a change in the cached normalization argset
1276 /// to all the registered proxies.
1277 
1279 {
1280  for (int i=0 ; i<numProxies() ; i++) {
1281  RooAbsProxy* p = getProxy(i) ;
1282  if (!p) continue ;
1283  getProxy(i)->changeNormSet(nset) ;
1284  }
1285 }
1286 
1287 
1288 
1289 ////////////////////////////////////////////////////////////////////////////////
1290 /// Overloadable function for derived classes to implement
1291 /// attachment as branch to a TTree
1292 
1294 {
1295  coutE(Contents) << "RooAbsArg::attachToTree(" << GetName()
1296  << "): Cannot be attached to a TTree" << endl ;
1297 }
1298 
1299 
1300 
1301 ////////////////////////////////////////////////////////////////////////////////
1302 /// WVE (08/21/01) Probably obsolete now
1303 
1305 {
1306  return kTRUE ;
1307 }
1308 
1309 
1310 
1311 
1312 ////////////////////////////////////////////////////////////////////////////////
1313 /// Print object name
1314 
1315 void RooAbsArg::printName(ostream& os) const
1316 {
1317  os << GetName() ;
1318 }
1319 
1320 
1321 
1322 ////////////////////////////////////////////////////////////////////////////////
1323 /// Print object title
1324 
1325 void RooAbsArg::printTitle(ostream& os) const
1326 {
1327  os << GetTitle() ;
1328 }
1329 
1330 
1331 
1332 ////////////////////////////////////////////////////////////////////////////////
1333 /// Print object class name
1334 
1335 void RooAbsArg::printClassName(ostream& os) const
1336 {
1337  os << IsA()->GetName() ;
1338 }
1339 
1340 
1341 void RooAbsArg::printAddress(ostream& os) const
1342 {
1343  // Print addrss of this RooAbsArg
1344  os << this ;
1345 }
1346 
1347 
1348 
1349 ////////////////////////////////////////////////////////////////////////////////
1350 /// Print object arguments, ie its proxies
1351 
1352 void RooAbsArg::printArgs(ostream& os) const
1353 {
1354  // Print nothing if there are no dependencies
1355  if (numProxies()==0) return ;
1356 
1357  os << "[ " ;
1358  for (Int_t i=0 ; i<numProxies() ; i++) {
1359  RooAbsProxy* p = getProxy(i) ;
1360  if (p==0) continue ;
1361  if (!TString(p->name()).BeginsWith("!")) {
1362  p->print(os) ;
1363  os << " " ;
1364  }
1365  }
1366  printMetaArgs(os) ;
1367  os << "]" ;
1368 }
1369 
1370 
1371 
1372 ////////////////////////////////////////////////////////////////////////////////
1373 /// Define default contents to print
1374 
1376 {
1377  return kName|kClassName|kValue|kArgs ;
1378 }
1379 
1380 
1381 
1382 ////////////////////////////////////////////////////////////////////////////////
1383 /// Implement multi-line detailed printing
1384 
1385 void RooAbsArg::printMultiline(ostream& os, Int_t /*contents*/, Bool_t /*verbose*/, TString indent) const
1386 {
1387  os << indent << "--- RooAbsArg ---" << endl;
1388  // dirty state flags
1389  os << indent << " Value State: " ;
1390  switch(_operMode) {
1391  case ADirty: os << "FORCED DIRTY" ; break ;
1392  case AClean: os << "FORCED clean" ; break ;
1393  case Auto: os << (isValueDirty() ? "DIRTY":"clean") ; break ;
1394  }
1395  os << endl
1396  << indent << " Shape State: " << (isShapeDirty() ? "DIRTY":"clean") << endl;
1397  // attribute list
1398  os << indent << " Attributes: " ;
1399  printAttribList(os) ;
1400  os << endl ;
1401  // our memory address (for x-referencing with client addresses of other args)
1402  os << indent << " Address: " << (void*)this << endl;
1403  // client list
1404  os << indent << " Clients: " << endl;
1405  RooFIter clientIter= _clientList.fwdIterator();
1406  RooAbsArg* client ;
1407  while ((client=clientIter.next())) {
1408  os << indent << " (" << (void*)client << ","
1409  << (_clientListValue.findArg(client)?"V":"-")
1410  << (_clientListShape.findArg(client)?"S":"-")
1411  << ") " ;
1413  }
1414 
1415  // server list
1416  os << indent << " Servers: " << endl;
1417  RooFIter serverIter= _serverList.fwdIterator();
1418  RooAbsArg* server ;
1419  while ((server=serverIter.next())) {
1420  os << indent << " (" << (void*)server << ","
1421  << (server->_clientListValue.findArg(this)?"V":"-")
1422  << (server->_clientListShape.findArg(this)?"S":"-")
1423  << ") " ;
1425  }
1426 
1427  // proxy list
1428  os << indent << " Proxies: " << endl ;
1429  for (int i=0 ; i<numProxies() ; i++) {
1430  RooAbsProxy* proxy=getProxy(i) ;
1431  if (!proxy) continue ;
1432  if (proxy->IsA()->InheritsFrom(RooArgProxy::Class())) {
1433  os << indent << " " << proxy->name() << " -> " ;
1434  RooAbsArg* parg = ((RooArgProxy*)proxy)->absArg() ;
1435  if (parg) {
1436  parg->printStream(os,kName,kSingleLine) ;
1437  } else {
1438  os << " (empty)" << endl ; ;
1439  }
1440  } else {
1441  os << indent << " " << proxy->name() << " -> " ;
1442  os << endl ;
1443  TString moreIndent(indent) ;
1444  moreIndent.Append(" ") ;
1445  ((RooSetProxy*)proxy)->printStream(os,kName,kStandard,moreIndent.Data()) ;
1446  }
1447  }
1448 }
1449 
1450 
1451 ////////////////////////////////////////////////////////////////////////////////
1452 /// Print object tree structure
1453 
1454 void RooAbsArg::printTree(ostream& os, TString /*indent*/) const
1455 {
1456  const_cast<RooAbsArg*>(this)->printCompactTree(os) ;
1457 }
1458 
1459 
1460 ////////////////////////////////////////////////////////////////////////////////
1461 /// Ostream operator
1462 
1463 ostream& operator<<(ostream& os, RooAbsArg &arg)
1464 {
1465  arg.writeToStream(os,kTRUE) ;
1466  return os ;
1467 }
1468 
1469 ////////////////////////////////////////////////////////////////////////////////
1470 /// Istream operator
1471 
1472 istream& operator>>(istream& is, RooAbsArg &arg)
1473 {
1474  arg.readFromStream(is,kTRUE,kFALSE) ;
1475  return is ;
1476 }
1477 
1478 ////////////////////////////////////////////////////////////////////////////////
1479 /// Print the attribute list
1480 
1481 void RooAbsArg::printAttribList(ostream& os) const
1482 {
1483  set<string>::const_iterator iter = _boolAttrib.begin() ;
1484  Bool_t first(kTRUE) ;
1485  while (iter != _boolAttrib.end()) {
1486  os << (first?" [":",") << *iter ;
1487  first=kFALSE ;
1488  ++iter ;
1489  }
1490  if (!first) os << "] " ;
1491 }
1492 
1493 ////////////////////////////////////////////////////////////////////////////////
1494 /// Replace server nodes with names matching the dataset variable names
1495 /// with those data set variables, making this PDF directly dependent on the dataset
1496 
1498 {
1499  const RooArgSet* set = data.get() ;
1501  branchNodeServerList(&branches,0,kTRUE) ;
1502 
1503  RooFIter iter = branches.fwdIterator() ;
1504  RooAbsArg* branch ;
1505  while((branch=iter.next())) {
1506  branch->redirectServers(*set,kFALSE,kFALSE) ;
1507  }
1508 }
1509 
1510 
1511 
1512 ////////////////////////////////////////////////////////////////////////////////
1513 /// Replace server nodes with names matching the dataset variable names
1514 /// with those data set variables, making this PDF directly dependent on the dataset
1515 
1517 {
1518  const RooArgSet* set = dstore.get() ;
1520  branchNodeServerList(&branches,0,kTRUE) ;
1521 
1522  RooFIter iter = branches.fwdIterator() ;
1523  RooAbsArg* branch ;
1524  while((branch=iter.next())) {
1525  branch->redirectServers(*set,kFALSE,kFALSE) ;
1526  }
1527 }
1528 
1529 
1530 
1531 ////////////////////////////////////////////////////////////////////////////////
1532 /// Utility function used by TCollection::Sort to compare contained TObjects
1533 /// We implement comparison by name, resulting in alphabetical sorting by object name.
1534 
1535 Int_t RooAbsArg::Compare(const TObject* other) const
1536 {
1537  return strcmp(GetName(),other->GetName()) ;
1538 }
1539 
1540 
1541 
1542 ////////////////////////////////////////////////////////////////////////////////
1543 /// Print information about current value dirty state information.
1544 /// If depth flag is true, information is recursively printed for
1545 /// all nodes in this arg tree.
1546 
1548 {
1549  if (depth) {
1550 
1551  RooArgSet branchList ;
1552  branchNodeServerList(&branchList) ;
1553  RooFIter bIter = branchList.fwdIterator() ;
1554  RooAbsArg* branch ;
1555  while((branch=bIter.next())) {
1556  branch->printDirty(kFALSE) ;
1557  }
1558 
1559  } else {
1560  cout << GetName() << " : " ;
1561  switch (_operMode) {
1562  case AClean: cout << "FORCED clean" ; break ;
1563  case ADirty: cout << "FORCED DIRTY" ; break ;
1564  case Auto: cout << "Auto " << (isValueDirty()?"DIRTY":"clean") ;
1565  }
1566  cout << endl ;
1567  }
1568 }
1569 
1570 
1571 ////////////////////////////////////////////////////////////////////////////////
1572 /// Activate cache mode optimization with given definition of observables.
1573 /// The cache operation mode of all objects in the expression tree will
1574 /// modified such that all nodes that depend directly or indirectly on
1575 /// any of the listed observables will be set to ADirty, as they are
1576 /// expected to change every time. This save change tracking overhead for
1577 /// nodes that are a priori known to change every time
1578 
1579 void RooAbsArg::optimizeCacheMode(const RooArgSet& observables)
1580 {
1581  RooLinkedList proc;
1582  RooArgSet opt ;
1583  optimizeCacheMode(observables,opt,proc) ;
1584 
1585  coutI(Optimization) << "RooAbsArg::optimizeCacheMode(" << GetName() << ") nodes " << opt << " depend on observables, "
1586  << "changing cache operation mode from change tracking to unconditional evaluation" << endl ;
1587 }
1588 
1589 
1590 ////////////////////////////////////////////////////////////////////////////////
1591 /// Activate cache mode optimization with given definition of observables.
1592 /// The cache operation mode of all objects in the expression tree will
1593 /// modified such that all nodes that depend directly or indirectly on
1594 /// any of the listed observables will be set to ADirty, as they are
1595 /// expected to change every time. This save change tracking overhead for
1596 /// nodes that are a priori known to change every time
1597 
1598 void RooAbsArg::optimizeCacheMode(const RooArgSet& observables, RooArgSet& optimizedNodes, RooLinkedList& processedNodes)
1599 {
1600  // Optimization applies only to branch nodes, not to leaf nodes
1601  if (!isDerived()) {
1602  return ;
1603  }
1604 
1605 
1606  // Terminate call if this node was already processed (tree structure may be cyclical)
1607  if (processedNodes.findArg(this)) {
1608  return ;
1609  } else {
1610  processedNodes.Add(this) ;
1611  }
1612 
1613  // Set cache mode operator to 'AlwaysDirty' if we depend on any of the given observables
1614  if (dependsOnValue(observables)) {
1615 
1616  if (dynamic_cast<RooRealIntegral*>(this)) {
1617  cxcoutI(Integration) << "RooAbsArg::optimizeCacheMode(" << GetName() << ") integral depends on value of one or more observables and will be evaluated for every event" << endl ;
1618  }
1619  optimizedNodes.add(*this,kTRUE) ;
1620  if (operMode()==AClean) {
1621  } else {
1622  setOperMode(ADirty,kTRUE) ; // WVE propagate flag recursively to top of tree
1623  }
1624  } else {
1625  }
1626  // Process any RooAbsArgs contained in any of the caches of this object
1627  for (Int_t i=0 ;i<numCaches() ; i++) {
1628  getCache(i)->optimizeCacheMode(observables,optimizedNodes,processedNodes) ;
1629  }
1630 
1631  // Forward calls to all servers
1632  RooFIter sIter = serverMIterator() ;
1633  RooAbsArg* server ;
1634  while((server=sIter.next())) {
1635  server->optimizeCacheMode(observables,optimizedNodes,processedNodes) ;
1636  }
1637 
1638 }
1639 
1640 ////////////////////////////////////////////////////////////////////////////////
1641 /// Find branch nodes with all-constant parameters, and add them to the list of
1642 /// nodes that can be cached with a dataset in a test statistic calculation
1643 
1645 {
1646  RooLinkedList proc ;
1647  Bool_t ret = findConstantNodes(observables,cacheList,proc) ;
1648 
1649  // If node can be optimized and hasn't been identified yet, add it to the list
1650  coutI(Optimization) << "RooAbsArg::findConstantNodes(" << GetName() << "): components "
1651  << cacheList << " depend exclusively on constant parameters and will be precalculated and cached" << endl ;
1652 
1653  return ret ;
1654 }
1655 
1656 
1657 
1658 ////////////////////////////////////////////////////////////////////////////////
1659 /// Find branch nodes with all-constant parameters, and add them to the list of
1660 /// nodes that can be cached with a dataset in a test statistic calculation
1661 
1662 Bool_t RooAbsArg::findConstantNodes(const RooArgSet& observables, RooArgSet& cacheList, RooLinkedList& processedNodes)
1663 {
1664  // Caching only applies to branch nodes
1665  if (!isDerived()) {
1666  return kFALSE;
1667  }
1668 
1669  // Terminate call if this node was already processed (tree structure may be cyclical)
1670  if (processedNodes.findArg(this)) {
1671  return kFALSE ;
1672  } else {
1673  processedNodes.Add(this) ;
1674  }
1675 
1676  // Check if node depends on any non-constant parameter
1677  Bool_t canOpt(kTRUE) ;
1678  RooArgSet* paramSet = getParameters(observables) ;
1679  RooFIter iter = paramSet->fwdIterator() ;
1680  RooAbsArg* param ;
1681  while((param = iter.next())) {
1682  if (!param->isConstant()) {
1683  canOpt=kFALSE ;
1684  break ;
1685  }
1686  }
1687  delete paramSet ;
1688 
1689 
1690  if (getAttribute("NeverConstant")) {
1691  canOpt = kFALSE ;
1692  }
1693 
1694  if (canOpt) {
1695  setAttribute("ConstantExpression") ;
1696  }
1697 
1698  // If yes, list node eligible for caching, if not test nodes one level down
1699  if (canOpt||getAttribute("CacheAndTrack")) {
1700 
1701  if (!cacheList.find(*this) && dependsOnValue(observables) && !observables.find(*this) ) {
1702 
1703  // Add to cache list
1704  cxcoutD(Optimization) << "RooAbsArg::findConstantNodes(" << GetName() << ") adding self to list of constant nodes" << endl ;
1705 
1706  if (canOpt) setAttribute("ConstantExpressionCached") ;
1707  cacheList.add(*this,kFALSE) ;
1708  }
1709  }
1710 
1711  if (!canOpt) {
1712 
1713  // If not, see if next level down can be cached
1714  RooFIter sIter = serverMIterator() ;
1715  RooAbsArg* server ;
1716  while((server=sIter.next())) {
1717  if (server->isDerived()) {
1718  server->findConstantNodes(observables,cacheList,processedNodes) ;
1719  }
1720  }
1721  }
1722 
1723  // Forward call to all cached contained in current object
1724  for (Int_t i=0 ;i<numCaches() ; i++) {
1725  getCache(i)->findConstantNodes(observables,cacheList,processedNodes) ;
1726  }
1727 
1728  return kFALSE ;
1729 }
1730 
1731 
1732 
1733 
1734 ////////////////////////////////////////////////////////////////////////////////
1735 /// Interface function signaling a request to perform constant term
1736 /// optimization. This default implementation takes no action other than to
1737 /// forward the calls to all servers
1738 
1740 {
1741  RooFIter sIter = serverMIterator() ;
1742  RooAbsArg* server ;
1743  while((server=sIter.next())) {
1744  server->constOptimizeTestStatistic(opcode,doAlsoTrackingOpt) ;
1745  }
1746 }
1747 
1748 
1749 ////////////////////////////////////////////////////////////////////////////////
1750 /// Change cache operation mode to given mode. If recurseAdirty
1751 /// is true, then a mode change to AlwaysDirty will automatically
1752 /// be propagated recursively to all client nodes
1753 
1754 void RooAbsArg::setOperMode(OperMode mode, Bool_t recurseADirty)
1755 {
1756  // Prevent recursion loops
1757  if (mode==_operMode) return ;
1758 
1759  _operMode = mode ;
1760  _fast = ((mode==AClean) || dynamic_cast<RooRealVar*>(this)!=0 || dynamic_cast<RooConstVar*>(this)!=0 ) ;
1761  for (Int_t i=0 ;i<numCaches() ; i++) {
1762  getCache(i)->operModeHook() ;
1763  }
1764  operModeHook() ;
1765 
1766  // Propagate to all clients
1767  if (mode==ADirty && recurseADirty) {
1768  RooFIter iter = valueClientMIterator() ;
1769  RooAbsArg* client ;
1770  while((client=iter.next())) {
1771  client->setOperMode(mode) ;
1772  }
1773  }
1774 }
1775 
1776 
1777 ////////////////////////////////////////////////////////////////////////////////
1778 /// Print tree structure of expression tree on stdout, or to file if filename is specified.
1779 /// If namePat is not "*", only nodes with names matching the pattern will be printed.
1780 /// The client argument is used in recursive calls to properly display the value or shape nature
1781 /// of the client-server links. It should be zero in calls initiated by users.
1782 
1783 void RooAbsArg::printCompactTree(const char* indent, const char* filename, const char* namePat, RooAbsArg* client)
1784 {
1785  if (filename) {
1786  ofstream ofs(filename) ;
1787  printCompactTree(ofs,indent,namePat,client) ;
1788  } else {
1789  printCompactTree(cout,indent,namePat,client) ;
1790  }
1791 }
1792 
1793 
1794 ////////////////////////////////////////////////////////////////////////////////
1795 /// Print tree structure of expression tree on given ostream.
1796 /// If namePat is not "*", only nodes with names matching the pattern will be printed.
1797 /// The client argument is used in recursive calls to properly display the value or shape nature
1798 /// of the client-server links. It should be zero in calls initiated by users.
1799 
1800 void RooAbsArg::printCompactTree(ostream& os, const char* indent, const char* namePat, RooAbsArg* client)
1801 {
1802  if ( !namePat || TString(GetName()).Contains(namePat)) {
1803  os << indent << this ;
1804  if (client) {
1805  os << "/" ;
1806  if (isValueServer(*client)) os << "V" ; else os << "-" ;
1807  if (isShapeServer(*client)) os << "S" ; else os << "-" ;
1808  }
1809  os << " " ;
1810 
1811  os << IsA()->GetName() << "::" << GetName() << " = " ;
1812  printValue(os) ;
1813 
1814  if (_serverList.GetSize()>0) {
1815  switch(operMode()) {
1816  case Auto: os << " [Auto," << (isValueDirty()?"Dirty":"Clean") << "] " ; break ;
1817  case AClean: os << " [ACLEAN] " ; break ;
1818  case ADirty: os << " [ADIRTY] " ; break ;
1819  }
1820  }
1821  os << endl ;
1822 
1823  for (Int_t i=0 ;i<numCaches() ; i++) {
1824  getCache(i)->printCompactTreeHook(os,indent) ;
1825  }
1826  printCompactTreeHook(os,indent) ;
1827  }
1828 
1829  TString indent2(indent) ;
1830  indent2 += " " ;
1831  RooFIter iter = serverMIterator() ;
1832  RooAbsArg* arg ;
1833  while((arg=iter.next())) {
1834  arg->printCompactTree(os,indent2,namePat,this) ;
1835  }
1836 }
1837 
1838 
1839 ////////////////////////////////////////////////////////////////////////////////
1840 /// Print tree structure of expression tree on given ostream, only branch nodes are printed.
1841 /// Lead nodes (variables) will not be shown
1842 ///
1843 /// If namePat is not "*", only nodes with names matching the pattern will be printed.
1844 
1845 void RooAbsArg::printComponentTree(const char* indent, const char* namePat, Int_t nLevel)
1846 {
1847  if (nLevel==0) return ;
1848  if (isFundamental()) return ;
1849  RooResolutionModel* rmodel = dynamic_cast<RooResolutionModel*>(this) ;
1850  if (rmodel && rmodel->isConvolved()) return ;
1851  if (InheritsFrom("RooConstVar")) return ;
1852 
1853  if ( !namePat || TString(GetName()).Contains(namePat)) {
1854  cout << indent ;
1855  Print() ;
1856  }
1857 
1858  TString indent2(indent) ;
1859  indent2 += " " ;
1860  RooFIter iter = serverMIterator() ;
1861  RooAbsArg* arg ;
1862  while((arg=iter.next())) {
1863  arg->printComponentTree(indent2.Data(),namePat,nLevel-1) ;
1864  }
1865 }
1866 
1867 
1868 ////////////////////////////////////////////////////////////////////////////////
1869 /// Construct a mangled name from the actual name that
1870 /// is free of any math symbols that might be interpreted by TTree
1871 
1873 {
1874  // Check for optional alternate name of branch for this argument
1875  TString rawBranchName = GetName() ;
1876  if (getStringAttribute("BranchName")) {
1877  rawBranchName = getStringAttribute("BranchName") ;
1878  }
1879 
1880  TString cleanName(rawBranchName) ;
1881  cleanName.ReplaceAll("/","D") ;
1882  cleanName.ReplaceAll("-","M") ;
1883  cleanName.ReplaceAll("+","P") ;
1884  cleanName.ReplaceAll("*","X") ;
1885  cleanName.ReplaceAll("[","L") ;
1886  cleanName.ReplaceAll("]","R") ;
1887  cleanName.ReplaceAll("(","L") ;
1888  cleanName.ReplaceAll(")","R") ;
1889  cleanName.ReplaceAll("{","L") ;
1890  cleanName.ReplaceAll("}","R") ;
1891 
1892  if (cleanName.Length()<=60) return cleanName ;
1893 
1894  // Name is too long, truncate and include CRC32 checksum of full name in clean name
1895  static char buf[1024] ;
1896  strlcpy(buf,cleanName.Data(),1024) ;
1897  snprintf(buf+46,1024-46,"_CRC%08x",crc32(cleanName.Data())) ;
1898 
1899  return TString(buf) ;
1900 }
1901 
1902 
1903 
1904 
1905 
1907 {
1908  // Calculate crc32 checksum on given string
1909  unsigned long sz = strlen(data);
1910  switch (strlen(data)) {
1911  case 0:
1912  return 0;
1913  case 1:
1914  return data[0];
1915  case 2:
1916  return (data[0] << 8) | data[1];
1917  case 3:
1918  return (data[0] << 16) | (data[1] << 8) | data[2];
1919  case 4:
1920  return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
1921  default:
1922  return crc32(data + 4, sz - 4, (data[0] << 24) | (data[1] << 16) |
1923  (data[2] << 8) | data[3]);
1924  }
1925 }
1926 
1927 
1929 {
1930  // update CRC32 with new data
1931 
1932  // use precomputed table, rather than computing it on the fly
1933  static const UInt_t crctab[256] = { 0x00000000,
1934  0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
1935  0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
1936  0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
1937  0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
1938  0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
1939  0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
1940  0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
1941  0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
1942  0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
1943  0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
1944  0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
1945  0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
1946  0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
1947  0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
1948  0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
1949  0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
1950  0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
1951  0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
1952  0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
1953  0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
1954  0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
1955  0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
1956  0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
1957  0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
1958  0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
1959  0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
1960  0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
1961  0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
1962  0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
1963  0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
1964  0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
1965  0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
1966  0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
1967  0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
1968  0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
1969  0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
1970  0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
1971  0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
1972  0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
1973  0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
1974  0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
1975  0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
1976  0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
1977  0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
1978  0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
1979  0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
1980  0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
1981  0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
1982  0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
1983  0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
1984  0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
1985  };
1986 
1987  crc = ~crc;
1988  while (sz--) crc = (crc << 8) ^ UInt_t(*data++) ^ crctab[crc >> 24];
1989 
1990  return ~crc;
1991 }
1992 
1994 {
1995  // calculate 32 bit FNV1A hash of string
1996  return fnv1a32(data, strlen(data));
1997 }
1998 
2000 {
2001  // update 32 bit FNV1A hash
2002  const UInt_t fnv1a32mult = 16777619u;
2003  while (sz--) {
2004  hash ^= *data++;
2005  hash *= fnv1a32mult;
2006  }
2007  return hash;
2008 }
2009 
2011 {
2012  // calculate 64 bit FNV1A hash of string
2013  return fnv1a64(data, strlen(data));
2014 }
2015 
2017 {
2018  // update 64 bit FNV1A hash
2019  const ULong64_t fnv1a64mult = (ULong64_t(1) << 40) | ULong64_t(435);
2020  while (sz--) {
2021  hash ^= *data++;
2022  hash *= fnv1a64mult;
2023  }
2024  return hash;
2025 }
2026 
2027 ////////////////////////////////////////////////////////////////////////////////
2028 /// Hook function interface for object to insert additional information
2029 /// when printed in the context of a tree structure. This default
2030 /// implementation prints nothing
2031 
2032 void RooAbsArg::printCompactTreeHook(ostream&, const char *)
2033 {
2034 }
2035 
2036 
2037 ////////////////////////////////////////////////////////////////////////////////
2038 /// Register RooAbsCache with this object. This function is called
2039 /// by RooAbsCache constructors for objects that are a datamember
2040 /// of this RooAbsArg. By registering itself the RooAbsArg is aware
2041 /// of all its cache data members and will forward server change
2042 /// and cache mode change calls to the cache objects, which in turn
2043 /// can forward them their contents
2044 
2046 {
2047  _cacheList.push_back(&cache) ;
2048 }
2049 
2050 
2051 ////////////////////////////////////////////////////////////////////////////////
2052 /// Unregister a RooAbsCache. Called from the RooAbsCache destructor
2053 
2055 {
2056  _cacheList.erase(std::remove(_cacheList.begin(), _cacheList.end(), &cache),
2057  _cacheList.end());
2058 }
2059 
2060 
2061 ////////////////////////////////////////////////////////////////////////////////
2062 /// Return number of registered caches
2063 
2065 {
2066  return _cacheList.size() ;
2067 }
2068 
2069 
2070 ////////////////////////////////////////////////////////////////////////////////
2071 /// Return registered cache object by index
2072 
2074 {
2075  return _cacheList[index] ;
2076 }
2077 
2078 
2079 ////////////////////////////////////////////////////////////////////////////////
2080 /// Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
2081 
2082 RooArgSet* RooAbsArg::getVariables(Bool_t stripDisconnected) const
2083 {
2084  return getParameters(RooArgSet(),stripDisconnected) ;
2085 }
2086 
2087 
2088 ////////////////////////////////////////////////////////////////////////////////
2089 /// Return ancestors in cloning chain of this RooAbsArg. NOTE: Returned pointers
2090 /// are not guaranteed to be 'live', so do not dereference without proper caution
2091 
2093 {
2094  RooLinkedList retVal ;
2095 
2096  set<string>::const_iterator iter= _boolAttrib.begin() ;
2097  while(iter != _boolAttrib.end()) {
2098  if (TString(*iter).BeginsWith("CloneOf(")) {
2099  char buf[128] ;
2100  strlcpy(buf,iter->c_str(),128) ;
2101  strtok(buf,"(") ;
2102  char* ptrToken = strtok(0,")") ;
2103  RooAbsArg* ptr = (RooAbsArg*) strtol(ptrToken,0,16) ;
2104  retVal.Add(ptr) ;
2105  }
2106  }
2107 
2108  return retVal ;
2109 }
2110 
2111 
2112 ////////////////////////////////////////////////////////////////////////////////
2113 /// Create a GraphViz .dot file visualizing the expression tree headed by
2114 /// this RooAbsArg object. Use the GraphViz tool suite to make e.g. a gif
2115 /// or ps file from the .dot file
2116 ///
2117 /// Based on concept developed by Kyle Cranmer
2118 
2119 void RooAbsArg::graphVizTree(const char* fileName, const char* delimiter, bool useTitle, bool useLatex)
2120 {
2121  ofstream ofs(fileName) ;
2122  if (!ofs) {
2123  coutE(InputArguments) << "RooAbsArg::graphVizTree() ERROR: Cannot open graphViz output file with name " << fileName << endl ;
2124  return ;
2125  }
2126  graphVizTree(ofs, delimiter, useTitle, useLatex) ;
2127 }
2128 
2129 ////////////////////////////////////////////////////////////////////////////////
2130 /// Write the GraphViz representation of the expression tree headed by
2131 /// this RooAbsArg object to the given ostream.
2132 ///
2133 /// Based on concept developed by Kyle Cranmer
2134 
2135 void RooAbsArg::graphVizTree(ostream& os, const char* delimiter, bool useTitle, bool useLatex)
2136 {
2137  if (!os) {
2138  coutE(InputArguments) << "RooAbsArg::graphVizTree() ERROR: output stream provided as input argument is in invalid state" << endl ;
2139  }
2140 
2141  // Write header
2142  os << "digraph " << GetName() << "{" << endl ;
2143 
2144  // First list all the tree nodes
2145  RooArgSet nodeSet ;
2146  treeNodeServerList(&nodeSet) ;
2147  RooFIter iter = nodeSet.fwdIterator() ;
2148  RooAbsArg* node ;
2149 
2150  // iterate over nodes
2151  while((node=iter.next())) {
2152  string nodeName = node->GetName();
2153  string nodeTitle = node->GetTitle();
2154  string nodeLabel = (useTitle && !nodeTitle.empty()) ? nodeTitle : nodeName;
2155 
2156  // if using latex, replace ROOT's # with normal latex backslash
2157  string::size_type position = nodeLabel.find("#") ;
2158  while(useLatex && position!=nodeLabel.npos){
2159  nodeLabel.replace(position, 1, "\\");
2160  }
2161 
2162  string typeFormat = "\\texttt{";
2163  string nodeType = (useLatex) ? typeFormat+node->IsA()->GetName()+"}" : node->IsA()->GetName();
2164 
2165  os << "\"" << nodeName << "\" [ color=" << (node->isFundamental()?"blue":"red")
2166  << ", label=\"" << nodeType << delimiter << nodeLabel << "\"];" << endl ;
2167 
2168  }
2169 
2170  // Get set of all server links
2171  set<pair<RooAbsArg*,RooAbsArg*> > links ;
2172  graphVizAddConnections(links) ;
2173 
2174  // And write them out
2175  set<pair<RooAbsArg*,RooAbsArg*> >::iterator liter = links.begin() ;
2176  for( ; liter != links.end() ; ++liter ) {
2177  os << "\"" << liter->first->GetName() << "\" -> \"" << liter->second->GetName() << "\";" << endl ;
2178  }
2179 
2180  // Write trailer
2181  os << "}" << endl ;
2182 
2183 }
2184 
2185 ////////////////////////////////////////////////////////////////////////////////
2186 /// Utility function that inserts all point-to-point client-server connections
2187 /// between any two RooAbsArgs in the expression tree headed by this object
2188 /// in the linkSet argument.
2189 
2190 void RooAbsArg::graphVizAddConnections(set<pair<RooAbsArg*,RooAbsArg*> >& linkSet)
2191 {
2192  RooFIter sIter = serverMIterator() ;
2193  RooAbsArg* server ;
2194  while((server=sIter.next())) {
2195  linkSet.insert(make_pair(this,server)) ;
2196  server->graphVizAddConnections(linkSet) ;
2197  }
2198 }
2199 
2200 
2201 
2202 // //_____________________________________________________________________________
2203 // TGraphStruct* RooAbsArg::graph(Bool_t useFactoryTag, Double_t textSize)
2204 // {
2205 // // Return a TGraphStruct object filled with the tree structure of the pdf object
2206 
2207 // TGraphStruct* theGraph = new TGraphStruct() ;
2208 
2209 // // First list all the tree nodes
2210 // RooArgSet nodeSet ;
2211 // treeNodeServerList(&nodeSet) ;
2212 // TIterator* iter = nodeSet.createIterator() ;
2213 // RooAbsArg* node ;
2214 
2215 
2216 // // iterate over nodes
2217 // while((node=(RooAbsArg*)iter->Next())) {
2218 
2219 // // Skip node that represent numeric constants
2220 // if (node->IsA()->InheritsFrom(RooConstVar::Class())) continue ;
2221 
2222 // string nodeName ;
2223 // if (useFactoryTag && node->getStringAttribute("factory_tag")) {
2224 // nodeName = node->getStringAttribute("factory_tag") ;
2225 // } else {
2226 // if (node->isFundamental()) {
2227 // nodeName = node->GetName();
2228 // } else {
2229 // ostringstream oss ;
2230 // node->printStream(oss,(node->defaultPrintContents(0)&(~kValue)),node->defaultPrintStyle(0)) ;
2231 // nodeName= oss.str() ;
2232 // // nodeName = Form("%s::%s",node->IsA()->GetName(),node->GetName());
2233 
2234 // }
2235 // }
2236 // if (strncmp(nodeName.c_str(),"Roo",3)==0) {
2237 // nodeName = string(nodeName.c_str()+3) ;
2238 // }
2239 // node->setStringAttribute("graph_name",nodeName.c_str()) ;
2240 
2241 // TGraphNode* gnode = theGraph->AddNode(nodeName.c_str(),nodeName.c_str()) ;
2242 // gnode->SetLineWidth(2) ;
2243 // gnode->SetTextColor(node->isFundamental()?kBlue:kRed) ;
2244 // gnode->SetTextSize(textSize) ;
2245 // }
2246 // delete iter ;
2247 
2248 // // Get set of all server links
2249 // set<pair<RooAbsArg*,RooAbsArg*> > links ;
2250 // graphVizAddConnections(links) ;
2251 
2252 // // And insert them into the graph
2253 // set<pair<RooAbsArg*,RooAbsArg*> >::iterator liter = links.begin() ;
2254 // for( ; liter != links.end() ; ++liter ) {
2255 
2256 // TGraphNode* n1 = (TGraphNode*)theGraph->GetListOfNodes()->FindObject(liter->first->getStringAttribute("graph_name")) ;
2257 // TGraphNode* n2 = (TGraphNode*)theGraph->GetListOfNodes()->FindObject(liter->second->getStringAttribute("graph_name")) ;
2258 // if (n1 && n2) {
2259 // TGraphEdge* edge = theGraph->AddEdge(n1,n2) ;
2260 // edge->SetLineWidth(2) ;
2261 // }
2262 // }
2263 
2264 // return theGraph ;
2265 // }
2266 
2267 
2268 
2269 // //_____________________________________________________________________________
2270 // Bool_t RooAbsArg::inhibitDirty()
2271 // {
2272 // // Return current status of the inhibitDirty global flag. If true
2273 // // no dirty state change tracking occurs and all caches are considered
2274 // // to be always dirty.
2275 // return _inhibitDirty ;
2276 // }
2277 
2278 
2279 ////////////////////////////////////////////////////////////////////////////////
2280 /// Take ownership of the contents of 'comps'
2281 
2283 {
2284  if (!_ownedComponents) {
2285  _ownedComponents = new RooArgSet("owned components") ;
2286  }
2287  return _ownedComponents->addOwned(comps) ;
2288 }
2289 
2290 
2291 
2292 ////////////////////////////////////////////////////////////////////////////////
2293 /// Clone tree expression of objects. All tree nodes will be owned by
2294 /// the head node return by cloneTree()
2295 
2296 RooAbsArg* RooAbsArg::cloneTree(const char* newname) const
2297 {
2298  // Clone tree using snapshot
2299  RooArgSet* clonedNodes = (RooArgSet*) RooArgSet(*this).snapshot(kTRUE) ;
2300 
2301  // Find the head node in the cloneSet
2302  RooAbsArg* head = clonedNodes->find(*this) ;
2303 
2304  // Remove the head node from the cloneSet
2305  // To release it from the set ownership
2306  clonedNodes->remove(*head) ;
2307 
2308  // Add the set as owned component of the head
2309  head->addOwnedComponents(*clonedNodes) ;
2310 
2311  // Delete intermediate container
2312  clonedNodes->releaseOwnership() ;
2313  delete clonedNodes ;
2314 
2315  // Adjust name of head node if requested
2316  if (newname) {
2317  head->TNamed::SetName(newname) ;
2318  head->_namePtr = (TNamed*) RooNameReg::instance().constPtr(newname) ;
2319  }
2320 
2321  // Return the head
2322  return head ;
2323 }
2324 
2325 
2326 
2327 ////////////////////////////////////////////////////////////////////////////////
2328 
2330 {
2331  if (dynamic_cast<RooTreeDataStore*>(&store)) {
2332  attachToTree(((RooTreeDataStore&)store).tree()) ;
2333  } else if (dynamic_cast<RooVectorDataStore*>(&store)) {
2335  }
2336 }
2337 
2338 
2339 
2340 ////////////////////////////////////////////////////////////////////////////////
2341 
2343 {
2344  if (_eocache) {
2345  return *_eocache ;
2346  } else {
2348  }
2349 }
2350 
2351 
2352 ////////////////////////////////////////////////////////////////////////////////
2353 
2355 {
2356  string suffix ;
2357 
2359  branchNodeServerList(&branches) ;
2360  RooFIter iter = branches.fwdIterator();
2361  RooAbsArg* arg ;
2362  while((arg=iter.next())) {
2363  const char* tmp = arg->cacheUniqueSuffix() ;
2364  if (tmp) suffix += tmp ;
2365  }
2366  return Form("%s",suffix.c_str()) ;
2367 }
2368 
2369 
2370 ////////////////////////////////////////////////////////////////////////////////
2371 
2373 {
2375  branchNodeServerList(&branches) ;
2376  RooFIter iter = branches.fwdIterator() ;
2377  RooAbsArg* arg ;
2378  while((arg=iter.next())) {
2379 // cout << "wiring caches on node " << arg->GetName() << endl ;
2380  for (deque<RooAbsCache*>::iterator iter2 = arg->_cacheList.begin() ; iter2 != arg->_cacheList.end() ; ++iter2) {
2381  (*iter2)->wireCache() ;
2382  }
2383  }
2384 }
2385 
2386 
2387 
2388 ////////////////////////////////////////////////////////////////////////////////
2389 
2390 void RooAbsArg::SetName(const char* name)
2391 {
2392  TNamed::SetName(name) ;
2393  TNamed* newPtr = (TNamed*) RooNameReg::instance().constPtr(GetName()) ;
2394  if (newPtr != _namePtr) {
2395  //cout << "Rename '" << _namePtr->GetName() << "' to '" << name << "' (set flag in new name)" << endl;
2396  _namePtr = newPtr;
2398  }
2399 }
2400 
2401 
2402 
2403 
2404 ////////////////////////////////////////////////////////////////////////////////
2405 
2406 void RooAbsArg::SetNameTitle(const char *name, const char *title)
2407 {
2408  TNamed::SetNameTitle(name,title) ;
2409  TNamed* newPtr = (TNamed*) RooNameReg::instance().constPtr(GetName()) ;
2410  if (newPtr != _namePtr) {
2411  //cout << "Rename '" << _namePtr->GetName() << "' to '" << name << "' (set flag in new name)" << endl;
2412  _namePtr = newPtr;
2414  }
2415 }
2416 
2417 
2418 ////////////////////////////////////////////////////////////////////////////////
2419 /// Stream an object of class RooAbsArg.
2420 
2421 void RooAbsArg::Streamer(TBuffer &R__b)
2422 {
2423  if (R__b.IsReading()) {
2424  _ioReadStack.push(this) ;
2425  R__b.ReadClassBuffer(RooAbsArg::Class(),this);
2426  _ioReadStack.pop() ;
2428  _isConstant = getAttribute("Constant") ;
2429  } else {
2430  R__b.WriteClassBuffer(RooAbsArg::Class(),this);
2431  }
2432 }
2433 
2434 ////////////////////////////////////////////////////////////////////////////////
2435 /// Method called by workspace container to finalize schema evolution issues
2436 /// that cannot be handled in a single ioStreamer pass.
2437 ///
2438 /// A second pass is typically needed when evolving data member of RooAbsArg-derived
2439 /// classes that are container classes with references to other members, which may
2440 /// not yet be 'live' in the first ioStreamer() evolution pass.
2441 ///
2442 /// Classes may overload this function, but must call the base method in the
2443 /// overloaded call to ensure base evolution is handled properly
2444 
2446 {
2447 
2448  // Handling of v5-v6 migration (TRefArray _proxyList --> RooRefArray _proxyList)
2449  map<RooAbsArg*,TRefArray*>::iterator iter = _ioEvoList.find(this) ;
2450  if (iter != _ioEvoList.end()) {
2451 
2452  // Transfer contents of saved TRefArray to RooRefArray now
2453  for (int i=0 ; i < iter->second->GetEntries() ; i++) {
2454  _proxyList.Add(iter->second->At(i)) ;
2455  }
2456  // Delete TRefArray and remove from list
2457  delete iter->second ;
2458  _ioEvoList.erase(iter) ;
2459  }
2460 }
2461 
2462 
2463 
2464 
2465 ////////////////////////////////////////////////////////////////////////////////
2466 /// Method called by workspace container to finalize schema evolution issues
2467 /// that cannot be handled in a single ioStreamer pass. This static finalize method
2468 /// is called after ioStreamerPass2() is called on each directly listed object
2469 /// in the workspace. It's purpose is to complete schema evolution of any
2470 /// objects in the workspace that are not directly listed as content elements
2471 /// (e.g. analytical convolution tokens )
2472 
2474 {
2475 
2476  // Handling of v5-v6 migration (TRefArray _proxyList --> RooRefArray _proxyList)
2477  map<RooAbsArg*,TRefArray*>::iterator iter = _ioEvoList.begin() ;
2478  while (iter != _ioEvoList.end()) {
2479 
2480  // Transfer contents of saved TRefArray to RooRefArray now
2481  for (int i=0 ; i < iter->second->GetEntries() ; i++) {
2482  iter->first->_proxyList.Add(iter->second->At(i)) ;
2483  }
2484 
2485  // Save iterator position for deletion after increment
2486  map<RooAbsArg*,TRefArray*>::iterator iter_tmp = iter ;
2487 
2488  iter++ ;
2489 
2490  // Delete TRefArray and remove from list
2491  delete iter_tmp->second ;
2492  _ioEvoList.erase(iter_tmp) ;
2493 
2494  }
2495 
2496 }
2497 
2498 
2499 ////////////////////////////////////////////////////////////////////////////////
2500 /// Stream an object of class RooRefArray.
2501 
2502 void RooRefArray::Streamer(TBuffer &R__b)
2503 {
2504  UInt_t R__s, R__c;
2505  if (R__b.IsReading()) {
2506 
2507  Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
2508 
2509  // Make temporary refArray and read that from the streamer
2510  TRefArray* refArray = new TRefArray ;
2511  refArray->Streamer(R__b) ;
2512  R__b.CheckByteCount(R__s, R__c, refArray->IsA());
2513 
2514  // Schedule deferred processing of TRefArray into proxy list
2515  RooAbsArg::_ioEvoList[RooAbsArg::_ioReadStack.top()] = refArray ;
2516 
2517  } else {
2518 
2519  R__c = R__b.WriteVersion(RooRefArray::IsA(), kTRUE);
2520 
2521  // Make a temporary refArray and write that to the streamer
2522  TRefArray refArray ;
2523  TIterator* iter = MakeIterator() ;
2524  TObject* tmpObj ; while ((tmpObj = iter->Next())) {
2525  refArray.Add(tmpObj) ;
2526  }
2527  delete iter ;
2528 
2529  refArray.Streamer(R__b) ;
2530  R__b.SetByteCount(R__c, kTRUE) ;
2531 
2532  }
2533 }
2534 
2535 
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
Definition: RooAbsArg.cxx:266
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2082
virtual void Add(TObject *arg)
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual RooAbsArg * cloneTree(const char *newname=0) const
Clone tree expression of objects.
Definition: RooAbsArg.cxx:2296
Bool_t IsReading() const
Definition: TBuffer.h:81
Int_t numCaches() const
Return number of registered caches.
Definition: RooAbsArg.cxx:2064
virtual void findConstantNodes(const RooArgSet &, RooArgSet &, RooLinkedList &)
Interface for constant term node finding calls.
#define coutE(a)
Definition: RooMsgService.h:34
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer, which is interpreted as an OR of &#39;enum ContentsOptions&#39; values and in the style given by &#39;enum StyleOption&#39;.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
void unRegisterProxy(RooArgProxy &proxy)
Remove proxy from proxy list.
Definition: RooAbsArg.cxx:1173
void treeNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=0, Bool_t doBranch=kTRUE, Bool_t doLeaf=kTRUE, Bool_t valueOnly=kFALSE, Bool_t recurseNonDerived=kFALSE) const
Fill supplied list with nodes of the arg tree, following all server links, starting with ourself as t...
Definition: RooAbsArg.cxx:514
RooAbsDataStore is the abstract base class for data collection that use a TTree as internal storage m...
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
TIterator * _clientShapeIter
Definition: RooAbsArg.h:479
virtual Bool_t RemoveAll(TObject *obj)
Remove object from list and delete object itself regardless of reference count.
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:86
static std::stack< RooAbsArg * > _ioReadStack
Definition: RooAbsArg.h:592
virtual const char * name() const
Definition: RooAbsProxy.h:41
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:744
void sort(Bool_t ascend=kTRUE)
#define cxcoutI(a)
Definition: RooMsgService.h:83
RooAbsCache * getCache(Int_t index) const
Return registered cache object by index.
Definition: RooAbsArg.cxx:2073
void graphVizTree(const char *fileName, const char *delimiter="\, bool useTitle=false, bool useLatex=false)
Create a GraphViz .dot file visualizing the expression tree headed by this RooAbsArg object...
Definition: RooAbsArg.cxx:2119
short Version_t
Definition: RtypesCore.h:61
static void ioStreamerPass2Finalize()
Method called by workspace container to finalize schema evolution issues that cannot be handled in a ...
Definition: RooAbsArg.cxx:2473
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Definition: RooAbsArg.h:194
virtual void operModeHook()
Interface for operation mode changes.
Definition: RooAbsCache.cxx:99
virtual void optimizeCacheMode(const RooArgSet &observables)
Activate cache mode optimization with given definition of observables.
Definition: RooAbsArg.cxx:1579
void Add(TObject *obj)
Definition: TRefArray.h:80
virtual const RooArgSet * get() const
Definition: RooAbsData.h:77
void printAttribList(std::ostream &os) const
Transient boolean attributes (not copied in ctor)
Definition: RooAbsArg.cxx:1481
RooFIter valueClientMIterator() const
Definition: RooAbsArg.h:117
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:493
void setHashTableSize(Int_t size)
Change the threshold for hash-table use to given size.
const char Option_t
Definition: RtypesCore.h:62
#define coutI(a)
Definition: RooMsgService.h:31
RooExpensiveObjectCache is a singleton class that serves as repository for objects that are expensive...
friend std::ostream & operator<<(std::ostream &os, const RooAbsArg &arg)
#define cxcoutD(a)
Definition: RooMsgService.h:79
A RooRefCountList is a RooLinkedList that keeps a reference counter with each added node...
void registerProxy(RooArgProxy &proxy)
Register an RooArgProxy in the proxy list.
Definition: RooAbsArg.cxx:1145
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
TNamed * _namePtr
Definition: RooAbsArg.h:580
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
virtual void printClassName(std::ostream &os) const
Print object class name.
Definition: RooAbsArg.cxx:1335
virtual Int_t defaultPrintContents(Option_t *opt) const
Define default contents to print.
Definition: RooAbsArg.cxx:1375
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
virtual TObject * Remove(TObject *obj)
Remove object from array.
Definition: TObjArray.cxx:653
Int_t refCount(TObject *obj)
Return reference count associated with &#39;obj&#39;.
virtual const RooArgSet * get(Int_t index) const =0
RooAbsArg()
Default constructor.
Definition: RooAbsArg.cxx:93
virtual void printValue(std::ostream &os) const
Interface to print value of object.
virtual Bool_t isLValue() const
Definition: RooAbsArg.h:170
RooFIter fwdIterator() const
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
std::set< std::string > _boolAttrib
Definition: RooAbsArg.h:523
Int_t getHashTableSize() const
Definition: RooLinkedList.h:50
Bool_t inhibitDirty() const
Delete watch flag.
Definition: RooAbsArg.cxx:84
An array of references to TObjects.
Definition: TRefArray.h:39
void setProxyNormSet(const RooArgSet *nset)
Forward a change in the cached normalization argset to all the registered proxies.
Definition: RooAbsArg.cxx:1278
Bool_t addOwnedComponents(const RooArgSet &comps)
Take ownership of the contents of &#39;comps&#39;.
Definition: RooAbsArg.cxx:2282
STL namespace.
RooTreeDataStore is the abstract base class for data collection that use a TTree as internal storage ...
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
void replaceServer(RooAbsArg &oldServer, RooAbsArg &newServer, Bool_t valueProp, Bool_t shapeProp)
Replace &#39;oldServer&#39; with &#39;newServer&#39;.
Definition: RooAbsArg.cxx:446
RooAbsCache is the abstract base class for data members of RooAbsArgs that cache other (composite) Ro...
Definition: RooAbsCache.h:27
void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Definition: RooAbsArg.cxx:2406
Bool_t _fast
Definition: RooAbsArg.h:571
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Definition: TNamed.cxx:145
virtual Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE)=0
void attachDataSet(const RooAbsData &set)
Replace server nodes with names matching the dataset variable names with those data set variables...
Definition: RooAbsArg.cxx:1497
TObject * First() const
Definition: RooLinkedList.h:78
Bool_t _deleteWatch
Definition: RooAbsArg.h:554
Int_t GetSize() const
Definition: RooLinkedList.h:60
Iterator abstract base class.
Definition: TIterator.h:30
Bool_t isCloneOf(const RooAbsArg &other) const
Check if this object was created as a clone of &#39;other&#39;.
Definition: RooAbsArg.cxx:256
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:687
virtual void getParametersHook(const RooArgSet *, RooArgSet *, Bool_t) const
Definition: RooAbsArg.h:434
void attachToStore(RooAbsDataStore &store)
Definition: RooAbsArg.cxx:2329
RooArgSet * _ownedComponents
Definition: RooAbsArg.h:574
RooAbsArg * findServer(const char *name) const
Definition: RooAbsArg.h:122
virtual void attachToTree(TTree &t, Int_t bufSize=32000)=0
Overloadable function for derived classes to implement attachment as branch to a TTree.
Definition: RooAbsArg.cxx:1293
RooRefCountList _clientListValue
Definition: RooAbsArg.h:476
Bool_t _valueDirty
Definition: RooAbsArg.h:566
void registerCache(RooAbsCache &cache)
Register RooAbsCache with this object.
Definition: RooAbsArg.cxx:2045
void setValueDirty() const
Definition: RooAbsArg.h:439
RooAbsArg * findNewServer(const RooAbsCollection &newSet, Bool_t nameChange) const
Find the new server in the specified set that matches the old server.
Definition: RooAbsArg.cxx:1051
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string &#39;value&#39; to this object under key &#39;key&#39;.
Definition: RooAbsArg.cxx:298
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:135
std::deque< RooAbsCache * > _cacheList
Definition: RooAbsArg.h:478
RooFIter serverMIterator() const
Definition: RooAbsArg.h:119
Bool_t observableOverlaps(const RooAbsData *dset, const RooAbsArg &testArg) const
Test if any of the dependents of the arg tree (as determined by getObservables) overlaps with those o...
Definition: RooAbsArg.cxx:817
void printCompactTree(const char *indent="", const char *fileName=0, const char *namePat=0, RooAbsArg *client=0)
Print tree structure of expression tree on stdout, or to file if filename is specified.
Definition: RooAbsArg.cxx:1783
RooPlotable is a &#39;mix-in&#39; base class that define the standard RooFit plotting and printing methods...
Definition: RooPrintable.h:25
void Class()
Definition: Class.C:29
RooLinkedList getCloningAncestors() const
Return ancestors in cloning chain of this RooAbsArg.
Definition: RooAbsArg.cxx:2092
virtual void printName(std::ostream &os) const
Print object name.
Definition: RooAbsArg.cxx:1315
virtual Bool_t changePointer(const RooAbsCollection &newServerSet, Bool_t nameChange=kFALSE, Bool_t factoryInitMode=kFALSE)=0
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:396
RooVectorDataStore is the abstract base class for data collection that use a TTree as internal storag...
virtual void attachToVStore(RooVectorDataStore &vstore)=0
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooAbsArg.h:227
RooAbsCollection * selectByAttrib(const char *name, Bool_t value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
friend std::istream & operator>>(std::istream &is, RooAbsArg &arg)
Istream operator.
Definition: RooAbsArg.cxx:1472
Int_t Compare(const TObject *other) const
Utility function used by TCollection::Sort to compare contained TObjects We implement comparison by n...
Definition: RooAbsArg.cxx:1535
static Bool_t _verboseDirty
Definition: RooAbsArg.h:552
virtual Bool_t redirectServersHook(const RooAbsCollection &, Bool_t, Bool_t, Bool_t)
Interface for server redirect calls.
Definition: RooAbsCache.cxx:89
virtual Bool_t redirectServersHook(const RooAbsCollection &, Bool_t, Bool_t, Bool_t)
Definition: RooAbsArg.h:486
RooConstVar represent a constant real-valued object.
Definition: RooConstVar.h:25
friend class RooArgSet
Definition: RooAbsArg.h:469
static Bool_t _inhibitDirty
Definition: RooAbsArg.h:553
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
Bool_t isShapeServer() const
Definition: RooArgProxy.h:65
TString operator+(const TString &s1, const TString &s2)
Use the special concatenation constructor.
Definition: TString.cxx:1448
void wireAllCaches()
Definition: RooAbsArg.cxx:2372
virtual void operModeHook()
Definition: RooAbsArg.h:428
Bool_t overlaps(const RooAbsArg &testArg, Bool_t valueOnly=kFALSE) const
Test if any of the nodes of tree are shared with that of the given tree.
Definition: RooAbsArg.cxx:803
static ULong64_t fnv1a64(const char *data)
Definition: RooAbsArg.cxx:2010
static void verboseDirty(Bool_t flag)
Activate verbose messaging related to dirty flag propagation.
Definition: RooAbsArg.cxx:248
virtual Bool_t isFundamental() const
Definition: RooAbsArg.h:157
void addServerList(RooAbsCollection &serverList, Bool_t valueProp=kTRUE, Bool_t shapeProp=kFALSE)
Register a list of RooAbsArg as servers to us by calls addServer() for each arg in the list...
Definition: RooAbsArg.cxx:398
virtual void printCompactTreeHook(std::ostream &, const char *)
Interface for printing of cache guts in tree mode printing.
static RooNameReg & instance()
Return reference to singleton instance.
Definition: RooNameReg.cxx:64
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:289
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:62
void graphVizAddConnections(std::set< std::pair< RooAbsArg *, RooAbsArg *> > &)
Utility function that inserts all point-to-point client-server connections between any two RooAbsArgs...
Definition: RooAbsArg.cxx:2190
void unRegisterCache(RooAbsCache &cache)
Unregister a RooAbsCache. Called from the RooAbsCache destructor.
Definition: RooAbsArg.cxx:2054
Int_t getSize() const
virtual const char * cacheUniqueSuffix() const
Definition: RooAbsArg.h:455
TString cleanBranchName() const
Construct a mangled name from the actual name that is free of any math symbols that might be interpre...
Definition: RooAbsArg.cxx:1872
void setTransientAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
Definition: RooAbsArg.cxx:327
RooExpensiveObjectCache & expensiveObjectCache() const
Definition: RooAbsArg.cxx:2342
RooAbsArg * first() const
Bool_t _isConstant
Do not persist. Pointer to global instance of string that matches object named.
Definition: RooAbsArg.h:581
RooAbsProxy is the abstact interface for proxy classes.
Definition: RooAbsProxy.h:31
virtual ~RooAbsArg()
Destructor.
Definition: RooAbsArg.cxx:192
Bool_t recursiveCheckObservables(const RooArgSet *nset) const
Recursively call checkObservables on all nodes in the expression tree.
Definition: RooAbsArg.cxx:718
RooArgSet * getComponents() const
Definition: RooAbsArg.cxx:688
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:504
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:436
void printComponentTree(const char *indent="", const char *namePat=0, Int_t nLevel=999)
Print tree structure of expression tree on given ostream, only branch nodes are printed.
Definition: RooAbsArg.cxx:1845
unsigned int UInt_t
Definition: RtypesCore.h:42
void SetName(const char *name)
Set the name of the TNamed.
Definition: RooAbsArg.cxx:2390
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key &#39;key&#39;.
Definition: RooAbsArg.cxx:313
char * Form(const char *fmt,...)
virtual void printAddress(std::ostream &os) const
Print class name of object.
Definition: RooAbsArg.cxx:1341
RooRefCountList _clientList
Definition: RooAbsArg.h:474
static UInt_t crc32(const char *data)
Definition: RooAbsArg.cxx:1906
RooAbsArg * absArg() const
Definition: RooArgProxy.h:37
void attachDataStore(const RooAbsDataStore &set)
Replace server nodes with names matching the dataset variable names with those data set variables...
Definition: RooAbsArg.cxx:1516
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:90
virtual void printMetaArgs(std::ostream &) const
Definition: RooAbsArg.h:237
virtual void changeNormSet(const RooArgSet *newNormSet)
Destructor.
Definition: RooAbsProxy.cxx:65
OperMode operMode() const
Definition: RooAbsArg.h:399
OperMode _operMode
Definition: RooAbsArg.h:570
Bool_t isValueServer() const
Definition: RooArgProxy.h:61
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Implement multi-line detailed printing.
Definition: RooAbsArg.cxx:1385
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:37
RooRefCountList _clientListShape
Definition: RooAbsArg.h:475
void changeServer(RooAbsArg &server, Bool_t valueProp, Bool_t shapeProp)
Change dirty flag propagation mask for specified server.
Definition: RooAbsArg.cxx:459
void addParameters(RooArgSet &params, const RooArgSet *nset=0, Bool_t stripDisconnected=kTRUE) const
INTERNAL helper function for getParameters()
Definition: RooAbsArg.cxx:569
TString fName
Definition: TNamed.h:32
#define coutF(a)
Definition: RooMsgService.h:35
static RooExpensiveObjectCache & instance()
Return reference to singleton instance.
virtual void writeToStream(std::ostream &os, Bool_t compact) const =0
RooListProxy is the concrete proxy for RooArgList objects.
Definition: RooListProxy.h:25
static void setDirtyInhibit(Bool_t flag)
Control global dirty inhibit mode.
Definition: RooAbsArg.cxx:239
RooAbsArg * next()
const Bool_t kFALSE
Definition: RtypesCore.h:92
virtual void printArgs(std::ostream &os) const
Print object arguments, ie its proxies.
Definition: RooAbsArg.cxx:1352
virtual Bool_t Remove(TObject *obj)
Remove object from list and if reference count reaches zero delete object itself as well...
Bool_t _localNoInhibitDirty
Cached isConstant status.
Definition: RooAbsArg.h:583
RooRefArray _proxyList
Definition: RooAbsArg.h:477
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:35
void printDirty(Bool_t depth=kTRUE) const
Print information about current value dirty state information.
Definition: RooAbsArg.cxx:1547
#define ClassImp(name)
Definition: Rtypes.h:336
virtual Bool_t isValid() const
WVE (08/21/01) Probably obsolete now.
Definition: RooAbsArg.cxx:1304
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooFIter fwdIterator() const
RooArgSet * getParameters(const RooAbsData *data, Bool_t stripDisconnected=kTRUE) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don&#39;t match any of...
Definition: RooAbsArg.cxx:560
std::map< std::string, std::string > _stringAttrib
Definition: RooAbsArg.h:524
unsigned long long ULong64_t
Definition: RtypesCore.h:70
unsigned long ULong_t
Definition: RtypesCore.h:51
virtual Bool_t checkObservables(const RooArgSet *nset) const
Overloadable function in which derived classes can implement consistency checks of the variables...
Definition: RooAbsArg.cxx:709
RooRefCountList _serverList
Definition: RooAbsArg.h:473
TIterator * _clientValueIter
Iterator over _clientListShape.
Definition: RooAbsArg.h:480
Bool_t findConstantNodes(const RooArgSet &observables, RooArgSet &cacheList)
Find branch nodes with all-constant parameters, and add them to the list of nodes that can be cached ...
Definition: RooAbsArg.cxx:1644
Bool_t _prohibitServerRedirect
Set of owned component.
Definition: RooAbsArg.h:576
const char * GetName() const
Returns name of object.
Bool_t isValueDirty() const
Definition: RooAbsArg.h:336
RooAbsProxy * getProxy(Int_t index) const
Return the nth proxy from the proxy list.
Definition: RooAbsArg.cxx:1254
Bool_t dependsOnValue(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=0) const
Definition: RooAbsArg.h:88
Mother of all ROOT objects.
Definition: TObject.h:37
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects...
Int_t numProxies() const
Return the number of registered proxies.
Definition: RooAbsArg.cxx:1267
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
RooArgProxy is the abstact interface for RooAbsArg proxy classes.
Definition: RooArgProxy.h:24
Bool_t isShapeServer(const RooAbsArg &arg) const
Definition: RooAbsArg.h:142
Bool_t _shapeDirty
Definition: RooAbsArg.h:567
virtual void printTitle(std::ostream &os) const
Print object title.
Definition: RooAbsArg.cxx:1325
Bool_t isValueServer(const RooAbsArg &arg) const
Definition: RooAbsArg.h:134
virtual Bool_t isDerived() const
Definition: RooAbsArg.h:81
Bool_t getTransientAttribute(const Text_t *name) const
Check if a named attribute is set.
Definition: RooAbsArg.cxx:349
void setShapeDirty() const
Definition: RooAbsArg.h:440
TIterator * MakeIterator(Bool_t dir=kTRUE) const
Return an iterator over this list.
virtual void optimizeCacheMode(const RooArgSet &, RooArgSet &, RooLinkedList &)
Interface for processing of cache mode optimization calls.
Definition: RooAbsCache.cxx:80
virtual void constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt=kTRUE)
Interface function signaling a request to perform constant term optimization.
Definition: RooAbsArg.cxx:1739
virtual TObject * Next()=0
const TNamed * constPtr(const char *stringPtr)
Return a unique TNamed pointer for given C++ string.
Definition: RooNameReg.cxx:91
RooSetProxy is the concrete proxy for RooArgSet objects.
Definition: RooSetProxy.h:24
#define snprintf
Definition: civetweb.c:822
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Change cache operation mode to given mode.
Definition: RooAbsArg.cxx:1754
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
char Text_t
Definition: RtypesCore.h:58
RooAbsArg * findArg(const RooAbsArg *) const
Return pointer to object with given name in collection.
void Add(TObject *obj)
Definition: TObjArray.h:73
#define cxcoutF(a)
Definition: RooMsgService.h:99
Definition: first.py:1
virtual void printTree(std::ostream &os, TString indent="") const
Print object tree structure.
Definition: RooAbsArg.cxx:1454
Bool_t isShapeDirty() const
Definition: RooAbsArg.h:331
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
static std::map< RooAbsArg *, TRefArray * > _ioEvoList
Definition: RooAbsArg.h:591
virtual void Compress()
Remove empty slots from array.
Definition: TObjArray.cxx:309
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:364
void addServer(RooAbsArg &server, Bool_t valueProp=kTRUE, Bool_t shapeProp=kFALSE)
Register another RooAbsArg as a server to us, ie, declare that we depend on it.
Definition: RooAbsArg.cxx:362
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Definition: RooAbsArg.cxx:1088
virtual void printCompactTreeHook(std::ostream &os, const char *ind="")
Hook function interface for object to insert additional information when printed in the context of a ...
Definition: RooAbsArg.cxx:2032
virtual void ioStreamerPass2()
Prevent &#39;AlwaysDirty&#39; mode for this node.
Definition: RooAbsArg.cxx:2445
const char * aggregateCacheUniqueSuffix() const
Definition: RooAbsArg.cxx:2354
Bool_t redirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t isRecursionStep=kFALSE)
Iterator over _clientListValue.
Definition: RooAbsArg.cxx:929
void removeServer(RooAbsArg &server, Bool_t force=kFALSE)
Unregister another RooAbsArg as a server to us, ie, declare that we no longer depend on its value and...
Definition: RooAbsArg.cxx:413
const Bool_t kTRUE
Definition: RtypesCore.h:91
virtual void print(std::ostream &os, Bool_t addContents=kFALSE) const
Print proxy name.
Definition: RooAbsProxy.cxx:75
RooExpensiveObjectCache * _eocache
Prohibit server redirects – Debugging tool.
Definition: RooAbsArg.h:578
std::set< std::string > _boolAttribTransient
Definition: RooAbsArg.h:525
static UInt_t fnv1a32(const char *data)
Definition: RooAbsArg.cxx:1993
Bool_t isConstant() const
Definition: RooAbsArg.h:266
const TNamed * namePtr() const
Definition: RooAbsArg.h:459
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48