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