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