Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
21RooAbsArg is the common abstract base class for objects that
22represent a value and a "shape" in RooFit. Values or shapes usually depend on values
23or shapes of other RooAbsArg instances. Connecting several RooAbsArg in
24a computation graph models an expression tree that can be evaluated.
25
26### Building a computation graph of RooFit objects
27Therefore, RooAbsArg provides functionality to connect objects of type RooAbsArg into
28a computation graph to pass values between those objects.
29A value can e.g. be a real-valued number, (instances of RooAbsReal), or an integer, that is,
30catgory index (instances of RooAbsCategory). The third subclass of RooAbsArg is RooStringVar,
31but it is rarely used.
32
33The "shapes" that a RooAbsArg can possess can e.g. be the definition
34range of an observable, or how many states a category object has. In computations,
35values are expected to change often, while shapes remain mostly constant
36(unless e.g. a new range is set for an observable).
37
38Nodes of a computation graph are connected using instances of RooAbsProxy.
39If Node B declares a member `RooTemplateProxy<TypeOfNodeA>`, Node A will be
40registered as a server of values to Node B, and Node B will know that it is
41a client of node A. Using functions like dependsOn(), or getObservables()
42/ getParameters(), the relation of `A --> B` can be queried. Using graphVizTree(),
43one can create a visualisation of the expression tree.
44
45
46An instance of RooAbsArg can have named attributes. It also has flags
47to indicate that either its value or its shape were changed (= it is dirty).
48RooAbsArg provides functionality to manage client/server relations in
49a computation graph (\ref clientServerInterface), and helps propagating
50value/shape changes through the graph. RooAbsArg implements interfaces
51for inspecting client/server relationships (\ref clientServerInterface) and
52setting/clearing/querying named attributes.
53
54### Caching of values
55The values of nodes in the computation graph are cached in RooFit. If
56a value is used in two nodes of a graph, it doesn't need to be recomputed. If
57a node acquires a new value, it notifies its consumers ("clients") that
58their cached values are dirty. See the functions in \ref optimisationInterface
59for details.
60A node uses its isValueDirty() and isShapeDirty() functions to decide if a
61computation is necessary. Caching can be vetoed globally by setting a
62bit using setDirtyInhibit(). This will make computations slower, but all the
63nodes of the computation graph will be evaluated irrespective of whether their
64state is clean or dirty. Using setOperMode(), caching can also be enabled/disabled
65for single nodes.
66
67*/
68
69#include "RooFit.h"
70
71#include "TBuffer.h"
72#include "TClass.h"
74#include "strlcpy.h"
75
76#include "RooSecondMoment.h"
77#include "RooNameSet.h"
78#include "RooWorkspace.h"
79
80#include "RooMsgService.h"
81#include "RooAbsArg.h"
82#include "RooArgSet.h"
83#include "RooArgProxy.h"
84#include "RooSetProxy.h"
85#include "RooListProxy.h"
86#include "RooAbsData.h"
88#include "RooAbsRealLValue.h"
89#include "RooTrace.h"
90#include "RooRealIntegral.h"
91#include "RooConstVar.h"
93#include "RooAbsDataStore.h"
94#include "RooResolutionModel.h"
95#include "RooVectorDataStore.h"
96#include "RooTreeDataStore.h"
97#include "ROOT/RMakeUnique.hxx"
98#include "RooHelpers.h"
99
100#include <iostream>
101#include <fstream>
102#include <sstream>
103#include <cstring>
104#include <algorithm>
105
106using namespace std;
107
108#if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
109char* operator+( streampos&, char* );
110#endif
111
113;
114
118
119std::map<RooAbsArg*,std::unique_ptr<TRefArray>> RooAbsArg::_ioEvoList;
120std::stack<RooAbsArg*> RooAbsArg::_ioReadStack ;
121
122
123////////////////////////////////////////////////////////////////////////////////
124/// Default constructor
125
127 : TNamed(), _deleteWatch(kFALSE), _valueDirty(kTRUE), _shapeDirty(kTRUE), _operMode(Auto), _fast(kFALSE), _ownedComponents(nullptr),
128 _prohibitServerRedirect(kFALSE), _namePtr(0), _isConstant(kFALSE), _localNoInhibitDirty(kFALSE),
129 _myws(0)
130{
132
133}
134
135////////////////////////////////////////////////////////////////////////////////
136/// Create an object with the specified name and descriptive title.
137/// The newly created object has no clients or servers and has its
138/// dirty flags set.
139
140RooAbsArg::RooAbsArg(const char *name, const char *title)
141 : TNamed(name, title), _deleteWatch(kFALSE), _valueDirty(kTRUE), _shapeDirty(kTRUE), _operMode(Auto), _fast(kFALSE),
142 _ownedComponents(0), _prohibitServerRedirect(kFALSE), _namePtr(0), _isConstant(kFALSE),
143 _localNoInhibitDirty(kFALSE), _myws(0)
144{
145 if (name == nullptr || strlen(name) == 0) {
146 throw std::logic_error("Each RooFit object needs a name. "
147 "Objects representing the same entity (e.g. an observable 'x') are identified using their name.");
148 }
150}
151
152////////////////////////////////////////////////////////////////////////////////
153/// Copy constructor transfers all boolean and string properties of the original
154/// object. Transient properties and client-server links are not copied
155
156RooAbsArg::RooAbsArg(const RooAbsArg &other, const char *name)
157 : TNamed(other.GetName(), other.GetTitle()), RooPrintable(other), _boolAttrib(other._boolAttrib),
158 _stringAttrib(other._stringAttrib), _deleteWatch(other._deleteWatch), _operMode(Auto), _fast(kFALSE),
159 _ownedComponents(0), _prohibitServerRedirect(kFALSE), _namePtr(other._namePtr),
160 _isConstant(other._isConstant), _localNoInhibitDirty(other._localNoInhibitDirty), _myws(0)
161{
162 // Use name in argument, if supplied
163 if (name) {
166 } else {
167 // Same name, don't recalculate name pointer (expensive)
168 TNamed::SetName(other.GetName()) ;
169 _namePtr = other._namePtr ;
170 }
171
172 // Copy server list by hand
173 Bool_t valueProp, shapeProp ;
174 for (const auto server : other._serverList) {
175 valueProp = server->_clientListValue.containsByNamePtr(&other);
176 shapeProp = server->_clientListShape.containsByNamePtr(&other);
177 addServer(*server,valueProp,shapeProp) ;
178 }
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/// Assign all boolean and string properties of the original
190/// object. Transient properties and client-server links are not assigned.
192 TNamed::operator=(other);
193 RooPrintable::operator=(other);
194 _boolAttrib = other._boolAttrib;
197 _operMode = other._operMode;
198 _fast = other._fast;
199 _ownedComponents = nullptr;
201 _namePtr = other._namePtr;
202 _isConstant = other._isConstant;
204 _myws = nullptr;
205
206 bool valueProp, shapeProp;
207 for (const auto server : other._serverList) {
208 valueProp = server->_clientListValue.containsByNamePtr(&other);
209 shapeProp = server->_clientListShape.containsByNamePtr(&other);
210 addServer(*server,valueProp,shapeProp) ;
211 }
212
215
216 return *this;
217}
218
219
220////////////////////////////////////////////////////////////////////////////////
221/// Destructor.
222
224{
225 // Notify all servers that they no longer need to serve us
226 while (!_serverList.empty()) {
228 }
229
230 // Notify all clients that they are in limbo
231 std::vector<RooAbsArg*> clientListTmp(_clientList.begin(), _clientList.end()); // have to copy, as we invalidate iterators
233 for (auto client : clientListTmp) {
234 client->setAttribute("ServerDied") ;
235 TString attr("ServerDied:");
236 attr.Append(GetName());
237 attr.Append(Form("(%lx)",(ULong_t)this)) ;
238 client->setAttribute(attr.Data());
239 client->removeServer(*this,kTRUE);
240
241 if (_verboseDirty) {
242
243 if (first) {
244 cxcoutD(Tracing) << "RooAbsArg::dtor(" << GetName() << "," << this << ") DeleteWatch: object is being destroyed" << endl ;
245 first = kFALSE ;
246 }
247
248 cxcoutD(Tracing) << fName << "::" << ClassName() << ":~RooAbsArg: dependent \""
249 << client->GetName() << "\" should have been deleted first" << endl ;
250 }
251 }
252
253 if (_ownedComponents) {
254 delete _ownedComponents ;
255 _ownedComponents = 0 ;
256 }
257
258}
259
260
261////////////////////////////////////////////////////////////////////////////////
262/// Control global dirty inhibit mode. When set to true no value or shape dirty
263/// flags are propagated and cache is always considered to be dirty.
264
266{
267 _inhibitDirty = flag ;
268}
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Activate verbose messaging related to dirty flag propagation
273
275{
276 _verboseDirty = flag ;
277}
278
279////////////////////////////////////////////////////////////////////////////////
280/// Check if this object was created as a clone of 'other'
281
283{
284 return (getAttribute(Form("CloneOf(%lx)",(ULong_t)&other)) ||
285 other.getAttribute(Form("CloneOf(%lx)",(ULong_t)this))) ;
286}
287
288
289////////////////////////////////////////////////////////////////////////////////
290/// Set (default) or clear a named boolean attribute of this object.
291
293{
294 // Preserve backward compatibility - any strong
295 if(string("Constant")==name) {
296 _isConstant = value ;
297 }
298
299 if (value) {
300 _boolAttrib.insert(name) ;
301 } else {
302 set<string>::iterator iter = _boolAttrib.find(name) ;
303 if (iter != _boolAttrib.end()) {
304 _boolAttrib.erase(iter) ;
305 }
306
307 }
308
309}
310
311
312////////////////////////////////////////////////////////////////////////////////
313/// Check if a named attribute is set. By default, all attributes are unset.
314
316{
317 return (_boolAttrib.find(name) != _boolAttrib.end()) ;
318}
319
320
321////////////////////////////////////////////////////////////////////////////////
322/// Associate string 'value' to this object under key 'key'
323
324void RooAbsArg::setStringAttribute(const Text_t* key, const Text_t* value)
325{
326 if (value) {
327 _stringAttrib[key] = value ;
328 } else {
329 _stringAttrib.erase(key) ;
330 }
331}
332
333////////////////////////////////////////////////////////////////////////////////
334/// Get string attribute mapped under key 'key'. Returns null pointer
335/// if no attribute exists under that key
336
338{
339 map<string,string>::const_iterator iter = _stringAttrib.find(key) ;
340 if (iter!=_stringAttrib.end()) {
341 return iter->second.c_str() ;
342 } else {
343 return 0 ;
344 }
345}
346
347
348////////////////////////////////////////////////////////////////////////////////
349/// Set (default) or clear a named boolean attribute of this object.
350
352{
353 if (value) {
354
355 _boolAttribTransient.insert(name) ;
356
357 } else {
358
359 set<string>::iterator iter = _boolAttribTransient.find(name) ;
360 if (iter != _boolAttribTransient.end()) {
361 _boolAttribTransient.erase(iter) ;
362 }
363
364 }
365
366}
367
368
369////////////////////////////////////////////////////////////////////////////////
370/// Check if a named attribute is set. By default, all attributes
371/// are unset.
372
374{
375 return (_boolAttribTransient.find(name) != _boolAttribTransient.end()) ;
376}
377
378
379
380
381////////////////////////////////////////////////////////////////////////////////
382/// Register another RooAbsArg as a server to us, ie, declare that
383/// we depend on it.
384/// \param server The server to be registered.
385/// \param valueProp In addition to the basic client-server relationship, declare dependence on the server's value.
386/// \param valueProp In addition to the basic client-server relationship, declare dependence on the server's shape.
387/// \param refCount Optionally add with higher reference count (if multiple components depend on it)
388
389void RooAbsArg::addServer(RooAbsArg& server, Bool_t valueProp, Bool_t shapeProp, std::size_t refCount)
390{
392 cxcoutF(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName()
393 << "): PROHIBITED SERVER ADDITION REQUESTED: adding server " << server.GetName()
394 << "(" << &server << ") for " << (valueProp?"value ":"") << (shapeProp?"shape":"") << endl ;
395 throw std::logic_error("PROHIBITED SERVER ADDITION REQUESTED in RooAbsArg::addServer");
396 }
397
398 cxcoutD(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName() << "): adding server " << server.GetName()
399 << "(" << &server << ") for " << (valueProp?"value ":"") << (shapeProp?"shape":"") << endl ;
400
401 if (server.operMode()==ADirty && operMode()!=ADirty && valueProp) {
403 }
404
405
406 // LM: use hash tables for larger lists
407// if (_serverList.GetSize() > 999 && _serverList.getHashTableSize() == 0) _serverList.setHashTableSize(1000);
408// if (server._clientList.GetSize() > 999 && server._clientList.getHashTableSize() == 0) server._clientList.setHashTableSize(1000);
409// if (server._clientListValue.GetSize() > 999 && server._clientListValue.getHashTableSize() == 0) server._clientListValue.setHashTableSize(1000);
410
411 // Add server link to given server
412 _serverList.Add(&server, refCount) ;
413
414 server._clientList.Add(this, refCount);
415 if (valueProp) server._clientListValue.Add(this, refCount);
416 if (shapeProp) server._clientListShape.Add(this, refCount);
417}
418
419
420
421////////////////////////////////////////////////////////////////////////////////
422/// Register a list of RooAbsArg as servers to us by calling
423/// addServer() for each arg in the list
424
425void RooAbsArg::addServerList(RooAbsCollection& serverList, Bool_t valueProp, Bool_t shapeProp)
426{
427 _serverList.reserve(_serverList.size() + serverList.size());
428
429 for (const auto arg : serverList) {
430 addServer(*arg,valueProp,shapeProp) ;
431 }
432}
433
434
435
436////////////////////////////////////////////////////////////////////////////////
437/// Unregister another RooAbsArg as a server to us, ie, declare that
438/// we no longer depend on its value and shape.
439
441{
443 cxcoutF(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName() << "): PROHIBITED SERVER REMOVAL REQUESTED: removing server "
444 << server.GetName() << "(" << &server << ")" << endl ;
445 assert(0) ;
446 }
447
448 if (_verboseDirty) {
449 cxcoutD(LinkStateMgmt) << "RooAbsArg::removeServer(" << GetName() << "): removing server "
450 << server.GetName() << "(" << &server << ")" << endl ;
451 }
452
453 // Remove server link to given server
454 _serverList.Remove(&server, force) ;
455
456 server._clientList.Remove(this, force) ;
457 server._clientListValue.Remove(this, force) ;
458 server._clientListShape.Remove(this, force) ;
459}
460
461
462////////////////////////////////////////////////////////////////////////////////
463/// Replace 'oldServer' with 'newServer'
464
465void RooAbsArg::replaceServer(RooAbsArg& oldServer, RooAbsArg& newServer, Bool_t propValue, Bool_t propShape)
466{
467 Int_t count = _serverList.refCount(&oldServer);
468 removeServer(oldServer, kTRUE);
469 addServer(newServer, propValue, propShape, count);
470}
471
472
473////////////////////////////////////////////////////////////////////////////////
474/// Change dirty flag propagation mask for specified server
475
476void RooAbsArg::changeServer(RooAbsArg& server, Bool_t valueProp, Bool_t shapeProp)
477{
478 if (!_serverList.containsByNamePtr(&server)) {
479 coutE(LinkStateMgmt) << "RooAbsArg::changeServer(" << GetName() << "): Server "
480 << server.GetName() << " not registered" << endl ;
481 return ;
482 }
483
484 // This condition should not happen, but check anyway
485 if (!server._clientList.containsByNamePtr(this)) {
486 coutE(LinkStateMgmt) << "RooAbsArg::changeServer(" << GetName() << "): Server "
487 << server.GetName() << " doesn't have us registered as client" << endl ;
488 return ;
489 }
490
491 // Remove all propagation links, then reinstall requested ones ;
492 Int_t vcount = server._clientListValue.refCount(this) ;
493 Int_t scount = server._clientListShape.refCount(this) ;
494 server._clientListValue.RemoveAll(this) ;
495 server._clientListShape.RemoveAll(this) ;
496 if (valueProp) {
497 server._clientListValue.Add(this, vcount) ;
498 }
499 if (shapeProp) {
500 server._clientListShape.Add(this, scount) ;
501 }
502}
503
504
505
506////////////////////////////////////////////////////////////////////////////////
507/// Fill supplied list with all leaf nodes of the arg tree, starting with
508/// ourself as top node. A leaf node is node that has no servers declared.
509
510void RooAbsArg::leafNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t recurseNonDerived) const
511{
512 treeNodeServerList(list,arg,kFALSE,kTRUE,kFALSE,recurseNonDerived) ;
513}
514
515
516
517////////////////////////////////////////////////////////////////////////////////
518/// Fill supplied list with all branch nodes of the arg tree starting with
519/// ourself as top node. A branch node is node that has one or more servers declared.
520
521void RooAbsArg::branchNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t recurseNonDerived) const
522{
523 treeNodeServerList(list,arg,kTRUE,kFALSE,kFALSE,recurseNonDerived) ;
524}
525
526
527////////////////////////////////////////////////////////////////////////////////
528/// Fill supplied list with nodes of the arg tree, following all server links,
529/// starting with ourself as top node.
530/// \param[in] list Output list
531/// \param[in] arg Start searching at this element of the tree.
532/// \param[in] doBranch Add branch nodes to the list.
533/// \param[in] doLeaf Add leaf nodes to the list.
534/// \param[in] valueOnly Only check if an element is a value server (no shape server).
535/// \param[in] recurseFundamental
536
537void RooAbsArg::treeNodeServerList(RooAbsCollection* list, const RooAbsArg* arg, Bool_t doBranch, Bool_t doLeaf, Bool_t valueOnly, Bool_t recurseFundamental) const
538{
539// if (arg==0) {
540// cout << "treeNodeServerList(" << GetName() << ") doBranch=" << (doBranch?"T":"F") << " doLeaf = " << (doLeaf?"T":"F") << " valueOnly=" << (valueOnly?"T":"F") << endl ;
541// }
542
543 if (!arg) {
544 list->reserve(10);
545 arg=this ;
546 }
547
548 // Decide if to add current node
549 if ((doBranch&&doLeaf) ||
550 (doBranch&&arg->isDerived()) ||
551 (doLeaf&&arg->isFundamental()&&(!(recurseFundamental&&arg->isDerived()))) ||
552 (doLeaf && !arg->isFundamental() && !arg->isDerived())) {
553
554 list->add(*arg,kTRUE) ;
555 }
556
557 // Recurse if current node is derived
558 if (arg->isDerived() && (!arg->isFundamental() || recurseFundamental)) {
559 for (const auto server : arg->_serverList) {
560
561 // Skip non-value server nodes if requested
562 Bool_t isValueSrv = server->_clientListValue.containsByNamePtr(arg);
563 if (valueOnly && !isValueSrv) {
564 continue ;
565 }
566 treeNodeServerList(list,server,doBranch,doLeaf,valueOnly,recurseFundamental) ;
567 }
568 }
569}
570
571
572////////////////////////////////////////////////////////////////////////////////
573/// Create a list of leaf nodes in the arg tree starting with
574/// ourself as top node that don't match any of the names of the variable list
575/// of the supplied data set (the dependents). The caller of this
576/// function is responsible for deleting the returned argset.
577/// The complement of this function is getObservables()
578
579RooArgSet* RooAbsArg::getParameters(const RooAbsData* set, Bool_t stripDisconnected) const
580{
581 return getParameters(set?set->get():0,stripDisconnected) ;
582}
583
584
585////////////////////////////////////////////////////////////////////////////////
586/// INTERNAL helper function for getParameters()
587
588void RooAbsArg::addParameters(RooArgSet& params, const RooArgSet* nset,Bool_t stripDisconnected) const
589{
590 // INTERNAL helper function for getParameters()
591
592 RooArgSet nodeParamServers ;
593 RooArgSet nodeBranchServers ;
594 for (const auto server : _serverList) {
595 if (server->isValueServer(*this)) {
596 if (server->isFundamental()) {
597 if (!nset || !server->dependsOn(*nset)) {
598 nodeParamServers.add(*server) ;
599 }
600 } else {
601 nodeBranchServers.add(*server) ;
602 }
603 }
604 }
605
606 // Allow pdf to strip parameters from list before adding it
607 getParametersHook(nset,&nodeParamServers,stripDisconnected) ;
608
609 // Add parameters of this node to the combined list
610 params.add(nodeParamServers,kTRUE) ;
611
612 // Now recurse into branch servers
613 for (const auto server : nodeBranchServers) {
614 server->addParameters(params,nset) ;
615 }
616}
617
618
619////////////////////////////////////////////////////////////////////////////////
620/// Create a list of leaf nodes in the arg tree starting with
621/// ourself as top node that don't match any of the names the args in the
622/// supplied argset. The caller of this function is responsible
623/// for deleting the returned argset. The complement of this function
624/// is getObservables().
625
626RooArgSet* RooAbsArg::getParameters(const RooArgSet* observables, bool stripDisconnected) const {
627 auto * outputSet = new RooArgSet;
628 getParameters(observables, *outputSet, stripDisconnected);
629 return outputSet;
630}
631
632
633////////////////////////////////////////////////////////////////////////////////
634/// Fills a list with leaf nodes in the arg tree starting with
635/// ourself as top node that don't match any of the names the args in the
636/// supplied argset. Returns `true` only if something went wrong.
637/// The complement of this function is getObservables().
638/// \param[in] observables Set of leafs to ignore because they are observables and not parameters.
639/// \param[out] outputSet Output set.
640/// \param[in] stripDisconnected Allow pdf to strip parameters from list before adding it.
641
642bool RooAbsArg::getParameters(const RooArgSet* observables, RooArgSet& outputSet, bool stripDisconnected) const
643{
644
645 // Check for cached parameter set
646 if (_myws) {
647 RooNameSet nsetObs(observables ? *observables : RooArgSet());
648 const RooArgSet *paramSet = _myws->set(Form("CACHE_PARAMS_OF_PDF_%s_FOR_OBS_%s", GetName(), nsetObs.content()));
649 if (paramSet) {
650 outputSet.add(*paramSet);
651 return false;
652 }
653 }
654
655 outputSet.clear();
656 outputSet.setName("parameters");
657
658 addParameters(outputSet, observables, stripDisconnected);
659
660 outputSet.sort();
661
662 // Cache parameter set
663 if (_myws && outputSet.getSize() > 10) {
664 RooNameSet nsetObs(observables ? *observables : RooArgSet());
665 _myws->defineSetInternal(Form("CACHE_PARAMS_OF_PDF_%s_FOR_OBS_%s", GetName(), nsetObs.content()), outputSet);
666 // cout << " caching parameters in workspace for pdf " << IsA()->GetName() << "::" << GetName() << endl ;
667 }
668
669 return false;
670}
671
672
673////////////////////////////////////////////////////////////////////////////////
674/// Create a list of leaf nodes in the arg tree starting with
675/// ourself as top node that match any of the names of the variable list
676/// of the supplied data set (the dependents). The caller of this
677/// function is responsible for deleting the returned argset.
678/// The complement of this function is getParameters().
679
681{
682 if (!set) return new RooArgSet ;
683
684 return getObservables(set->get()) ;
685}
686
687
688////////////////////////////////////////////////////////////////////////////////
689/// Create a list of leaf nodes in the arg tree starting with
690/// ourself as top node that match any of the names the args in the
691/// supplied argset. The caller of this function is responsible
692/// for deleting the returned argset. The complement of this function
693/// is getParameters().
694
695RooArgSet* RooAbsArg::getObservables(const RooArgSet* dataList, bool valueOnly) const
696{
697 auto depList = new RooArgSet;
698 getObservables(dataList, *depList, valueOnly);
699 return depList;
700}
701
702
703////////////////////////////////////////////////////////////////////////////////
704/// Create a list of leaf nodes in the arg tree starting with
705/// ourself as top node that match any of the names the args in the
706/// supplied argset.
707/// Returns `true` only if something went wrong.
708/// The complement of this function is getParameters().
709/// \param[in] dataList Set of leaf nodes to match.
710/// \param[out] outputSet Output set.
711/// \param[in] valueOnly If this parameter is true, we only match leafs that
712/// depend on the value of any arg in `dataList`.
713
714bool RooAbsArg::getObservables(const RooArgSet* dataList, RooArgSet& outputSet, bool valueOnly) const
715{
716 outputSet.clear();
717 outputSet.setName("dependents");
718
719 if (!dataList) return false;
720
721 // Make iterator over tree leaf node list
722 RooArgSet leafList("leafNodeServerList") ;
723 treeNodeServerList(&leafList,0,kFALSE,kTRUE,valueOnly) ;
724
725 if (valueOnly) {
726 for (const auto arg : leafList) {
727 if (arg->dependsOnValue(*dataList) && arg->isLValue()) {
728 outputSet.add(*arg) ;
729 }
730 }
731 } else {
732 for (const auto arg : leafList) {
733 if (arg->dependsOn(*dataList) && arg->isLValue()) {
734 outputSet.add(*arg) ;
735 }
736 }
737 }
738
739 return false;
740}
741
742
743////////////////////////////////////////////////////////////////////////////////
744/// Create a RooArgSet with all components (branch nodes) of the
745/// expression tree headed by this object.
747{
748 TString name(GetName()) ;
749 name.Append("_components") ;
750
751 RooArgSet* set = new RooArgSet(name) ;
753
754 return set ;
755}
756
757
758
759////////////////////////////////////////////////////////////////////////////////
760/// Overloadable function in which derived classes can implement
761/// consistency checks of the variables. If this function returns
762/// true, indicating an error, the fitter or generator will abort.
763
765{
766 return kFALSE ;
767}
768
769
770////////////////////////////////////////////////////////////////////////////////
771/// Recursively call checkObservables on all nodes in the expression tree
772
774{
775 RooArgSet nodeList ;
776 treeNodeServerList(&nodeList) ;
777 RooFIter iter = nodeList.fwdIterator() ;
778
779 RooAbsArg* arg ;
780 Bool_t ret(kFALSE) ;
781 while((arg=iter.next())) {
782 if (arg->getAttribute("ServerDied")) {
783 coutE(LinkStateMgmt) << "RooAbsArg::recursiveCheckObservables(" << GetName() << "): ERROR: one or more servers of node "
784 << arg->GetName() << " no longer exists!" << endl ;
785 arg->Print("v") ;
786 ret = kTRUE ;
787 }
788 ret |= arg->checkObservables(nset) ;
789 }
790
791 return ret ;
792}
793
794
795////////////////////////////////////////////////////////////////////////////////
796/// Test whether we depend on (ie, are served by) any object in the
797/// specified collection. Uses the dependsOn(RooAbsArg&) member function.
798
799Bool_t RooAbsArg::dependsOn(const RooAbsCollection& serverList, const RooAbsArg* ignoreArg, Bool_t valueOnly) const
800{
801 // Test whether we depend on (ie, are served by) any object in the
802 // specified collection. Uses the dependsOn(RooAbsArg&) member function.
803
804 for (auto server : serverList) {
805 if (dependsOn(*server,ignoreArg,valueOnly)) {
806 return kTRUE;
807 }
808 }
809 return kFALSE;
810}
811
812
813////////////////////////////////////////////////////////////////////////////////
814/// Test whether we depend on (ie, are served by) the specified object.
815/// Note that RooAbsArg objects are considered equivalent if they have
816/// the same name.
817
818Bool_t RooAbsArg::dependsOn(const RooAbsArg& testArg, const RooAbsArg* ignoreArg, Bool_t valueOnly) const
819{
820 if (this==ignoreArg) return kFALSE ;
821
822 // First check if testArg is self
823 //if (!TString(testArg.GetName()).CompareTo(GetName())) return kTRUE ;
824 if (testArg.namePtr()==namePtr()) return kTRUE ;
825
826
827 // Next test direct dependence
828 RooAbsArg* foundServer = findServer(testArg) ;
829 if (foundServer) {
830
831 // Return true if valueOnly is FALSE or if server is value server, otherwise keep looking
832 if ( !valueOnly || foundServer->isValueServer(*this)) {
833 return kTRUE ;
834 }
835 }
836
837 // If not, recurse
838 for (const auto server : _serverList) {
839 if ( !valueOnly || server->isValueServer(*this)) {
840 if (server->dependsOn(testArg,ignoreArg,valueOnly)) {
841 return kTRUE ;
842 }
843 }
844 }
845
846 return kFALSE ;
847}
848
849
850
851////////////////////////////////////////////////////////////////////////////////
852/// Test if any of the nodes of tree are shared with that of the given tree
853
854Bool_t RooAbsArg::overlaps(const RooAbsArg& testArg, Bool_t valueOnly) const
855{
856 RooArgSet list("treeNodeList") ;
857 treeNodeServerList(&list) ;
858
859 return valueOnly ? testArg.dependsOnValue(list) : testArg.dependsOn(list) ;
860}
861
862
863
864////////////////////////////////////////////////////////////////////////////////
865/// Test if any of the dependents of the arg tree (as determined by getObservables)
866/// overlaps with those of the testArg.
867
869{
870 return observableOverlaps(dset->get(),testArg) ;
871}
872
873
874////////////////////////////////////////////////////////////////////////////////
875/// Test if any of the dependents of the arg tree (as determined by getObservables)
876/// overlaps with those of the testArg.
877
878Bool_t RooAbsArg::observableOverlaps(const RooArgSet* nset, const RooAbsArg& testArg) const
879{
880 RooArgSet* depList = getObservables(nset) ;
881 Bool_t ret = testArg.dependsOn(*depList) ;
882 delete depList ;
883 return ret ;
884}
885
886
887
888////////////////////////////////////////////////////////////////////////////////
889/// Mark this object as having changed its value, and propagate this status
890/// change to all of our clients. If the object is not in automatic dirty
891/// state propagation mode, this call has no effect.
892
894{
895 _allBatchesDirty = true;
896
897 if (_operMode!=Auto || _inhibitDirty) return ;
898
899 // Handle no-propagation scenarios first
900 if (_clientListValue.size() == 0) {
902 return ;
903 }
904
905 // Cyclical dependency interception
906 if (source==0) {
907 source=this ;
908 } else if (source==this) {
909 // Cyclical dependency, abort
910 coutE(LinkStateMgmt) << "RooAbsArg::setValueDirty(" << GetName()
911 << "): cyclical dependency detected, source = " << source->GetName() << endl ;
912 //assert(0) ;
913 return ;
914 }
915
916 // Propagate dirty flag to all clients if this is a down->up transition
917 if (_verboseDirty) {
918 cxcoutD(LinkStateMgmt) << "RooAbsArg::setValueDirty(" << (source?source->GetName():"self") << "->" << GetName() << "," << this
919 << "): dirty flag " << (_valueDirty?"already ":"") << "raised" << endl ;
920 }
921
923
924
925 for (auto client : _clientListValue) {
926 client->setValueDirty(source) ;
927 }
928
929
930}
931
932
933////////////////////////////////////////////////////////////////////////////////
934/// Mark this object as having changed its shape, and propagate this status
935/// change to all of our clients.
936
938{
939 if (_verboseDirty) {
940 cxcoutD(LinkStateMgmt) << "RooAbsArg::setShapeDirty(" << GetName()
941 << "): dirty flag " << (_shapeDirty?"already ":"") << "raised" << endl ;
942 }
943
944 if (_clientListShape.empty()) {
946 return ;
947 }
948
949 // Set 'dirty' shape state for this object and propagate flag to all its clients
950 if (source==0) {
951 source=this ;
952 } else if (source==this) {
953 // Cyclical dependency, abort
954 coutE(LinkStateMgmt) << "RooAbsArg::setShapeDirty(" << GetName()
955 << "): cyclical dependency detected" << endl ;
956 return ;
957 }
958
959 // Propagate dirty flag to all clients if this is a down->up transition
961
962 for (auto client : _clientListShape) {
963 client->setShapeDirty(source) ;
964 client->setValueDirty(source) ;
965 }
966
967}
968
969
970
971////////////////////////////////////////////////////////////////////////////////
972/// Replace all direct servers of this object with the new servers in `newServerList`.
973/// This substitutes objects that we receive values from with new objects that have the same name.
974/// \see recursiveRedirectServers() Use recursive version if servers that are only indirectly serving this object should be replaced as well.
975/// \see redirectServers() If only the direct servers of an object need to be replaced.
976///
977/// Note that changing the types of objects is generally allowed, but can be wrong if the interface of an object changes.
978/// For example, one can reparametrise a model by substituting a variable with a function:
979/// \f[
980/// f(x\, |\, a) = a \cdot x \rightarrow f(x\, |\, b) = (2.1 \cdot b) \cdot x
981/// \f]
982/// If an object, however, expects a PDF, and this is substituted with a function that isn't normalised, wrong results might be obtained
983/// or it might even crash the program. The types of the objects being substituted are not checked.
984///
985/// \param[in] newSetOrig Set of new servers that should be used instead of the current servers.
986/// \param[in] mustReplaceAll A warning is printed and error status is returned if not all servers could be
987/// substituted successfully.
988/// \param[in] nameChange If false, an object named "x" is replaced with an object named "x" in `newSetOrig`.
989/// If the object in `newSet` is called differently, set `nameChange` to true and use setStringAttribute on the x object:
990/// ```
991/// objectToReplaceX.setStringAttribute("ORIGNAME", "x")
992/// ```
993/// \param[in] isRecursionStep Internal switch used when called from recursiveRedirectServers().
994Bool_t RooAbsArg::redirectServers(const RooAbsCollection& newSetOrig, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t isRecursionStep)
995{
996 // Trivial case, no servers
997 if (_serverList.empty()) return kFALSE ;
998 if (newSetOrig.getSize()==0) return kFALSE ;
999
1000 // Strip any non-matching removal nodes from newSetOrig
1001 RooAbsCollection* newSet ;
1002
1003 if (nameChange) {
1004 newSet = new RooArgSet ;
1005 for (auto arg : newSetOrig) {
1006
1007 if (string("REMOVAL_DUMMY")==arg->GetName()) {
1008
1009 if (arg->getAttribute("REMOVE_ALL")) {
1010 newSet->add(*arg) ;
1011 } else if (arg->getAttribute(Form("REMOVE_FROM_%s",getStringAttribute("ORIGNAME")))) {
1012 newSet->add(*arg) ;
1013 }
1014 } else {
1015 newSet->add(*arg) ;
1016 }
1017 }
1018 } else {
1019 newSet = (RooAbsCollection*) &newSetOrig ;
1020 }
1021
1022 // Replace current servers with new servers with the same name from the given list
1023 Bool_t ret(kFALSE) ;
1024
1025 //Copy original server list to not confuse the iterator while deleting
1026 std::vector<RooAbsArg*> origServerList, origServerValue, origServerShape;
1027 auto origSize = _serverList.size();
1028 origServerList.reserve(origSize);
1029 origServerValue.reserve(origSize);
1030
1031 for (const auto oldServer : _serverList) {
1032 origServerList.push_back(oldServer) ;
1033
1034 // Retrieve server side link state information
1035 if (oldServer->_clientListValue.containsByNamePtr(this)) {
1036 origServerValue.push_back(oldServer) ;
1037 }
1038 if (oldServer->_clientListShape.containsByNamePtr(this)) {
1039 origServerShape.push_back(oldServer) ;
1040 }
1041 }
1042
1043 // Delete all previously registered servers
1044 for (auto oldServer : origServerList) {
1045
1046 RooAbsArg * newServer= oldServer->findNewServer(*newSet, nameChange);
1047
1048 if (newServer && _verboseDirty) {
1049 cxcoutD(LinkStateMgmt) << "RooAbsArg::redirectServers(" << (void*)this << "," << GetName() << "): server " << oldServer->GetName()
1050 << " redirected from " << oldServer << " to " << newServer << endl ;
1051 }
1052
1053 if (!newServer) {
1054 if (mustReplaceAll) {
1055 coutE(LinkStateMgmt) << "RooAbsArg::redirectServers(" << (void*)this << "," << GetName() << "): server " << oldServer->GetName()
1056 << " (" << (void*)oldServer << ") not redirected" << (nameChange?"[nameChange]":"") << endl ;
1057 ret = kTRUE ;
1058 }
1059 continue ;
1060 }
1061
1062 auto findByNamePtr = [&oldServer](const RooAbsArg * item) {
1063 return oldServer->namePtr() == item->namePtr();
1064 };
1065 bool propValue = std::any_of(origServerValue.begin(), origServerValue.end(), findByNamePtr);
1066 bool propShape = std::any_of(origServerShape.begin(), origServerShape.end(), findByNamePtr);
1067
1068 if (newServer != this) {
1069 replaceServer(*oldServer,*newServer,propValue,propShape) ;
1070 }
1071 }
1072
1073
1074 setValueDirty() ;
1075 setShapeDirty() ;
1076
1077 // Process the proxies
1078 for (int i=0 ; i<numProxies() ; i++) {
1079 RooAbsProxy* p = getProxy(i) ;
1080 if (!p) continue ;
1081 Bool_t ret2 = p->changePointer(*newSet,nameChange,kFALSE) ;
1082
1083 if (mustReplaceAll && !ret2) {
1084 auto ap = dynamic_cast<const RooArgProxy*>(p);
1085 coutE(LinkStateMgmt) << "RooAbsArg::redirectServers(" << GetName()
1086 << "): ERROR, proxy '" << p->name()
1087 << "' with arg '" << (ap ? ap->absArg()->GetName() : "<could not cast>") << "' could not be adjusted" << endl;
1088 ret = kTRUE ;
1089 }
1090 }
1091
1092
1093 // Optional subclass post-processing
1094 for (Int_t i=0 ;i<numCaches() ; i++) {
1095 ret |= getCache(i)->redirectServersHook(*newSet,mustReplaceAll,nameChange,isRecursionStep) ;
1096 }
1097 ret |= redirectServersHook(*newSet,mustReplaceAll,nameChange,isRecursionStep) ;
1098
1099 if (nameChange) {
1100 delete newSet ;
1101 }
1102
1103 return ret ;
1104}
1105
1106////////////////////////////////////////////////////////////////////////////////
1107/// Find the new server in the specified set that matches the old server.
1108/// Allow a name change if nameChange is kTRUE, in which case the new
1109/// server is selected by searching for a new server with an attribute
1110/// of "ORIGNAME:<oldName>". Return zero if there is not a unique match.
1111
1113{
1114 RooAbsArg *newServer = 0;
1115 if (!nameChange) {
1116 newServer = newSet.find(*this) ;
1117 }
1118 else {
1119 // Name changing server redirect:
1120 // use 'ORIGNAME:<oldName>' attribute instead of name of new server
1121 TString nameAttrib("ORIGNAME:") ;
1122 nameAttrib.Append(GetName()) ;
1123
1124 RooArgSet* tmp = (RooArgSet*) newSet.selectByAttrib(nameAttrib,kTRUE) ;
1125 if(0 != tmp) {
1126
1127 // Check if any match was found
1128 if (tmp->getSize()==0) {
1129 delete tmp ;
1130 return 0 ;
1131 }
1132
1133 // Check if match is unique
1134 if(tmp->getSize()>1) {
1135 coutF(LinkStateMgmt) << "RooAbsArg::redirectServers(" << GetName() << "): FATAL Error, " << tmp->getSize() << " servers with "
1136 << nameAttrib << " attribute" << endl ;
1137 tmp->Print("v") ;
1138 assert(0) ;
1139 }
1140
1141 // use the unique element in the set
1142 newServer= tmp->first();
1143 delete tmp ;
1144 }
1145 }
1146 return newServer;
1147}
1148
1149
1150////////////////////////////////////////////////////////////////////////////////
1151/// Recursively replace all servers with the new servers in `newSet`.
1152/// This substitutes objects that we receive values from (also indirectly through other objects) with new objects that have the same name.
1153///
1154/// *Copied from redirectServers:*
1155///
1156/// \copydetails RooAbsArg::redirectServers
1157Bool_t RooAbsArg::recursiveRedirectServers(const RooAbsCollection& newSet, Bool_t mustReplaceAll, Bool_t nameChange, Bool_t recurseInNewSet)
1158{
1159 // Cyclic recursion protection
1160 static std::set<const RooAbsArg*> callStack;
1161 {
1162 std::set<const RooAbsArg*>::iterator it = callStack.lower_bound(this);
1163 if (it != callStack.end() && this == *it) {
1164 return kFALSE;
1165 } else {
1166 callStack.insert(it, this);
1167 }
1168 }
1169
1170 // Do not recurse into newset if not so specified
1171// if (!recurseInNewSet && newSet.contains(*this)) {
1172// return kFALSE ;
1173// }
1174
1175
1176 // Apply the redirectServers function recursively on all branch nodes in this argument tree.
1177 Bool_t ret(kFALSE) ;
1178
1179 cxcoutD(LinkStateMgmt) << "RooAbsArg::recursiveRedirectServers(" << this << "," << GetName() << ") newSet = " << newSet << " mustReplaceAll = "
1180 << (mustReplaceAll?"T":"F") << " nameChange = " << (nameChange?"T":"F") << " recurseInNewSet = " << (recurseInNewSet?"T":"F") << endl ;
1181
1182 // Do redirect on self (identify operation as recursion step)
1183 ret |= redirectServers(newSet,mustReplaceAll,nameChange,kTRUE) ;
1184
1185 // Do redirect on servers
1186 for (const auto server : _serverList){
1187 ret |= server->recursiveRedirectServers(newSet,mustReplaceAll,nameChange,recurseInNewSet) ;
1188 }
1189
1190 callStack.erase(this);
1191 return ret ;
1192}
1193
1194
1195
1196////////////////////////////////////////////////////////////////////////////////
1197/// Register an RooArgProxy in the proxy list. This function is called by owned
1198/// proxies upon creation. After registration, this arg wil forward pointer
1199/// changes from serverRedirects and updates in cached normalization sets
1200/// to the proxies immediately after they occur. The proxied argument is
1201/// also added as value and/or shape server
1202
1204{
1205 // Every proxy can be registered only once
1206 if (_proxyList.FindObject(&proxy)) {
1207 coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
1208 << proxy.GetName() << " for arg " << proxy.absArg()->GetName()
1209 << " already registered" << endl ;
1210 return ;
1211 }
1212
1213// cout << (void*)this << " " << GetName() << ": registering proxy "
1214// << (void*)&proxy << " with name " << proxy.name() << " in mode "
1215// << (proxy.isValueServer()?"V":"-") << (proxy.isShapeServer()?"S":"-") << endl ;
1216
1217 // Register proxied object as server
1218 if (proxy.absArg()) {
1219 addServer(*proxy.absArg(),proxy.isValueServer(),proxy.isShapeServer()) ;
1220 }
1221
1222 // Register proxy itself
1223 _proxyList.Add(&proxy) ;
1224}
1225
1226
1227////////////////////////////////////////////////////////////////////////////////
1228/// Remove proxy from proxy list. This functions is called by owned proxies
1229/// upon their destruction.
1230
1232{
1233 _proxyList.Remove(&proxy) ;
1235}
1236
1237
1238
1239////////////////////////////////////////////////////////////////////////////////
1240/// Register an RooSetProxy in the proxy list. This function is called by owned
1241/// proxies upon creation. After registration, this arg wil forward pointer
1242/// changes from serverRedirects and updates in cached normalization sets
1243/// to the proxies immediately after they occur.
1244
1246{
1247 // Every proxy can be registered only once
1248 if (_proxyList.FindObject(&proxy)) {
1249 coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
1250 << proxy.GetName() << " already registered" << endl ;
1251 return ;
1252 }
1253
1254 // Register proxy itself
1255 _proxyList.Add(&proxy) ;
1256}
1257
1258
1259
1260////////////////////////////////////////////////////////////////////////////////
1261/// Remove proxy from proxy list. This functions is called by owned proxies
1262/// upon their destruction.
1263
1265{
1266 _proxyList.Remove(&proxy) ;
1268}
1269
1270
1271
1272////////////////////////////////////////////////////////////////////////////////
1273/// Register an RooListProxy in the proxy list. This function is called by owned
1274/// proxies upon creation. After registration, this arg wil forward pointer
1275/// changes from serverRedirects and updates in cached normalization sets
1276/// to the proxies immediately after they occur.
1277
1279{
1280 // Every proxy can be registered only once
1281 if (_proxyList.FindObject(&proxy)) {
1282 coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named "
1283 << proxy.GetName() << " already registered" << endl ;
1284 return ;
1285 }
1286
1287 // Register proxy itself
1288 Int_t nProxyOld = _proxyList.GetEntries() ;
1289 _proxyList.Add(&proxy) ;
1290 if (_proxyList.GetEntries()!=nProxyOld+1) {
1291 cout << "RooAbsArg::registerProxy(" << GetName() << ") proxy registration failure! nold=" << nProxyOld << " nnew=" << _proxyList.GetEntries() << endl ;
1292 }
1293}
1294
1295
1296
1297////////////////////////////////////////////////////////////////////////////////
1298/// Remove proxy from proxy list. This functions is called by owned proxies
1299/// upon their destruction.
1300
1302{
1303 _proxyList.Remove(&proxy) ;
1305}
1306
1307
1308
1309////////////////////////////////////////////////////////////////////////////////
1310/// Return the nth proxy from the proxy list.
1311
1313{
1314 // Cross cast: proxy list returns TObject base pointer, we need
1315 // a RooAbsProxy base pointer. C++ standard requires
1316 // a dynamic_cast for this.
1317 return dynamic_cast<RooAbsProxy*> (_proxyList.At(index)) ;
1318}
1319
1320
1321
1322////////////////////////////////////////////////////////////////////////////////
1323/// Return the number of registered proxies.
1324
1326{
1327 return _proxyList.GetEntriesFast();
1328}
1329
1330
1331
1332////////////////////////////////////////////////////////////////////////////////
1333/// Forward a change in the cached normalization argset
1334/// to all the registered proxies.
1335
1337{
1338 for (int i=0 ; i<numProxies() ; i++) {
1339 RooAbsProxy* p = getProxy(i) ;
1340 if (!p) continue ;
1341 getProxy(i)->changeNormSet(nset) ;
1342 }
1343}
1344
1345
1346
1347////////////////////////////////////////////////////////////////////////////////
1348/// Overloadable function for derived classes to implement
1349/// attachment as branch to a TTree
1350
1352{
1353 coutE(Contents) << "RooAbsArg::attachToTree(" << GetName()
1354 << "): Cannot be attached to a TTree" << endl ;
1355}
1356
1357
1358
1359////////////////////////////////////////////////////////////////////////////////
1360/// WVE (08/21/01) Probably obsolete now
1361
1363{
1364 return kTRUE ;
1365}
1366
1367
1368
1369
1370////////////////////////////////////////////////////////////////////////////////
1371/// Print object name
1372
1373void RooAbsArg::printName(ostream& os) const
1374{
1375 os << GetName() ;
1376}
1377
1378
1379
1380////////////////////////////////////////////////////////////////////////////////
1381/// Print object title
1382
1383void RooAbsArg::printTitle(ostream& os) const
1384{
1385 os << GetTitle() ;
1386}
1387
1388
1389
1390////////////////////////////////////////////////////////////////////////////////
1391/// Print object class name
1392
1393void RooAbsArg::printClassName(ostream& os) const
1394{
1395 os << IsA()->GetName() ;
1396}
1397
1398
1399void RooAbsArg::printAddress(ostream& os) const
1400{
1401 // Print addrss of this RooAbsArg
1402 os << this ;
1403}
1404
1405
1406
1407////////////////////////////////////////////////////////////////////////////////
1408/// Print object arguments, ie its proxies
1409
1410void RooAbsArg::printArgs(ostream& os) const
1411{
1412 // Print nothing if there are no dependencies
1413 if (numProxies()==0) return ;
1414
1415 os << "[ " ;
1416 for (Int_t i=0 ; i<numProxies() ; i++) {
1417 RooAbsProxy* p = getProxy(i) ;
1418 if (p==0) continue ;
1419 if (!TString(p->name()).BeginsWith("!")) {
1420 p->print(os) ;
1421 os << " " ;
1422 }
1423 }
1424 printMetaArgs(os) ;
1425 os << "]" ;
1426}
1427
1428
1429
1430////////////////////////////////////////////////////////////////////////////////
1431/// Define default contents to print
1432
1434{
1435 return kName|kClassName|kValue|kArgs ;
1436}
1437
1438
1439
1440////////////////////////////////////////////////////////////////////////////////
1441/// Implement multi-line detailed printing
1442
1443void RooAbsArg::printMultiline(ostream& os, Int_t /*contents*/, Bool_t /*verbose*/, TString indent) const
1444{
1445 os << indent << "--- RooAbsArg ---" << endl;
1446 // dirty state flags
1447 os << indent << " Value State: " ;
1448 switch(_operMode) {
1449 case ADirty: os << "FORCED DIRTY" ; break ;
1450 case AClean: os << "FORCED clean" ; break ;
1451 case Auto: os << (isValueDirty() ? "DIRTY":"clean") ; break ;
1452 }
1453 os << endl
1454 << indent << " Shape State: " << (isShapeDirty() ? "DIRTY":"clean") << endl;
1455 // attribute list
1456 os << indent << " Attributes: " ;
1457 printAttribList(os) ;
1458 os << endl ;
1459 // our memory address (for x-referencing with client addresses of other args)
1460 os << indent << " Address: " << (void*)this << endl;
1461 // client list
1462 os << indent << " Clients: " << endl;
1463 for (const auto client : _clientList) {
1464 os << indent << " (" << (void*)client << ","
1465 << (_clientListValue.containsByNamePtr(client)?"V":"-")
1466 << (_clientListShape.containsByNamePtr(client)?"S":"-")
1467 << ") " ;
1468 client->printStream(os,kClassName|kTitle|kName,kSingleLine);
1469 }
1470
1471 // server list
1472 os << indent << " Servers: " << endl;
1473 for (const auto server : _serverList) {
1474 os << indent << " (" << (void*)server << ","
1475 << (server->_clientListValue.containsByNamePtr(this)?"V":"-")
1476 << (server->_clientListShape.containsByNamePtr(this)?"S":"-")
1477 << ") " ;
1478 server->printStream(os,kClassName|kName|kTitle,kSingleLine);
1479 }
1480
1481 // proxy list
1482 os << indent << " Proxies: " << endl ;
1483 for (int i=0 ; i<numProxies() ; i++) {
1484 RooAbsProxy* proxy=getProxy(i) ;
1485 if (!proxy) continue ;
1486 if (proxy->IsA()->InheritsFrom(RooArgProxy::Class())) {
1487 os << indent << " " << proxy->name() << " -> " ;
1488 RooAbsArg* parg = ((RooArgProxy*)proxy)->absArg() ;
1489 if (parg) {
1490 parg->printStream(os,kName,kSingleLine) ;
1491 } else {
1492 os << " (empty)" << endl ; ;
1493 }
1494 } else {
1495 os << indent << " " << proxy->name() << " -> " ;
1496 os << endl ;
1497 TString moreIndent(indent) ;
1498 moreIndent.Append(" ") ;
1499 ((RooSetProxy*)proxy)->printStream(os,kName,kStandard,moreIndent.Data()) ;
1500 }
1501 }
1502}
1503
1504
1505////////////////////////////////////////////////////////////////////////////////
1506/// Print object tree structure
1507
1508void RooAbsArg::printTree(ostream& os, TString /*indent*/) const
1509{
1510 const_cast<RooAbsArg*>(this)->printCompactTree(os) ;
1511}
1512
1513
1514////////////////////////////////////////////////////////////////////////////////
1515/// Ostream operator
1516
1517ostream& operator<<(ostream& os, RooAbsArg &arg)
1518{
1519 arg.writeToStream(os,kTRUE) ;
1520 return os ;
1521}
1522
1523////////////////////////////////////////////////////////////////////////////////
1524/// Istream operator
1525
1526istream& operator>>(istream& is, RooAbsArg &arg)
1527{
1528 arg.readFromStream(is,kTRUE,kFALSE) ;
1529 return is ;
1530}
1531
1532////////////////////////////////////////////////////////////////////////////////
1533/// Print the attribute list
1534
1535void RooAbsArg::printAttribList(ostream& os) const
1536{
1537 set<string>::const_iterator iter = _boolAttrib.begin() ;
1538 Bool_t first(kTRUE) ;
1539 while (iter != _boolAttrib.end()) {
1540 os << (first?" [":",") << *iter ;
1541 first=kFALSE ;
1542 ++iter ;
1543 }
1544 if (!first) os << "] " ;
1545}
1546
1547////////////////////////////////////////////////////////////////////////////////
1548/// Replace server nodes with names matching the dataset variable names
1549/// with those data set variables, making this PDF directly dependent on the dataset.
1550
1552{
1553 const RooArgSet* set = data.get() ;
1554 RooArgSet branches ;
1555 branchNodeServerList(&branches,0,kTRUE) ;
1556
1557 RooFIter iter = branches.fwdIterator() ;
1558 RooAbsArg* branch ;
1559 while((branch=iter.next())) {
1560 branch->redirectServers(*set,kFALSE,kFALSE) ;
1561 }
1562}
1563
1564
1565
1566////////////////////////////////////////////////////////////////////////////////
1567/// Replace server nodes with names matching the dataset variable names
1568/// with those data set variables, making this PDF directly dependent on the dataset
1569
1571{
1572 const RooArgSet* set = dstore.get() ;
1573 RooArgSet branches ;
1574 branchNodeServerList(&branches,0,kTRUE) ;
1575
1576 RooFIter iter = branches.fwdIterator() ;
1577 RooAbsArg* branch ;
1578 while((branch=iter.next())) {
1579 branch->redirectServers(*set,kFALSE,kFALSE) ;
1580 }
1581}
1582
1583
1584
1585////////////////////////////////////////////////////////////////////////////////
1586/// Utility function used by TCollection::Sort to compare contained TObjects
1587/// We implement comparison by name, resulting in alphabetical sorting by object name.
1588
1590{
1591 return strcmp(GetName(),other->GetName()) ;
1592}
1593
1594
1595
1596////////////////////////////////////////////////////////////////////////////////
1597/// Print information about current value dirty state information.
1598/// If depth flag is true, information is recursively printed for
1599/// all nodes in this arg tree.
1600
1602{
1603 if (depth) {
1604
1605 RooArgSet branchList ;
1606 branchNodeServerList(&branchList) ;
1607 RooFIter bIter = branchList.fwdIterator() ;
1608 RooAbsArg* branch ;
1609 while((branch=bIter.next())) {
1610 branch->printDirty(kFALSE) ;
1611 }
1612
1613 } else {
1614 cout << GetName() << " : " ;
1615 switch (_operMode) {
1616 case AClean: cout << "FORCED clean" ; break ;
1617 case ADirty: cout << "FORCED DIRTY" ; break ;
1618 case Auto: cout << "Auto " << (isValueDirty()?"DIRTY":"clean") ;
1619 }
1620 cout << endl ;
1621 }
1622}
1623
1624
1625////////////////////////////////////////////////////////////////////////////////
1626/// Activate cache mode optimization with given definition of observables.
1627/// The cache operation mode of all objects in the expression tree will
1628/// modified such that all nodes that depend directly or indirectly on
1629/// any of the listed observables will be set to ADirty, as they are
1630/// expected to change every time. This save change tracking overhead for
1631/// nodes that are a priori known to change every time
1632
1634{
1635 RooLinkedList proc;
1636 RooArgSet opt ;
1637 optimizeCacheMode(observables,opt,proc) ;
1638
1639 coutI(Optimization) << "RooAbsArg::optimizeCacheMode(" << GetName() << ") nodes " << opt << " depend on observables, "
1640 << "changing cache operation mode from change tracking to unconditional evaluation" << endl ;
1641}
1642
1643
1644////////////////////////////////////////////////////////////////////////////////
1645/// Activate cache mode optimization with given definition of observables.
1646/// The cache operation mode of all objects in the expression tree will
1647/// modified such that all nodes that depend directly or indirectly on
1648/// any of the listed observables will be set to ADirty, as they are
1649/// expected to change every time. This save change tracking overhead for
1650/// nodes that are a priori known to change every time
1651
1652void RooAbsArg::optimizeCacheMode(const RooArgSet& observables, RooArgSet& optimizedNodes, RooLinkedList& processedNodes)
1653{
1654 // Optimization applies only to branch nodes, not to leaf nodes
1655 if (!isDerived()) {
1656 return ;
1657 }
1658
1659
1660 // Terminate call if this node was already processed (tree structure may be cyclical)
1661 // LM : RooLinkedList::findArg looks by name and not but by object pointer,
1662 // should one use RooLinkedList::FindObject (look byt pointer) instead of findArg when
1663 // tree contains nodes with the same name ?
1664 // Add an info message if the require node does not exist but a different node already exists with same name
1665
1666 if (processedNodes.FindObject(this))
1667 return;
1668
1669 // check if findArgs returns something different (i.e. a different node with same name) when
1670 // this node has not been processed (FindObject returns a null pointer)
1671 auto obj = processedNodes.findArg(this);
1672 assert(obj != this); // obj == this cannot happen
1673 if (obj)
1674 // here for nodes with duplicate names
1675 cxcoutI(Optimization) << "RooAbsArg::optimizeCacheMode(" << GetName()
1676 << " node " << this << " exists already as " << obj << " but with the SAME name !" << endl;
1677
1678 processedNodes.Add(this);
1679
1680 // Set cache mode operator to 'AlwaysDirty' if we depend on any of the given observables
1681 if (dependsOnValue(observables)) {
1682
1683 if (dynamic_cast<RooRealIntegral*>(this)) {
1684 cxcoutI(Integration) << "RooAbsArg::optimizeCacheMode(" << GetName() << ") integral depends on value of one or more observables and will be evaluated for every event" << endl ;
1685 }
1686 optimizedNodes.add(*this,kTRUE) ;
1687 if (operMode()==AClean) {
1688 } else {
1689 setOperMode(ADirty,kTRUE) ; // WVE propagate flag recursively to top of tree
1690 }
1691 } else {
1692 }
1693 // Process any RooAbsArgs contained in any of the caches of this object
1694 for (Int_t i=0 ;i<numCaches() ; i++) {
1695 getCache(i)->optimizeCacheMode(observables,optimizedNodes,processedNodes) ;
1696 }
1697
1698 // Forward calls to all servers
1699 for (const auto server : _serverList) {
1700 server->optimizeCacheMode(observables,optimizedNodes,processedNodes) ;
1701 }
1702
1703}
1704
1705////////////////////////////////////////////////////////////////////////////////
1706/// Find branch nodes with all-constant parameters, and add them to the list of
1707/// nodes that can be cached with a dataset in a test statistic calculation
1708
1710{
1711 RooLinkedList proc ;
1712 Bool_t ret = findConstantNodes(observables,cacheList,proc) ;
1713
1714 // If node can be optimized and hasn't been identified yet, add it to the list
1715 coutI(Optimization) << "RooAbsArg::findConstantNodes(" << GetName() << "): components "
1716 << cacheList << " depend exclusively on constant parameters and will be precalculated and cached" << endl ;
1717
1718 return ret ;
1719}
1720
1721
1722
1723////////////////////////////////////////////////////////////////////////////////
1724/// Find branch nodes with all-constant parameters, and add them to the list of
1725/// nodes that can be cached with a dataset in a test statistic calculation
1726
1727Bool_t RooAbsArg::findConstantNodes(const RooArgSet& observables, RooArgSet& cacheList, RooLinkedList& processedNodes)
1728{
1729 // Caching only applies to branch nodes
1730 if (!isDerived()) {
1731 return kFALSE;
1732 }
1733
1734 // Terminate call if this node was already processed (tree structure may be cyclical)
1735 if (processedNodes.findArg(this)) {
1736 return kFALSE ;
1737 } else {
1738 processedNodes.Add(this) ;
1739 }
1740
1741 // Check if node depends on any non-constant parameter
1742 Bool_t canOpt(kTRUE) ;
1743 RooArgSet* paramSet = getParameters(observables) ;
1744 RooFIter iter = paramSet->fwdIterator() ;
1745 RooAbsArg* param ;
1746 while((param = iter.next())) {
1747 if (!param->isConstant()) {
1748 canOpt=kFALSE ;
1749 break ;
1750 }
1751 }
1752 delete paramSet ;
1753
1754
1755 if (getAttribute("NeverConstant")) {
1756 canOpt = kFALSE ;
1757 }
1758
1759 if (canOpt) {
1760 setAttribute("ConstantExpression") ;
1761 }
1762
1763 // If yes, list node eligible for caching, if not test nodes one level down
1764 if (canOpt||getAttribute("CacheAndTrack")) {
1765
1766 if (!cacheList.find(*this) && dependsOnValue(observables) && !observables.find(*this) ) {
1767
1768 // Add to cache list
1769 cxcoutD(Optimization) << "RooAbsArg::findConstantNodes(" << GetName() << ") adding self to list of constant nodes" << endl ;
1770
1771 if (canOpt) setAttribute("ConstantExpressionCached") ;
1772 cacheList.add(*this,kFALSE) ;
1773 }
1774 }
1775
1776 if (!canOpt) {
1777
1778 // If not, see if next level down can be cached
1779 for (const auto server : _serverList) {
1780 if (server->isDerived()) {
1781 server->findConstantNodes(observables,cacheList,processedNodes) ;
1782 }
1783 }
1784 }
1785
1786 // Forward call to all cached contained in current object
1787 for (Int_t i=0 ;i<numCaches() ; i++) {
1788 getCache(i)->findConstantNodes(observables,cacheList,processedNodes) ;
1789 }
1790
1791 return kFALSE ;
1792}
1793
1794
1795
1796
1797////////////////////////////////////////////////////////////////////////////////
1798/// Interface function signaling a request to perform constant term
1799/// optimization. This default implementation takes no action other than to
1800/// forward the calls to all servers
1801
1803{
1804 for (const auto server : _serverList) {
1805 server->constOptimizeTestStatistic(opcode,doAlsoTrackingOpt) ;
1806 }
1807}
1808
1809
1810////////////////////////////////////////////////////////////////////////////////
1811/// Change cache operation mode to given mode. If recurseAdirty
1812/// is true, then a mode change to AlwaysDirty will automatically
1813/// be propagated recursively to all client nodes
1814
1815void RooAbsArg::setOperMode(OperMode mode, Bool_t recurseADirty)
1816{
1817 // Prevent recursion loops
1818 if (mode==_operMode) return ;
1819
1820 _operMode = mode ;
1821 _fast = ((mode==AClean) || dynamic_cast<RooRealVar*>(this)!=0 || dynamic_cast<RooConstVar*>(this)!=0 ) ;
1822 for (Int_t i=0 ;i<numCaches() ; i++) {
1823 getCache(i)->operModeHook() ;
1824 }
1825 operModeHook() ;
1826
1827 // Propagate to all clients
1828 if (mode==ADirty && recurseADirty) {
1829 for (auto clientV : _clientListValue) {
1830 clientV->setOperMode(mode) ;
1831 }
1832 }
1833}
1834
1835
1836////////////////////////////////////////////////////////////////////////////////
1837/// Print tree structure of expression tree on stdout, or to file if filename is specified.
1838/// If namePat is not "*", only nodes with names matching the pattern will be printed.
1839/// The client argument is used in recursive calls to properly display the value or shape nature
1840/// of the client-server links. It should be zero in calls initiated by users.
1841
1842void RooAbsArg::printCompactTree(const char* indent, const char* filename, const char* namePat, RooAbsArg* client)
1843{
1844 if (filename) {
1845 ofstream ofs(filename) ;
1846 printCompactTree(ofs,indent,namePat,client) ;
1847 } else {
1848 printCompactTree(cout,indent,namePat,client) ;
1849 }
1850}
1851
1852
1853////////////////////////////////////////////////////////////////////////////////
1854/// Print tree structure of expression tree on given ostream.
1855/// If namePat is not "*", only nodes with names matching the pattern will be printed.
1856/// The client argument is used in recursive calls to properly display the value or shape nature
1857/// of the client-server links. It should be zero in calls initiated by users.
1858
1859void RooAbsArg::printCompactTree(ostream& os, const char* indent, const char* namePat, RooAbsArg* client)
1860{
1861 if ( !namePat || TString(GetName()).Contains(namePat)) {
1862 os << indent << this ;
1863 if (client) {
1864 os << "/" ;
1865 if (isValueServer(*client)) os << "V" ; else os << "-" ;
1866 if (isShapeServer(*client)) os << "S" ; else os << "-" ;
1867 }
1868 os << " " ;
1869
1870 os << IsA()->GetName() << "::" << GetName() << " = " ;
1871 printValue(os) ;
1872
1873 if (!_serverList.empty()) {
1874 switch(operMode()) {
1875 case Auto: os << " [Auto," << (isValueDirty()?"Dirty":"Clean") << "] " ; break ;
1876 case AClean: os << " [ACLEAN] " ; break ;
1877 case ADirty: os << " [ADIRTY] " ; break ;
1878 }
1879 }
1880 os << endl ;
1881
1882 for (Int_t i=0 ;i<numCaches() ; i++) {
1884 }
1886 }
1887
1888 TString indent2(indent) ;
1889 indent2 += " " ;
1890 for (const auto arg : _serverList) {
1891 arg->printCompactTree(os,indent2,namePat,this) ;
1892 }
1893}
1894
1895
1896////////////////////////////////////////////////////////////////////////////////
1897/// Print tree structure of expression tree on given ostream, only branch nodes are printed.
1898/// Lead nodes (variables) will not be shown
1899///
1900/// If namePat is not "*", only nodes with names matching the pattern will be printed.
1901
1902void RooAbsArg::printComponentTree(const char* indent, const char* namePat, Int_t nLevel)
1903{
1904 if (nLevel==0) return ;
1905 if (isFundamental()) return ;
1906 RooResolutionModel* rmodel = dynamic_cast<RooResolutionModel*>(this) ;
1907 if (rmodel && rmodel->isConvolved()) return ;
1908 if (InheritsFrom("RooConstVar")) return ;
1909
1910 if ( !namePat || TString(GetName()).Contains(namePat)) {
1911 cout << indent ;
1912 Print() ;
1913 }
1914
1915 TString indent2(indent) ;
1916 indent2 += " " ;
1917 for (const auto arg : _serverList) {
1918 arg->printComponentTree(indent2.Data(),namePat,nLevel-1) ;
1919 }
1920}
1921
1922
1923////////////////////////////////////////////////////////////////////////////////
1924/// Construct a mangled name from the actual name that
1925/// is free of any math symbols that might be interpreted by TTree
1926
1928{
1929 // Check for optional alternate name of branch for this argument
1930 TString rawBranchName = GetName() ;
1931 if (getStringAttribute("BranchName")) {
1932 rawBranchName = getStringAttribute("BranchName") ;
1933 }
1934
1935 TString cleanName(rawBranchName) ;
1936 cleanName.ReplaceAll("/","D") ;
1937 cleanName.ReplaceAll("-","M") ;
1938 cleanName.ReplaceAll("+","P") ;
1939 cleanName.ReplaceAll("*","X") ;
1940 cleanName.ReplaceAll("[","L") ;
1941 cleanName.ReplaceAll("]","R") ;
1942 cleanName.ReplaceAll("(","L") ;
1943 cleanName.ReplaceAll(")","R") ;
1944 cleanName.ReplaceAll("{","L") ;
1945 cleanName.ReplaceAll("}","R") ;
1946
1947 return cleanName;
1948}
1949
1950
1951////////////////////////////////////////////////////////////////////////////////
1952/// Hook function interface for object to insert additional information
1953/// when printed in the context of a tree structure. This default
1954/// implementation prints nothing
1955
1956void RooAbsArg::printCompactTreeHook(ostream&, const char *)
1957{
1958}
1959
1960
1961////////////////////////////////////////////////////////////////////////////////
1962/// Register RooAbsCache with this object. This function is called
1963/// by RooAbsCache constructors for objects that are a datamember
1964/// of this RooAbsArg. By registering itself the RooAbsArg is aware
1965/// of all its cache data members and will forward server change
1966/// and cache mode change calls to the cache objects, which in turn
1967/// can forward them their contents
1968
1970{
1971 _cacheList.push_back(&cache) ;
1972}
1973
1974
1975////////////////////////////////////////////////////////////////////////////////
1976/// Unregister a RooAbsCache. Called from the RooAbsCache destructor
1977
1979{
1980 _cacheList.erase(std::remove(_cacheList.begin(), _cacheList.end(), &cache),
1981 _cacheList.end());
1982}
1983
1984
1985////////////////////////////////////////////////////////////////////////////////
1986/// Return number of registered caches
1987
1989{
1990 return _cacheList.size() ;
1991}
1992
1993
1994////////////////////////////////////////////////////////////////////////////////
1995/// Return registered cache object by index
1996
1998{
1999 return _cacheList[index] ;
2000}
2001
2002
2003////////////////////////////////////////////////////////////////////////////////
2004/// Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
2005
2007{
2008 return getParameters(RooArgSet(),stripDisconnected) ;
2009}
2010
2011
2012////////////////////////////////////////////////////////////////////////////////
2013/// Return ancestors in cloning chain of this RooAbsArg. NOTE: Returned pointers
2014/// are not guaranteed to be 'live', so do not dereference without proper caution
2015
2017{
2018 RooLinkedList retVal ;
2019
2020 set<string>::const_iterator iter= _boolAttrib.begin() ;
2021 while(iter != _boolAttrib.end()) {
2022 if (TString(*iter).BeginsWith("CloneOf(")) {
2023 char buf[128] ;
2024 strlcpy(buf,iter->c_str(),128) ;
2025 strtok(buf,"(") ;
2026 char* ptrToken = strtok(0,")") ;
2027 RooAbsArg* ptr = (RooAbsArg*) strtol(ptrToken,0,16) ;
2028 retVal.Add(ptr) ;
2029 }
2030 }
2031
2032 return retVal ;
2033}
2034
2035
2036////////////////////////////////////////////////////////////////////////////////
2037/// Create a GraphViz .dot file visualizing the expression tree headed by
2038/// this RooAbsArg object. Use the GraphViz tool suite to make e.g. a gif
2039/// or ps file from the .dot file
2040///
2041/// Based on concept developed by Kyle Cranmer
2042
2043void RooAbsArg::graphVizTree(const char* fileName, const char* delimiter, bool useTitle, bool useLatex)
2044{
2045 ofstream ofs(fileName) ;
2046 if (!ofs) {
2047 coutE(InputArguments) << "RooAbsArg::graphVizTree() ERROR: Cannot open graphViz output file with name " << fileName << endl ;
2048 return ;
2049 }
2050 graphVizTree(ofs, delimiter, useTitle, useLatex) ;
2051}
2052
2053////////////////////////////////////////////////////////////////////////////////
2054/// Write the GraphViz representation of the expression tree headed by
2055/// this RooAbsArg object to the given ostream.
2056///
2057/// Based on concept developed by Kyle Cranmer
2058
2059void RooAbsArg::graphVizTree(ostream& os, const char* delimiter, bool useTitle, bool useLatex)
2060{
2061 if (!os) {
2062 coutE(InputArguments) << "RooAbsArg::graphVizTree() ERROR: output stream provided as input argument is in invalid state" << endl ;
2063 }
2064
2065 // silent warning messages coming when evaluating a RooAddPdf without a normalization set
2067
2068 // Write header
2069 os << "digraph \"" << GetName() << "\"{" << endl ;
2070
2071 // First list all the tree nodes
2072 RooArgSet nodeSet ;
2073 treeNodeServerList(&nodeSet) ;
2074 RooFIter iter = nodeSet.fwdIterator() ;
2075 RooAbsArg* node ;
2076
2077 // iterate over nodes
2078 while((node=iter.next())) {
2079 string nodeName = node->GetName();
2080 string nodeTitle = node->GetTitle();
2081 string nodeLabel = (useTitle && !nodeTitle.empty()) ? nodeTitle : nodeName;
2082
2083 // if using latex, replace ROOT's # with normal latex backslash
2084 string::size_type position = nodeLabel.find("#") ;
2085 while(useLatex && position!=nodeLabel.npos){
2086 nodeLabel.replace(position, 1, "\\");
2087 }
2088
2089 string typeFormat = "\\texttt{";
2090 string nodeType = (useLatex) ? typeFormat+node->IsA()->GetName()+"}" : node->IsA()->GetName();
2091
2092 os << "\"" << nodeName << "\" [ color=" << (node->isFundamental()?"blue":"red")
2093 << ", label=\"" << nodeType << delimiter << nodeLabel << "\"];" << endl ;
2094
2095 }
2096
2097 // Get set of all server links
2098 set<pair<RooAbsArg*,RooAbsArg*> > links ;
2099 graphVizAddConnections(links) ;
2100
2101 // And write them out
2102 for(auto const& link : links) {
2103 os << "\"" << link.first->GetName() << "\" -> \"" << link.second->GetName() << "\";" << endl ;
2104 }
2105
2106 // Write trailer
2107 os << "}" << endl ;
2108
2109}
2110
2111////////////////////////////////////////////////////////////////////////////////
2112/// Utility function that inserts all point-to-point client-server connections
2113/// between any two RooAbsArgs in the expression tree headed by this object
2114/// in the linkSet argument.
2115
2116void RooAbsArg::graphVizAddConnections(set<pair<RooAbsArg*,RooAbsArg*> >& linkSet)
2117{
2118 for (const auto server : _serverList) {
2119 linkSet.insert(make_pair(this,server)) ;
2120 server->graphVizAddConnections(linkSet) ;
2121 }
2122}
2123
2124
2125
2126// //_____________________________________________________________________________
2127// TGraphStruct* RooAbsArg::graph(Bool_t useFactoryTag, Double_t textSize)
2128// {
2129// // Return a TGraphStruct object filled with the tree structure of the pdf object
2130
2131// TGraphStruct* theGraph = new TGraphStruct() ;
2132
2133// // First list all the tree nodes
2134// RooArgSet nodeSet ;
2135// treeNodeServerList(&nodeSet) ;
2136// TIterator* iter = nodeSet.createIterator() ;
2137// RooAbsArg* node ;
2138
2139
2140// // iterate over nodes
2141// while((node=(RooAbsArg*)iter->Next())) {
2142
2143// // Skip node that represent numeric constants
2144// if (node->IsA()->InheritsFrom(RooConstVar::Class())) continue ;
2145
2146// string nodeName ;
2147// if (useFactoryTag && node->getStringAttribute("factory_tag")) {
2148// nodeName = node->getStringAttribute("factory_tag") ;
2149// } else {
2150// if (node->isFundamental()) {
2151// nodeName = node->GetName();
2152// } else {
2153// ostringstream oss ;
2154// node->printStream(oss,(node->defaultPrintContents(0)&(~kValue)),node->defaultPrintStyle(0)) ;
2155// nodeName= oss.str() ;
2156// // nodeName = Form("%s::%s",node->IsA()->GetName(),node->GetName());
2157
2158// }
2159// }
2160// if (strncmp(nodeName.c_str(),"Roo",3)==0) {
2161// nodeName = string(nodeName.c_str()+3) ;
2162// }
2163// node->setStringAttribute("graph_name",nodeName.c_str()) ;
2164
2165// TGraphNode* gnode = theGraph->AddNode(nodeName.c_str(),nodeName.c_str()) ;
2166// gnode->SetLineWidth(2) ;
2167// gnode->SetTextColor(node->isFundamental()?kBlue:kRed) ;
2168// gnode->SetTextSize(textSize) ;
2169// }
2170// delete iter ;
2171
2172// // Get set of all server links
2173// set<pair<RooAbsArg*,RooAbsArg*> > links ;
2174// graphVizAddConnections(links) ;
2175
2176// // And insert them into the graph
2177// set<pair<RooAbsArg*,RooAbsArg*> >::iterator liter = links.begin() ;
2178// for( ; liter != links.end() ; ++liter ) {
2179
2180// TGraphNode* n1 = (TGraphNode*)theGraph->GetListOfNodes()->FindObject(liter->first->getStringAttribute("graph_name")) ;
2181// TGraphNode* n2 = (TGraphNode*)theGraph->GetListOfNodes()->FindObject(liter->second->getStringAttribute("graph_name")) ;
2182// if (n1 && n2) {
2183// TGraphEdge* edge = theGraph->AddEdge(n1,n2) ;
2184// edge->SetLineWidth(2) ;
2185// }
2186// }
2187
2188// return theGraph ;
2189// }
2190
2191
2192
2193// //_____________________________________________________________________________
2194// Bool_t RooAbsArg::inhibitDirty()
2195// {
2196// // Return current status of the inhibitDirty global flag. If true
2197// // no dirty state change tracking occurs and all caches are considered
2198// // to be always dirty.
2199// return _inhibitDirty ;
2200// }
2201
2202
2203////////////////////////////////////////////////////////////////////////////////
2204/// Take ownership of the contents of 'comps'
2205
2207{
2208 if (!_ownedComponents) {
2209 _ownedComponents = new RooArgSet("owned components") ;
2210 }
2211 return _ownedComponents->addOwned(comps) ;
2212}
2213
2214
2215
2216////////////////////////////////////////////////////////////////////////////////
2217/// Clone tree expression of objects. All tree nodes will be owned by
2218/// the head node return by cloneTree()
2219
2220RooAbsArg* RooAbsArg::cloneTree(const char* newname) const
2221{
2222 // Clone tree using snapshot
2223 RooArgSet* clonedNodes = (RooArgSet*) RooArgSet(*this).snapshot(kTRUE) ;
2224
2225 // Find the head node in the cloneSet
2226 RooAbsArg* head = clonedNodes->find(*this) ;
2227 assert(head);
2228
2229 // Remove the head node from the cloneSet
2230 // To release it from the set ownership
2231 clonedNodes->remove(*head) ;
2232
2233 // Add the set as owned component of the head
2234 head->addOwnedComponents(*clonedNodes) ;
2235
2236 // Delete intermediate container
2237 clonedNodes->releaseOwnership() ;
2238 delete clonedNodes ;
2239
2240 // Adjust name of head node if requested
2241 if (newname) {
2242 head->TNamed::SetName(newname) ;
2243 head->_namePtr = (TNamed*) RooNameReg::instance().constPtr(newname) ;
2244 }
2245
2246 // Return the head
2247 return head ;
2248}
2249
2250
2251
2252////////////////////////////////////////////////////////////////////////////////
2253
2255{
2256 if (dynamic_cast<RooTreeDataStore*>(&store)) {
2257 attachToTree(((RooTreeDataStore&)store).tree()) ;
2258 } else if (dynamic_cast<RooVectorDataStore*>(&store)) {
2260 }
2261}
2262
2263
2264
2265////////////////////////////////////////////////////////////////////////////////
2266
2268{
2269 if (_eocache) {
2270 return *_eocache ;
2271 } else {
2273 }
2274}
2275
2276
2277////////////////////////////////////////////////////////////////////////////////
2278
2280{
2281 string suffix ;
2282
2283 RooArgSet branches ;
2284 branchNodeServerList(&branches) ;
2285 RooFIter iter = branches.fwdIterator();
2286 RooAbsArg* arg ;
2287 while((arg=iter.next())) {
2288 const char* tmp = arg->cacheUniqueSuffix() ;
2289 if (tmp) suffix += tmp ;
2290 }
2291 return Form("%s",suffix.c_str()) ;
2292}
2293
2294
2295////////////////////////////////////////////////////////////////////////////////
2296
2298{
2299 RooArgSet branches ;
2300 branchNodeServerList(&branches) ;
2301 RooFIter iter = branches.fwdIterator() ;
2302 RooAbsArg* arg ;
2303 while((arg=iter.next())) {
2304// cout << "wiring caches on node " << arg->GetName() << endl ;
2305 for (deque<RooAbsCache*>::iterator iter2 = arg->_cacheList.begin() ; iter2 != arg->_cacheList.end() ; ++iter2) {
2306 (*iter2)->wireCache() ;
2307 }
2308 }
2309}
2310
2311
2312
2313////////////////////////////////////////////////////////////////////////////////
2314
2315void RooAbsArg::SetName(const char* name)
2316{
2319 if (newPtr != _namePtr) {
2320 //cout << "Rename '" << _namePtr->GetName() << "' to '" << name << "' (set flag in new name)" << endl;
2321 _namePtr = newPtr;
2323 }
2324}
2325
2326
2327
2328
2329////////////////////////////////////////////////////////////////////////////////
2330
2331void RooAbsArg::SetNameTitle(const char *name, const char *title)
2332{
2333 TNamed::SetNameTitle(name,title) ;
2335 if (newPtr != _namePtr) {
2336 //cout << "Rename '" << _namePtr->GetName() << "' to '" << name << "' (set flag in new name)" << endl;
2337 _namePtr = newPtr;
2339 }
2340}
2341
2342
2343////////////////////////////////////////////////////////////////////////////////
2344/// Stream an object of class RooAbsArg.
2345
2346void RooAbsArg::Streamer(TBuffer &R__b)
2347{
2348 if (R__b.IsReading()) {
2349 _ioReadStack.push(this) ;
2350 R__b.ReadClassBuffer(RooAbsArg::Class(),this);
2351 _ioReadStack.pop() ;
2353 _isConstant = getAttribute("Constant") ;
2354 } else {
2355 R__b.WriteClassBuffer(RooAbsArg::Class(),this);
2356 }
2357}
2358
2359////////////////////////////////////////////////////////////////////////////////
2360/// Method called by workspace container to finalize schema evolution issues
2361/// that cannot be handled in a single ioStreamer pass.
2362///
2363/// A second pass is typically needed when evolving data member of RooAbsArg-derived
2364/// classes that are container classes with references to other members, which may
2365/// not yet be 'live' in the first ioStreamer() evolution pass.
2366///
2367/// Classes may overload this function, but must call the base method in the
2368/// overloaded call to ensure base evolution is handled properly
2369
2371{
2372 // Handling of v5-v6 migration (TRefArray _proxyList --> RooRefArray _proxyList)
2373 auto iter = _ioEvoList.find(this);
2374 if (iter != _ioEvoList.end()) {
2375
2376 // Transfer contents of saved TRefArray to RooRefArray now
2378 _proxyList.Expand(iter->second->GetEntriesFast());
2379 for (int i = 0; i < iter->second->GetEntriesFast(); i++) {
2380 _proxyList.Add(iter->second->At(i));
2381 }
2382 // Delete TRefArray and remove from list
2383 _ioEvoList.erase(iter);
2384 }
2385}
2386
2387
2388
2389
2390////////////////////////////////////////////////////////////////////////////////
2391/// Method called by workspace container to finalize schema evolution issues
2392/// that cannot be handled in a single ioStreamer pass. This static finalize method
2393/// is called after ioStreamerPass2() is called on each directly listed object
2394/// in the workspace. It's purpose is to complete schema evolution of any
2395/// objects in the workspace that are not directly listed as content elements
2396/// (e.g. analytical convolution tokens )
2397
2399{
2400 // Handling of v5-v6 migration (TRefArray _proxyList --> RooRefArray _proxyList)
2401 for (const auto& iter : _ioEvoList) {
2402
2403 // Transfer contents of saved TRefArray to RooRefArray now
2404 if (!iter.first->_proxyList.GetEntriesFast())
2405 iter.first->_proxyList.Expand(iter.second->GetEntriesFast());
2406 for (int i = 0; i < iter.second->GetEntriesFast(); i++) {
2407 iter.first->_proxyList.Add(iter.second->At(i));
2408 }
2409 }
2410
2411 _ioEvoList.clear();
2412}
2413
2414
2418}
2419
2420////////////////////////////////////////////////////////////////////////////////
2421/// Stream an object of class RooRefArray.
2422
2423void RooRefArray::Streamer(TBuffer &R__b)
2424{
2425 UInt_t R__s, R__c;
2426 if (R__b.IsReading()) {
2427
2428 Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
2429
2430 // Make temporary refArray and read that from the streamer
2431 auto refArray = std::make_unique<TRefArray>();
2432 refArray->Streamer(R__b) ;
2433 R__b.CheckByteCount(R__s, R__c, refArray->IsA());
2434
2435 // Schedule deferred processing of TRefArray into proxy list
2436 RooAbsArg::_ioEvoList[RooAbsArg::_ioReadStack.top()] = std::move(refArray);
2437
2438 } else {
2439
2440 R__c = R__b.WriteVersion(RooRefArray::IsA(), kTRUE);
2441
2442 // Make a temporary refArray and write that to the streamer
2443 TRefArray refArray(GetEntriesFast());
2444 TIterator* iter = MakeIterator() ;
2445 TObject* tmpObj ; while ((tmpObj = iter->Next())) {
2446 refArray.Add(tmpObj) ;
2447 }
2448 delete iter ;
2449
2450 refArray.Streamer(R__b) ;
2451 R__b.SetByteCount(R__c, kTRUE) ;
2452
2453 }
2454}
2455
2456/// Print at the prompt
2457namespace cling {
2458std::string printValue(RooAbsArg *raa)
2459{
2460 std::stringstream s;
2461 if (0 == *raa->GetName() && 0 == *raa->GetTitle()) {
2462 s << "An instance of " << raa->ClassName() << ".";
2463 return s.str();
2464 }
2465 raa->printStream(s, raa->defaultPrintContents(""), raa->defaultPrintStyle(""));
2466 return s.str();
2467}
2468} // namespace cling
istream & operator>>(istream &is, RooAbsArg &arg)
Istream operator.
#define coutI(a)
#define cxcoutI(a)
#define cxcoutD(a)
#define coutF(a)
#define coutE(a)
#define cxcoutF(a)
char Text_t
Definition RtypesCore.h:62
short Version_t
Definition RtypesCore.h:65
const Bool_t kFALSE
Definition RtypesCore.h:92
unsigned long ULong_t
Definition RtypesCore.h:55
bool Bool_t
Definition RtypesCore.h:63
const Bool_t kTRUE
Definition RtypesCore.h:91
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:364
TBuffer & operator<<(TBuffer &buf, const Tmpl *obj)
Definition TBuffer.h:399
static void indent(ostringstream &buf, int indent_level)
char name[80]
Definition TGX11.cxx:110
char * Form(const char *fmt,...)
TString operator+(const TString &s1, const TString &s2)
Use the special concatenation constructor.
Definition TString.cxx:1494
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:72
RooExpensiveObjectCache & expensiveObjectCache() const
virtual Bool_t checkObservables(const RooArgSet *nset) const
Overloadable function in which derived classes can implement consistency checks of the variables.
virtual RooAbsArg * cloneTree(const char *newname=0) const
Clone tree expression of objects.
RooRefArray _proxyList
Definition RooAbsArg.h:619
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Given a set of possible observables, return the observables that this PDF depends on.
Definition RooAbsArg.h:313
Bool_t _fast
Definition RooAbsArg.h:688
virtual Bool_t readFromStream(std::istream &is, Bool_t compact, Bool_t verbose=kFALSE)=0
virtual Bool_t isValid() const
WVE (08/21/01) Probably obsolete now.
TNamed * _namePtr
Definition RooAbsArg.h:697
static void verboseDirty(Bool_t flag)
Activate verbose messaging related to dirty flag propagation.
void attachToStore(RooAbsDataStore &store)
Attach this argument to the data store such that it reads data from there.
virtual Int_t defaultPrintContents(Option_t *opt) const
Define default contents to print.
const TNamed * namePtr() const
Definition RooAbsArg.h:550
const char * aggregateCacheUniqueSuffix() const
Bool_t redirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t isRecursionStep=kFALSE)
Replace all direct servers of this object with the new servers in newServerList.
void changeServer(RooAbsArg &server, Bool_t valueProp, Bool_t shapeProp)
Change dirty flag propagation mask for specified server.
Bool_t isValueServer(const RooAbsArg &arg) const
Check if this is serving values to arg.
Definition RooAbsArg.h:217
RooWorkspace * _myws
Prevent 'AlwaysDirty' mode for this node.
Definition RooAbsArg.h:705
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.
void attachDataStore(const RooAbsDataStore &set)
Replace server nodes with names matching the dataset variable names with those data set variables,...
virtual void printClassName(std::ostream &os) const
Print object class name.
RooArgSet * _ownedComponents
Definition RooAbsArg.h:691
std::deque< RooAbsCache * > _cacheList
Definition RooAbsArg.h:620
void setShapeDirty()
Notify that a shape-like property (e.g. binning) has changed.
Definition RooAbsArg.h:513
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.
void registerProxy(RooArgProxy &proxy)
Register an RooArgProxy in the proxy list.
Bool_t isShapeServer(const RooAbsArg &arg) const
Check if this is serving shape to arg.
Definition RooAbsArg.h:225
void setStringAttribute(const Text_t *key, const Text_t *value)
Associate string 'value' to this object under key 'key'.
static void ioStreamerPass2Finalize()
Method called by workspace container to finalize schema evolution issues that cannot be handled in a ...
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.
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Implement multi-line detailed printing.
Bool_t isCloneOf(const RooAbsArg &other) const
Check if this object was created as a clone of 'other'.
Bool_t isShapeDirty() const
Definition RooAbsArg.h:434
static void setDirtyInhibit(Bool_t flag)
Control global dirty inhibit mode.
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 ...
void graphVizAddConnections(std::set< std::pair< RooAbsArg *, RooAbsArg * > > &)
Utility function that inserts all point-to-point client-server connections between any two RooAbsArgs...
void unRegisterProxy(RooArgProxy &proxy)
Remove proxy from proxy list.
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.
friend class RooArgSet
Definition RooAbsArg.h:606
Bool_t inhibitDirty() const
Delete watch flag.
std::set< std::string > _boolAttrib
Definition RooAbsArg.h:641
void addServer(RooAbsArg &server, Bool_t valueProp=kTRUE, Bool_t shapeProp=kFALSE, std::size_t refCount=1)
Register another RooAbsArg as a server to us, ie, declare that we depend on it.
virtual void printTree(std::ostream &os, TString indent="") const
Print object tree structure.
void unRegisterCache(RooAbsCache &cache)
Unregister a RooAbsCache. Called from the RooAbsCache destructor.
virtual Bool_t isFundamental() const
Is this object a fundamental type that can be added to a dataset? Fundamental-type subclasses overrid...
Definition RooAbsArg.h:243
virtual void printTitle(std::ostream &os) const
Print object title.
RefCountList_t _clientListValue
Definition RooAbsArg.h:617
void printAttribList(std::ostream &os) const
Transient boolean attributes (not copied in ctor)
virtual void Print(Option_t *options=0) const
Print the object to the defaultPrintStream().
Definition RooAbsArg.h:340
friend void RooRefArray::Streamer(TBuffer &)
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
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...
void setAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
virtual void writeToStream(std::ostream &os, Bool_t compact) const =0
virtual void printAddress(std::ostream &os) const
Print class name of object.
void setTransientAttribute(const Text_t *name, Bool_t value=kTRUE)
Set (default) or clear a named boolean attribute of this object.
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 ...
Bool_t _isConstant
Do not persist. Pointer to global instance of string that matches object named.
Definition RooAbsArg.h:698
Bool_t isValueDirty() const
Definition RooAbsArg.h:439
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.
Int_t Compare(const TObject *other) const
Utility function used by TCollection::Sort to compare contained TObjects We implement comparison by n...
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
virtual void ioStreamerPass2()
Method called by workspace container to finalize schema evolution issues that cannot be handled in a ...
void wireAllCaches()
Bool_t _valueDirty
Definition RooAbsArg.h:683
virtual ~RooAbsArg()
Destructor.
virtual Bool_t isDerived() const
Does value or shape of this arg depend on any other arg?
Definition RooAbsArg.h:92
static Bool_t _inhibitDirty
Definition RooAbsArg.h:672
virtual const char * cacheUniqueSuffix() const
Definition RooAbsArg.h:516
RefCountListLegacyIterator_t * makeLegacyIterator(const RefCountList_t &list) const
Bool_t _localNoInhibitDirty
Cached isConstant status.
Definition RooAbsArg.h:700
virtual void constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt=kTRUE)
Interface function signaling a request to perform constant term optimization.
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Set the operation mode of this node.
virtual void attachToTree(TTree &t, Int_t bufSize=32000)=0
Overloadable function for derived classes to implement attachment as branch to a TTree.
OperMode _operMode
Mark batches as dirty (only meaningful for RooAbsReal).
Definition RooAbsArg.h:687
RooLinkedList getCloningAncestors() const
Return ancestors in cloning chain of this RooAbsArg.
void setValueDirty()
Mark the element dirty. This forces a re-evaluation when a value is requested.
Definition RooAbsArg.h:508
Bool_t addOwnedComponents(const RooArgSet &comps)
Take ownership of the contents of 'comps'.
Bool_t recursiveCheckObservables(const RooArgSet *nset) const
Recursively call checkObservables on all nodes in the expression tree.
RooAbsCache * getCache(Int_t index) const
Return registered cache object by index.
void printDirty(Bool_t depth=kTRUE) const
Print information about current value dirty state information.
bool _allBatchesDirty
Definition RooAbsArg.h:685
static Bool_t _verboseDirty
Definition RooAbsArg.h:671
void registerCache(RooAbsCache &cache)
Register RooAbsCache with this object.
virtual void optimizeCacheMode(const RooArgSet &observables)
Activate cache mode optimization with given definition of observables.
RefCountList_t _clientListShape
Definition RooAbsArg.h:616
virtual void attachToVStore(RooVectorDataStore &vstore)=0
TString cleanBranchName() const
Construct a mangled name from the actual name that is free of any math symbols that might be interpre...
void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Bool_t _prohibitServerRedirect
Set of owned component.
Definition RooAbsArg.h:693
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...
Int_t numProxies() const
Return the number of registered proxies.
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
virtual void printName(std::ostream &os) const
Print object name.
void replaceServer(RooAbsArg &oldServer, RooAbsArg &newServer, Bool_t valueProp, Bool_t shapeProp)
Replace 'oldServer' with 'newServer'.
virtual void getParametersHook(const RooArgSet *, RooArgSet *, Bool_t) const
Definition RooAbsArg.h:573
virtual void printMetaArgs(std::ostream &) const
Definition RooAbsArg.h:350
void addServerList(RooAbsCollection &serverList, Bool_t valueProp=kTRUE, Bool_t shapeProp=kFALSE)
Register a list of RooAbsArg as servers to us by calling addServer() for each arg in the list.
Bool_t dependsOnValue(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=0) const
Check whether this object depends on values from an element in the serverList.
Definition RooAbsArg.h:102
void setProxyNormSet(const RooArgSet *nset)
Forward a change in the cached normalization argset to all the registered proxies.
RefCountList_t _clientList
Definition RooAbsArg.h:615
RooAbsProxy * getProxy(Int_t index) const
Return the nth proxy from the proxy list.
RooAbsArg & operator=(const RooAbsArg &other)
Assign all boolean and string properties of the original object.
virtual bool redirectServersHook(const RooAbsCollection &, bool, bool, bool)
Function that is called at the end of redirectServers().
Definition RooAbsArg.h:275
RefCountList_t _serverList
Definition RooAbsArg.h:614
RooExpensiveObjectCache * _eocache
Prohibit server redirects – Debugging tool.
Definition RooAbsArg.h:695
RooArgSet * getComponents() const
Create a RooArgSet with all components (branch nodes) of the expression tree headed by this object.
std::set< std::string > _boolAttribTransient
Definition RooAbsArg.h:643
Bool_t _shapeDirty
Definition RooAbsArg.h:684
RooArgSet * getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
RooAbsArg * findNewServer(const RooAbsCollection &newSet, Bool_t nameChange) const
Find the new server in the specified set that matches the old server.
Bool_t isConstant() const
Check if the "Constant" attribute is set.
Definition RooAbsArg.h:380
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.
void graphVizTree(const char *fileName, const char *delimiter="\n", bool useTitle=false, bool useLatex=false)
Create a GraphViz .dot file visualizing the expression tree headed by this RooAbsArg object.
virtual void operModeHook()
Definition RooAbsArg.h:567
Bool_t getTransientAttribute(const Text_t *name) const
Check if a named attribute is set.
std::map< std::string, std::string > _stringAttrib
Definition RooAbsArg.h:642
Int_t numCaches() const
Return number of registered caches.
RooAbsArg()
Default constructor.
Bool_t recursiveRedirectServers(const RooAbsCollection &newServerList, Bool_t mustReplaceAll=kFALSE, Bool_t nameChange=kFALSE, Bool_t recurseInNewSet=kTRUE)
Recursively replace all servers with the new servers in newSet.
void attachDataSet(const RooAbsData &set)
Replace server nodes with names matching the dataset variable names with those data set variables,...
virtual void printArgs(std::ostream &os) const
Print object arguments, ie its proxies.
TIteratorToSTLInterface< RefCountList_t::Container_t > RefCountListLegacyIterator_t
Definition RooAbsArg.h:75
RooAbsArg * findServer(const char *name) const
Return server of this with name name. Returns nullptr if not found.
Definition RooAbsArg.h:203
void SetName(const char *name)
Set the name of the TNamed.
void addParameters(RooArgSet &params, const RooArgSet *nset=0, Bool_t stripDisconnected=kTRUE) const
INTERNAL helper function for getParameters()
Bool_t _deleteWatch
Definition RooAbsArg.h:673
OperMode operMode() const
Query the operation mode of this node.
Definition RooAbsArg.h:502
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...
RooAbsCache is the abstract base class for data members of RooAbsArgs that cache other (composite) Ro...
Definition RooAbsCache.h:27
virtual void printCompactTreeHook(std::ostream &, const char *)
Interface for printing of cache guts in tree mode printing.
virtual Bool_t redirectServersHook(const RooAbsCollection &, Bool_t, Bool_t, Bool_t)
Interface for server redirect calls.
virtual void optimizeCacheMode(const RooArgSet &, RooArgSet &, RooLinkedList &)
Interface for processing of cache mode optimization calls.
virtual void operModeHook()
Interface for operation mode changes.
virtual void findConstantNodes(const RooArgSet &, RooArgSet &, RooLinkedList &)
Interface for constant term node finding calls.
RooAbsCollection is an abstract container object that can hold multiple RooAbsArg objects.
Int_t getSize() const
void sort(Bool_t reverse=false)
Sort collection using std::sort and name comparison.
RooFIter fwdIterator() const
One-time forward iterator.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
Storage_t::size_type size() const
RooAbsArg * first() const
void reserve(Storage_t::size_type count)
void clear()
Clear contents. If the collection is owning, it will also delete the contents.
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
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...
const char * GetName() const
Returns name of object.
void setName(const char *name)
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsDataStore is the abstract base class for data collection that use a TTree as internal storage m...
virtual const RooArgSet * get(Int_t index) const =0
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:49
virtual const RooArgSet * get() const
Definition RooAbsData.h:92
RooAbsProxy is the abstact interface for proxy classes.
Definition RooAbsProxy.h:30
virtual void changeNormSet(const RooArgSet *newNormSet)
Destructor.
virtual void print(std::ostream &os, Bool_t addContents=kFALSE) const
Print proxy name.
virtual const char * name() const
Definition RooAbsProxy.h:40
virtual Bool_t changePointer(const RooAbsCollection &newServerSet, Bool_t nameChange=kFALSE, Bool_t factoryInitMode=kFALSE)=0
RooArgProxy is the abstract interface for RooAbsArg proxy classes.
Definition RooArgProxy.h:24
Bool_t isShapeServer() const
Definition RooArgProxy.h:65
Bool_t isValueServer() const
Definition RooArgProxy.h:61
RooAbsArg * absArg() const
Definition RooArgProxy.h:37
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:29
Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE) override
Add element to non-owning set.
Bool_t addOwned(RooAbsArg &var, Bool_t silent=kFALSE) override
Add element to an owning set.
RooConstVar represent a constant real-valued object.
Definition RooConstVar.h:26
RooExpensiveObjectCache is a singleton class that serves as repository for objects that are expensive...
static RooExpensiveObjectCache & instance()
Return reference to singleton instance.
A one-time forward iterator working on RooLinkedList or RooAbsCollection.
RooAbsArg * next()
Return next element or nullptr if at end.
Switches the message service to a different level while the instance is alive.
Definition RooHelpers.h:39
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
TObject * FindObject(const char *name) const
Return pointer to obejct with given name.
RooAbsArg * findArg(const RooAbsArg *) const
Return pointer to object with given name in collection.
virtual void Add(TObject *arg)
RooListProxy is the concrete proxy for RooArgList objects.
const TNamed * constPtr(const char *stringPtr)
Return a unique TNamed pointer for given C++ string.
static RooNameReg & instance()
Return reference to singleton instance.
RooNameSet is a utility class that stores the names the objects in a RooArget.
Definition RooNameSet.h:24
const char * content() const
Definition RooNameSet.h:50
RooPlotable is a 'mix-in' base class that define the standard RooFit plotting and printing methods.
virtual StyleOption defaultPrintStyle(Option_t *opt) const
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,...
virtual void printValue(std::ostream &os) const
Interface to print value of object.
RooRealIntegral performs hybrid numerical/analytical integrals of RooAbsReal objects.
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:39
RooResolutionModel is the base class for PDFs that represent a resolution model that can be convolute...
std::size_t refCount(typename Container_t::const_iterator item) const
Return ref count of item that iterator points to.
const Container_t & containedObjects() const
Direct reference to container of objects held by this list.
void Remove(const T *obj, bool force=false)
Decrease ref count of given object.
Container_t::const_iterator begin() const
Iterator over contained objects.
void Add(T *obj, std::size_t initialCount=1)
Add an object or increase refCount if it is already present.
Container_t::const_iterator end() const
End of contained objects.
bool empty() const
Check if empty.
std::size_t size() const
Number of contained objects (neglecting the ref count).
void RemoveAll(const T *obj)
Remove from list irrespective of ref count.
void reserve(std::size_t amount)
bool containsByNamePtr(const T *obj) const
Check if list contains an item using findByNamePointer().
RooSetProxy is the concrete proxy for RooArgSet objects.
Definition RooSetProxy.h:23
RooTreeDataStore is a TTree-backed data storage.
RooVectorDataStore uses std::vectors to store data columns.
Bool_t defineSetInternal(const char *name, const RooArgSet &aset)
const RooArgSet * set(const char *name)
Return pointer to previously defined named set with given nmame If no such set is found a null pointe...
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
Bool_t IsReading() const
Definition TBuffer.h:86
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
TIterator and GenericRooFIter front end with STL back end.
Iterator abstract base class.
Definition TIterator.h:30
virtual TObject * Next()=0
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
TString fName
Definition TNamed.h:32
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition TNamed.h:48
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
Definition TNamed.cxx:51
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
virtual void SetNameTitle(const char *name, const char *title)
Set all the TNamed parameters (name and title).
Definition TNamed.cxx:154
Int_t GetEntriesFast() const
Definition TObjArray.h:64
virtual void Expand(Int_t newSize)
Expand or shrink the array to newSize elements.
void Add(TObject *obj)
Definition TObjArray.h:74
virtual void Compress()
Remove empty slots from array.
Int_t GetEntries() const
Return the number of objects in array (i.e.
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
TIterator * MakeIterator(Bool_t dir=kIterForward) const
Returns an array iterator.
virtual TObject * Remove(TObject *obj)
Remove object from array.
TObject * At(Int_t idx) const
Definition TObjArray.h:166
Mother of all ROOT objects.
Definition TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:359
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:130
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:696
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:445
An array of references to TObjects.
Definition TRefArray.h:39
Basic string class.
Definition TString.h:136
const char * Data() const
Definition TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:692
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:615
TString & Append(const char *cs)
Definition TString.h:564
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
A TTree represents a columnar dataset.
Definition TTree.h:79
Definition first.py:1
Definition tree.py:1