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