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