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