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