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/** \class RooAbsArg
18 \ingroup Roofitcore
19
20Common abstract base class for objects that
21represent a value and a "shape" in RooFit. Values or shapes usually depend on values
22or shapes of other RooAbsArg instances. Connecting several RooAbsArg in
23a computation graph models an expression tree that can be evaluated.
24
25### Building a computation graph of RooFit objects
26Therefore, RooAbsArg provides functionality to connect objects of type RooAbsArg into
27a computation graph to pass values between those objects.
28A value can e.g. be a real-valued number, (instances of RooAbsReal), or an integer, that is,
29category index (instances of RooAbsCategory). The third subclass of RooAbsArg is RooStringVar,
30but it is rarely used.
31
32The "shapes" that a RooAbsArg can possess can e.g. be the definition
33range of an observable, or how many states a category object has. In computations,
34values are expected to change often, while shapes remain mostly constant
35(unless e.g. a new range is set for an observable).
36
37Nodes of a computation graph are connected using instances of RooAbsProxy.
38If Node B declares a member `RooTemplateProxy<TypeOfNodeA>`, Node A will be
39registered as a server of values to Node B, and Node B will know that it is
40a client of node A. Using functions like dependsOn(), or getObservables()
41/ getParameters(), the relation of `A --> B` can be queried. Using graphVizTree(),
42one can create a visualisation of the expression tree.
43
44
45An instance of RooAbsArg can have named attributes. It also has flags
46to indicate that either its value or its shape were changed (= it is dirty).
47RooAbsArg provides functionality to manage client/server relations in
48a computation graph (\ref clientServerInterface), and helps propagating
49value/shape changes through the graph. RooAbsArg implements interfaces
50for inspecting client/server relationships (\ref clientServerInterface) and
51setting/clearing/querying named attributes.
52
53### Caching of values
54The values of nodes in the computation graph are cached in RooFit. If
55a value is used in two nodes of a graph, it doesn't need to be recomputed. If
56a node acquires a new value, it notifies its consumers ("clients") that
57their cached values are dirty. See the functions in \ref optimisationInterface
58for details.
59A node uses its isValueDirty() and isShapeDirty() functions to decide if a
60computation is necessary. Caching can be vetoed globally by setting a
61bit using setDirtyInhibit(). This will make computations slower, but all the
62nodes of the computation graph will be evaluated irrespective of whether their
63state is clean or dirty. Using setOperMode(), caching can also be enabled/disabled
64for single nodes.
65
66*/
67
68#include <RooAbsArg.h>
69
71#include <RooAbsData.h>
72#include <RooAbsDataStore.h>
73#include <RooArgProxy.h>
74#include <RooArgSet.h>
75#include <RooConstVar.h>
77#include <RooHelpers.h>
78#include "RooFitImplHelpers.h"
79#include <RooListProxy.h>
80#include <RooMsgService.h>
81#include <RooRealIntegral.h>
82#include <RooResolutionModel.h>
83#include <RooSetProxy.h>
84#include <RooTrace.h>
85#include <RooTreeDataStore.h>
86#include <RooVectorDataStore.h>
87#include <RooWorkspace.h>
88
89#include <TBuffer.h>
90#include <TClass.h>
92
93#include <algorithm>
94#include <cstring>
95#include <fstream>
96#include <sstream>
97
98bool RooAbsArg::_verboseDirty(false);
99bool RooAbsArg::_inhibitDirty(false);
101{
103}
104
105namespace {
106
107auto &ioEvoList()
108{
109 // temporary holding list for proxies needed in schema evolution
110 static std::map<RooAbsArg *, std::unique_ptr<TRefArray>> ioEvoListInstance;
111 return ioEvoListInstance;
112}
113
114// reading stack
115auto &ioReadStack()
116{
117 static std::stack<RooAbsArg *> ioReadStackInstance;
118 return ioReadStackInstance;
119}
120
121} // namespace
122
123/// Default constructor
124
125RooAbsArg::RooAbsArg() : _namePtr(RooNameReg::instance().constPtr(GetName())) {}
126
127/// Create an object with the specified name and descriptive title.
128/// The newly created object has no clients or servers and has its
129/// dirty flags set.
130
131RooAbsArg::RooAbsArg(const char *name, const char *title) : TNamed(name, title)
132{
133 if (name == nullptr || strlen(name) == 0) {
134 throw std::logic_error(
135 "Each RooFit object needs a name. "
136 "Objects representing the same entity (e.g. an observable 'x') are identified using their name.");
137 }
138 _namePtr = RooNameReg::instance().constPtr(GetName());
139}
140
141/// Copy constructor transfers all boolean and string properties of the original
142/// object. Transient properties and client-server links are not copied
143
145 : TNamed(name ? name : other.GetName(), other.GetTitle()),
147 _boolAttrib(other._boolAttrib),
148 _stringAttrib(other._stringAttrib),
149 _deleteWatch(other._deleteWatch),
150 _namePtr(name ? RooNameReg::instance().constPtr(name) : other._namePtr),
151 _isConstant(other._isConstant),
152 _localNoInhibitDirty(other._localNoInhibitDirty)
153{
154
155 // Copy server list by hand
156 bool valueProp;
157 bool shapeProp;
158 for (const auto server : other._serverList) {
159 valueProp = server->_clientListValue.containsByNamePtr(&other);
160 shapeProp = server->_clientListShape.containsByNamePtr(&other);
162 }
163
166}
167
168/// Destructor.
169
171{
172 // Notify all servers that they no longer need to serve us
173 while (!_serverList.empty()) {
174 removeServer(*_serverList.containedObjects().back(), true);
175 }
176
177 // Notify all clients that they are in limbo
178 std::vector<RooAbsArg *> clientListTmp(_clientList.begin(),
179 _clientList.end()); // have to copy, as we invalidate iterators
180 bool first(true);
181 for (auto client : clientListTmp) {
182 client->setAttribute("ServerDied");
183 std::stringstream attr;
184 attr << "ServerDied:" << GetName() << "(" << reinterpret_cast<std::size_t>(this) << ")";
185 client->setAttribute(attr.str().c_str());
186 client->removeServer(*this, true);
187
188 if (_verboseDirty) {
189
190 if (first) {
191 cxcoutD(Tracing) << "RooAbsArg::dtor(" << GetName() << "," << this
192 << ") DeleteWatch: object is being destroyed" << std::endl;
193 first = false;
194 }
195
196 cxcoutD(Tracing) << fName << "::" << ClassName() << ":~RooAbsArg: dependent \"" << client->GetName()
197 << "\" should have been deleted first" << std::endl;
198 }
199 }
200
201 if (_ownedComponents) {
202 delete _ownedComponents;
203 _ownedComponents = nullptr;
204 }
205}
206
207/// Control global dirty inhibit mode. When set to true no value or shape dirty
208/// flags are propagated and cache is always considered to be dirty.
209
214
215/// Activate verbose messaging related to dirty flag propagation
216
218{
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 std::set<std::string>::iterator iter = _boolAttrib.find(name);
235 if (iter != _boolAttrib.end()) {
236 _boolAttrib.erase(iter);
237 }
238 }
239}
240
241/// Check if a named attribute is set. By default, all attributes are unset.
242
244{
245 return _boolAttrib.find(name) != _boolAttrib.end();
246}
247
248/// Associate string 'value' to this object under key 'key'
249
251{
252 if (value) {
253 _stringAttrib[key] = value;
254 } else {
256 }
257}
258
259/// Delete a string attribute with a given key.
260
262{
263 _stringAttrib.erase(key);
264}
265
266/// Get string attribute mapped under key 'key'. Returns null pointer
267/// if no attribute exists under that key
268
270{
271 std::map<std::string, std::string>::const_iterator iter = _stringAttrib.find(key);
272 return iter != _stringAttrib.end() ? iter->second.c_str() : nullptr;
273}
274
275/// Set (default) or clear a named boolean attribute of this object.
276
278{
279 if (value) {
280
282
283 } else {
284
285 std::set<std::string>::iterator iter = _boolAttribTransient.find(name);
286 if (iter != _boolAttribTransient.end()) {
287 _boolAttribTransient.erase(iter);
288 }
289 }
290}
291
292/// Check if a named attribute is set. By default, all attributes
293/// are unset.
294
296{
297 return (_boolAttribTransient.find(name) != _boolAttribTransient.end());
298}
299
300/// Register another RooAbsArg as a server to us, ie, declare that
301/// we depend on it.
302/// \param server The server to be registered.
303/// \param valueProp In addition to the basic client-server relationship, declare dependence on the server's value.
304/// \param shapeProp In addition to the basic client-server relationship, declare dependence on the server's shape.
305/// \param refCount Optionally add with higher reference count (if multiple components depend on it)
306
307void RooAbsArg::addServer(RooAbsArg &server, bool valueProp, bool shapeProp, std::size_t refCount)
308{
310 cxcoutF(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName()
311 << "): PROHIBITED SERVER ADDITION REQUESTED: adding server " << server.GetName() << "("
312 << &server << ") for " << (valueProp ? "value " : "") << (shapeProp ? "shape" : "")
313 << std::endl;
314 throw std::logic_error("PROHIBITED SERVER ADDITION REQUESTED in RooAbsArg::addServer");
315 }
316
317 cxcoutD(LinkStateMgmt) << "RooAbsArg::addServer(" << this << "," << GetName() << "): adding server "
318 << server.GetName() << "(" << &server << ") for " << (valueProp ? "value " : "")
319 << (shapeProp ? "shape" : "") << std::endl;
320
321 if (server.operMode() == ADirty && operMode() != ADirty && valueProp) {
323 }
324
325 // LM: use hash tables for larger lists
326 // if (_serverList.GetSize() > 999 && _serverList.getHashTableSize() == 0) _serverList.setHashTableSize(1000);
327 // if (server._clientList.GetSize() > 999 && server._clientList.getHashTableSize() == 0)
328 // server._clientList.setHashTableSize(1000); if (server._clientListValue.GetSize() > 999 &&
329 // server._clientListValue.getHashTableSize() == 0) server._clientListValue.setHashTableSize(1000);
330
331 // Add server link to given server
332 _serverList.Add(&server, refCount);
333
334 server._clientList.Add(this, refCount);
335 if (valueProp)
336 server._clientListValue.Add(this, refCount);
337 if (shapeProp)
338 server._clientListShape.Add(this, refCount);
339}
340
341/// Register a list of RooAbsArg as servers to us by calling
342/// addServer() for each arg in the list
343
345{
346 _serverList.reserve(_serverList.size() + serverList.size());
347
348 for (const auto arg : serverList) {
350 }
351}
352
353/// Unregister another RooAbsArg as a server to us, ie, declare that
354/// we no longer depend on its value and shape.
355
357{
359 std::stringstream ss;
360 ss << "RooAbsArg::addServer(" << this << "," << GetName()
361 << "): PROHIBITED SERVER REMOVAL REQUESTED: removing server " << server.GetName() << "(" << &server << ")";
362 cxcoutF(LinkStateMgmt) << ss.str() << std::endl;
363 throw std::runtime_error(ss.str());
364 }
365
366 if (_verboseDirty) {
367 cxcoutD(LinkStateMgmt) << "RooAbsArg::removeServer(" << GetName() << "): removing server " << server.GetName()
368 << "(" << &server << ")" << std::endl;
369 }
370
371 // Remove server link to given server
372 _serverList.Remove(&server, force);
373
374 server._clientList.Remove(this, force);
375 server._clientListValue.Remove(this, force);
376 server._clientListShape.Remove(this, force);
377}
378
379/// Replace 'oldServer' with 'newServer', specifying whether the new server has
380/// value or shape server properties.
381///
382/// \warning This function should not be used! This method is quite unsafe for
383/// many reasons. For once, the new server will be put at the end of the server
384/// list, no matter the position of the original server. This might mess up
385/// code that expects the servers to be in a certain order. Furthermore, the
386/// proxy objects corresponding to the server are not updated, leaving the
387/// object in an invalid state where the servers are out of sync with the
388/// proxies. This can have very bad consequences. Finally, by having to
389/// manually specify the value and shape server properties, it is very easy to
390/// get them wrong.
391///
392/// If you want to safely replace a server, you should use
393/// RooAbsArg::redirectServers(), which replaces the server in-place at the
394/// same position of the server list, keeps the same value and shape server
395/// properties, and also updates the corresponding proxies.
396
398{
399 coutW(LinkStateMgmt) << "replaceServer()"
400 << " is unsafe, because the server list will be out of sync with the proxy objects!"
401 << " If you want to safely replace a server, use RooAbsArg::redirectServers()."
402 << " See the docs to replaceServers() for more info." << std::endl;
403
404 Int_t count = _serverList.refCount(&oldServer);
405 removeServer(oldServer, true);
406
408}
409
410/// Change dirty flag propagation mask for specified server
411
413{
414 if (!_serverList.containsByNamePtr(&server)) {
415 coutE(LinkStateMgmt) << "RooAbsArg::changeServer(" << GetName() << "): Server " << server.GetName()
416 << " not registered" << std::endl;
417 return;
418 }
419
420 // This condition should not happen, but check anyway
421 if (!server._clientList.containsByNamePtr(this)) {
422 coutE(LinkStateMgmt) << "RooAbsArg::changeServer(" << GetName() << "): Server " << server.GetName()
423 << " doesn't have us registered as client" << std::endl;
424 return;
425 }
426
427 // Remove all propagation links, then reinstall requested ones ;
428 Int_t vcount = server._clientListValue.refCount(this);
429 Int_t scount = server._clientListShape.refCount(this);
430 server._clientListValue.RemoveAll(this);
431 server._clientListShape.RemoveAll(this);
432 if (valueProp) {
433 server._clientListValue.Add(this, vcount);
434 }
435 if (shapeProp) {
436 server._clientListShape.Add(this, scount);
437 }
438}
439
440/// Fill supplied list with all leaf nodes of the arg tree, starting with
441/// ourself as top node. A leaf node is node that has no servers declared.
442
444{
445 treeNodeServerList(list, arg, false, true, false, recurseNonDerived);
446}
447
448/// Fill supplied list with all branch nodes of the arg tree starting with
449/// ourself as top node. A branch node is node that has one or more servers declared.
450
452{
453 treeNodeServerList(list, arg, true, false, false, recurseNonDerived);
454}
455
456/// Fill supplied list with nodes of the arg tree, following all server links,
457/// starting with ourself as top node.
458/// \param[in] list Output list
459/// \param[in] arg Start searching at this element of the tree.
460/// \param[in] doBranch Add branch nodes to the list.
461/// \param[in] doLeaf Add leaf nodes to the list.
462/// \param[in] valueOnly Only check if an element is a value server (no shape server).
463/// \param[in] recurseFundamental
464
466 bool valueOnly, bool recurseFundamental) const
467{
468 // if (arg==0) {
469 // std::cout << "treeNodeServerList(" << GetName() << ") doBranch=" << (doBranch?"T":"F") << " doLeaf = " <<
470 // (doLeaf?"T":"F") << " valueOnly=" << (valueOnly?"T":"F") << std::endl ;
471 // }
472
473 if (!arg) {
474 list->reserve(10);
475 arg = this;
476 }
477
478 // Decide if to add current node
479 if ((doBranch && doLeaf) || (doBranch && arg->isDerived()) ||
480 (doLeaf && arg->isFundamental() && (!(recurseFundamental && arg->isDerived()))) ||
481 (doLeaf && !arg->isFundamental() && !arg->isDerived())) {
482
483 list->add(*arg, true);
484 }
485
486 // Recurse if current node is derived
487 if (arg->isDerived() && (!arg->isFundamental() || recurseFundamental)) {
488 for (const auto server : arg->_serverList) {
489
490 // Skip non-value server nodes if requested.
491 if (valueOnly) {
492 // The "containsByNamePtr" check is an expensive call, don't do it
493 // if "valueOnly" is false anyway!
494 if (!server->_clientListValue.containsByNamePtr(arg)) {
495 continue;
496 }
497 }
499 }
500 }
501}
502
503/// Create a list of leaf nodes in the arg tree starting with
504/// ourself as top node that don't match any of the names of the variable list
505/// of the supplied data set (the dependents). The caller of this
506/// function is responsible for deleting the returned argset.
507/// The complement of this function is getObservables()
508
510{
511 return getParameters(set ? set->get() : nullptr, stripDisconnected);
512}
513
514/// Return the parameters of this p.d.f when used in conjunction with dataset 'data'.
519
520/// Return the parameters of the p.d.f given the provided set of observables.
522{
523 return getParameters(&observables, stripDisconnected);
524}
525
526/// Create a list of leaf nodes in the arg tree starting with
527/// ourself as top node that don't match any of the names the args in the
528/// supplied argset. The caller of this function is responsible
529/// for deleting the returned argset. The complement of this function
530/// is getObservables().
531
538
539/// Add all parameters of the function and its daughters to `params`.
540/// \param[in] params Collection that stores all parameters. Add all new parameters to this.
541/// \param[in] nset Normalisation set (optional). If a value depends on this set, it's not a parameter.
542/// \param[in] stripDisconnected Passed on to getParametersHook().
543
545{
546
548 std::vector<RooAbsArg *> branchList;
549 for (const auto server : _serverList) {
550 if (server->isValueServer(*this)) {
551 if (server->isFundamental()) {
552 if (!nset || !server->dependsOn(*nset)) {
554 }
555 } else {
556 branchList.push_back(server);
557 }
558 }
559 }
560
561 // Now recurse into branch servers
562 std::sort(branchList.begin(), branchList.end());
563 const auto last = std::unique(branchList.begin(), branchList.end());
564 for (auto serverIt = branchList.begin(); serverIt < last; ++serverIt) {
565 (*serverIt)->addParameters(nodeParamServers, nset, stripDisconnected);
566 }
567
568 // Allow pdf to strip parameters from list
570
571 // Add parameters of this node to the combined list
572 params.add(nodeParamServers, true);
573}
574
575/// Fills a list with leaf nodes in the arg tree starting with
576/// ourself as top node that don't match any of the names the args in the
577/// supplied argset. Returns `true` only if something went wrong.
578/// The complement of this function is getObservables().
579/// \param[in] observables Set of leaves to ignore because they are observables and not parameters.
580/// \param[out] outputSet Output set.
581/// \param[in] stripDisconnected Allow pdf to strip parameters from list before adding it.
582
584{
585 outputSet.clear();
586 outputSet.setName("parameters");
587
589
590 outputSet.sort();
591
592 return false;
593}
594
595/// Given a set of possible observables, return the observables that this PDF depends on.
600
601/// Return the observables of this pdf given the observables defined by `data`.
606
607/// Create a list of leaf nodes in the arg tree starting with
608/// ourself as top node that match any of the names of the variable list
609/// of the supplied data set (the dependents). The caller of this
610/// function is responsible for deleting the returned argset.
611/// The complement of this function is getParameters().
612
614{
615 if (!set)
617
618 return getObservables(set->get());
619}
620
621/// Create a list of leaf nodes in the arg tree starting with
622/// ourself as top node that match any of the names the args in the
623/// supplied argset. The caller of this function is responsible
624/// for deleting the returned argset. The complement of this function
625/// is getParameters().
626
633
634/// Create a list of leaf nodes in the arg tree starting with
635/// ourself as top node that match any of the names the args in the
636/// supplied argset.
637/// Returns `true` only if something went wrong.
638/// The complement of this function is getParameters().
639/// \param[in] dataList Set of leaf nodes to match.
640/// \param[out] outputSet Output set.
641/// \param[in] valueOnly If this parameter is true, we only match leaves that
642/// depend on the value of any arg in `dataList`.
643
645{
646 outputSet.clear();
647 outputSet.setName("dependents");
648
649 if (!dataList)
650 return false;
651
652 // Make iterator over tree leaf node list
653 RooArgSet leafList("leafNodeServerList");
654 treeNodeServerList(&leafList, nullptr, false, true, valueOnly);
655
656 if (valueOnly) {
657 for (const auto arg : leafList) {
658 if (arg->dependsOnValue(*dataList) && arg->isLValue()) {
659 outputSet.add(*arg);
660 }
661 }
662 } else {
663 for (const auto arg : leafList) {
664 if (arg->dependsOn(*dataList) && arg->isLValue()) {
665 outputSet.add(*arg);
666 }
667 }
668 }
669
670 return false;
671}
672
673/// Create a RooArgSet with all components (branch nodes) of the
674/// expression tree headed by this object.
676{
677 RooArgSet *set = new RooArgSet((std::string(GetName()) + "_components").c_str());
679
681}
682
683/// Overloadable function in which derived classes can implement
684/// consistency checks of the variables. If this function returns
685/// true, indicating an error, the fitter or generator will abort.
686
688{
689 return false;
690}
691
692/// Recursively call checkObservables on all nodes in the expression tree
693
695{
698
699 bool ret(false);
700 for (RooAbsArg *arg : nodeList) {
701 if (arg->getAttribute("ServerDied")) {
702 coutE(LinkStateMgmt) << "RooAbsArg::recursiveCheckObservables(" << GetName()
703 << "): ERROR: one or more servers of node " << arg->GetName() << " no longer exists!"
704 << std::endl;
705 arg->Print("v");
706 ret = true;
707 }
708 ret |= arg->checkObservables(nset);
709 }
710
711 return ret;
712}
713
714/// Test whether we depend on (ie, are served by) any object in the
715/// specified collection. Uses the dependsOn(RooAbsArg&) member function.
716
718{
719 // Test whether we depend on (ie, are served by) any object in the
720 // specified collection. Uses the dependsOn(RooAbsArg&) member function.
721
722 for (auto server : serverList) {
724 return true;
725 }
726 }
727 return false;
728}
729
730/// Test whether we depend on (ie, are served by) an object with a specific name.
732{
733 if (this == ignoreArg)
734 return false;
735
736 // First check if testArg is self
737 if (testArgNamePtr == namePtr())
738 return true;
739
740 // Next test direct dependence
741 RooAbsArg *foundServer = _serverList.findByNamePointer(testArgNamePtr);
742 if (foundServer) {
743
744 // Return true if valueOnly is FALSE or if server is value server, otherwise keep looking
745 if (!valueOnly || foundServer->isValueServer(*this)) {
746 return true;
747 }
748 }
749
750 // If not, recurse
751 for (const auto server : _serverList) {
752 if (!valueOnly || server->isValueServer(*this)) {
753 if (server->dependsOn(testArgNamePtr, ignoreArg, valueOnly)) {
754 return true;
755 }
756 }
757 }
758
759 return false;
760}
761
762/// Test if any of the nodes of tree are shared with that of the given tree
763
765{
766 RooArgSet list("treeNodeList");
767 treeNodeServerList(&list);
768
769 return valueOnly ? testArg.dependsOnValue(list) : testArg.dependsOn(list);
770}
771
772/// Test if any of the dependents of the arg tree (as determined by getObservables)
773/// overlaps with those of the testArg.
774
776{
777 return observableOverlaps(dset->get(), testArg);
778}
779
780/// Test if any of the dependents of the arg tree (as determined by getObservables)
781/// overlaps with those of the testArg.
782
784{
785 return testArg.dependsOn(*std::unique_ptr<RooArgSet>{getObservables(nset)});
786}
787
788/// Mark this object as having changed its value, and propagate this status
789/// change to all of our clients. If the object is not in automatic dirty
790/// state propagation mode, this call has no effect.
791
793{
794 if (_operMode != Auto || _inhibitDirty)
795 return;
796
797 // Handle no-propagation scenarios first
798 if (_clientListValue.empty()) {
799 _valueDirty = true;
800 return;
801 }
802
803 // Cyclical dependency interception
804 if (source == nullptr) {
805 source = this;
806 } else if (source == this) {
807 // Cyclical dependency, abort
808 coutE(LinkStateMgmt) << "RooAbsArg::setValueDirty(" << GetName()
809 << "): cyclical dependency detected, source = " << source->GetName() << std::endl;
810 // assert(0) ;
811 return;
812 }
813
814 // Propagate dirty flag to all clients if this is a down->up transition
815 if (_verboseDirty) {
816 cxcoutD(LinkStateMgmt) << "RooAbsArg::setValueDirty(" << (source ? source->GetName() : "self") << "->"
817 << GetName() << "," << this << "): dirty flag " << (_valueDirty ? "already " : "")
818 << "raised" << std::endl;
819 }
820
821 _valueDirty = true;
822
823 for (auto client : _clientListValue) {
824 client->setValueDirty(source);
825 }
826}
827
828/// Mark this object as having changed its shape, and propagate this status
829/// change to all of our clients.
830
832{
833 if (_verboseDirty) {
834 cxcoutD(LinkStateMgmt) << "RooAbsArg::setShapeDirty(" << GetName() << "): dirty flag "
835 << (_shapeDirty ? "already " : "") << "raised" << std::endl;
836 }
837
838 if (_clientListShape.empty()) {
839 _shapeDirty = true;
840 return;
841 }
842
843 // Set 'dirty' shape state for this object and propagate flag to all its clients
844 if (source == nullptr) {
845 source = this;
846 } else if (source == this) {
847 // Cyclical dependency, abort
848 coutE(LinkStateMgmt) << "RooAbsArg::setShapeDirty(" << GetName() << "): cyclical dependency detected"
849 << std::endl;
850 return;
851 }
852
853 // Propagate dirty flag to all clients if this is a down->up transition
854 _shapeDirty = true;
855
856 for (auto client : _clientListShape) {
857 client->setShapeDirty(source);
858 client->setValueDirty(source);
859 }
860}
861
862/// Replace all direct servers of this object with the new servers in `newServerList`.
863/// This substitutes objects that we receive values from with new objects that have the same name.
864/// See: recursiveRedirectServers() Use recursive version if servers that are only indirectly serving this object should
865/// be replaced as well. See: redirectServers() If only the direct servers of an object need to be replaced.
866///
867/// Note that changing the types of objects is generally allowed, but can be wrong if the interface of an object
868/// changes. For example, one can reparametrise a model by substituting a variable with a function:
869/// \f[
870/// f(x\, |\, a) = a \cdot x \rightarrow f(x\, |\, b) = (2.1 \cdot b) \cdot x
871/// \f]
872/// If an object, however, expects a PDF, and this is substituted with a function that isn't normalised, wrong results
873/// might be obtained or it might even crash the program. The types of the objects being substituted are not checked.
874///
875/// \param[in] newSetOrig Set of new servers that should be used instead of the current servers.
876/// \param[in] mustReplaceAll A warning is printed and error status is returned if not all servers could be
877/// substituted successfully.
878/// \param[in] nameChange If false, an object named "x" is only replaced with an object also named "x" in `newSetOrig`.
879/// If the object in `newSet` is called differently, set `nameChange` to true and use setAttribute() on the x object:
880/// ```
881/// objectToReplaceX.setAttribute("ORIGNAME:x")
882/// ```
883/// Now, the renamed object will be selected based on the attribute "ORIGNAME:<name>".
884/// \param[in] isRecursionStep Internal switch used when called from recursiveRedirectServers().
886 bool isRecursionStep)
887{
888 // Trivial case, no servers
889 if (_serverList.empty())
890 return false;
891
892 // We don't need to do anything if there are no new servers or if the only
893 // new server is this RooAbsArg itself. And by returning early, we avoid
894 // potentially annoying side effects of the redirectServersHook.
895 if (newSetOrig.empty() || (newSetOrig.size() == 1 && newSetOrig[0] == this))
896 return false;
897
898 // Strip any non-matching removal nodes from newSetOrig
899 std::unique_ptr<RooArgSet> newSetOwned;
901
902 if (nameChange) {
903 newSetOwned = std::make_unique<RooArgSet>();
904 for (auto arg : *newSet) {
905
906 if (std::string("REMOVAL_DUMMY") == arg->GetName()) {
907
908 if (arg->getAttribute("REMOVE_ALL")) {
909 newSetOwned->add(*arg);
910 } else if (arg->getAttribute(Form("REMOVE_FROM_%s", getStringAttribute("ORIGNAME")))) {
911 newSetOwned->add(*arg);
912 }
913 } else {
914 newSetOwned->add(*arg);
915 }
916 }
917 newSet = newSetOwned.get();
918 }
919
920 // Replace current servers with new servers with the same name from the given list
921 for (auto oldServer : _serverList) {
922
923 RooAbsArg *newServer = oldServer->findNewServer(*newSet, nameChange);
924
925 if (!newServer) {
926 if (mustReplaceAll) {
927 std::stringstream ss;
928 ss << "RooAbsArg::redirectServers(" << (void *)this << "," << GetName() << "): server "
929 << oldServer->GetName() << " (" << (void *)oldServer << ") not redirected"
930 << (nameChange ? "[nameChange]" : "");
931 const std::string errorMsg = ss.str();
932 coutE(LinkStateMgmt) << errorMsg << std::endl;
933 throw std::runtime_error(errorMsg);
934 }
935 continue;
936 }
937
938 if (newServer != this) {
940 }
941 }
942
945
946 bool ret(false);
947
948 // Process the proxies
949 for (int i = 0; i < numProxies(); i++) {
950 RooAbsProxy *p = getProxy(i);
951 if (!p)
952 continue;
953 bool ret2 = p->changePointer(*newSet, nameChange, false);
954
955 if (mustReplaceAll && !ret2) {
956 auto ap = dynamic_cast<const RooArgProxy *>(p);
957 coutE(LinkStateMgmt) << "RooAbsArg::redirectServers(" << GetName() << "): ERROR, proxy '" << p->name()
958 << "' with arg '" << (ap ? ap->absArg()->GetName() : "<could not cast>")
959 << "' could not be adjusted" << std::endl;
960 ret = true;
961 }
962 }
963
964 // Optional subclass post-processing
966 return ret;
967}
968
969/// Private helper function for RooAbsArg::redirectServers().
971{
973
974 const int clientListRefCount = oldServer->_clientList.Remove(this, true);
975 const int clientListValueRefCount = oldServer->_clientListValue.Remove(this, true);
976 const int clientListShapeRefCount = oldServer->_clientListShape.Remove(this, true);
977
978 newServer->_clientList.Add(this, clientListRefCount);
979 newServer->_clientListValue.Add(this, clientListValueRefCount);
980 newServer->_clientListShape.Add(this, clientListShapeRefCount);
981
982 if (clientListValueRefCount > 0 && newServer->operMode() == ADirty && operMode() != ADirty) {
984 }
985}
986
987/// Private helper function for RooAbsArg::redirectServers().
999
1000/// Replace some servers of this object. If there are proxies that correspond
1001/// to the replaced servers, these proxies are adjusted as well.
1002/// \param[in] replacements Map that specifies which args replace which servers.
1003bool RooAbsArg::redirectServers(std::unordered_map<RooAbsArg *, RooAbsArg *> const &replacements)
1004{
1005 bool ret(false);
1006 bool nameChange = false;
1007
1009
1010 // Replace current servers with new servers with the same name from the given list
1011 for (auto oldServer : _serverList) {
1012
1015
1016 if (!newServer || newServer == this) {
1017 continue;
1018 }
1019
1020 if (nameChange == false)
1021 nameChange = strcmp(newServerFound->first->GetName(), newServerFound->second->GetName()) != 0;
1022
1024 newList.add(*newServer);
1025 }
1026
1027 // No servers were replaced, we don't need to process proxies and call the
1028 // redirectServersHook.
1029 if (newList.empty())
1030 return ret;
1031
1032 setValueDirty();
1033 setShapeDirty();
1034
1035 // Process the proxies
1036 for (int i = 0; i < numProxies(); i++) {
1037 if (RooAbsProxy *p = getProxy(i)) {
1038 p->changePointer(replacements);
1039 }
1040 }
1041
1042 // Optional subclass post-processing
1043 ret |= callRedirectServersHook(newList, false, nameChange, false);
1044 return ret;
1045}
1046
1047/// Find the new server in the specified set that matches the old server.
1048///
1049/// \param[in] newSet Search this set by name for a new server.
1050/// \param[in] nameChange If true, search for an item with the bool attribute "ORIGNAME:<oldName>" set.
1051/// Use `<object>.setAttribute("ORIGNAME:<oldName>")` to set this attribute.
1052/// \return Pointer to the new server or `nullptr` if there's no unique match.
1054{
1055 RooAbsArg *newServer = nullptr;
1056 if (!nameChange) {
1057 newServer = newSet.find(*this);
1058 } else {
1059 // Name changing server redirect:
1060 // use 'ORIGNAME:<oldName>' attribute instead of name of new server
1061 TString nameAttrib("ORIGNAME:");
1062 nameAttrib.Append(GetName());
1063
1064 if (auto tmp = std::unique_ptr<RooAbsCollection>{newSet.selectByAttrib(nameAttrib, true)}) {
1065
1066 // Check if any match was found
1067 if (tmp->empty()) {
1068 return nullptr;
1069 }
1070
1071 // Check if match is unique
1072 if (tmp->size() > 1) {
1073 std::stringstream ss;
1074 ss << "RooAbsArg::redirectServers(" << GetName() << "): FATAL Error, " << tmp->size() << " servers with "
1075 << nameAttrib << " attribute";
1076 coutF(LinkStateMgmt) << ss.str() << std::endl;
1077 tmp->Print("v");
1078 throw std::runtime_error(ss.str());
1079 }
1080
1081 // use the unique element in the set
1082 newServer = tmp->first();
1083 }
1084 }
1085 return newServer;
1086}
1087
1088namespace {
1089
1091 bool recurseInNewSet, std::set<RooAbsArg const *> &callStack)
1092{
1093 // Cyclic recursion protection
1094 {
1095 auto it = callStack.lower_bound(arg);
1096 if (it != callStack.end() && arg == *it) {
1097 return false;
1098 }
1099 callStack.insert(it, arg);
1100 }
1101
1102 // Do not recurse into newset if not so specified
1103 // if (!recurseInNewSet && newSet.contains(*arg)) {
1104 // return false;
1105 // }
1106
1107 // Apply the redirectServers function recursively on all branch nodes in this argument tree.
1108 bool ret(false);
1109
1110 oocxcoutD(arg, LinkStateMgmt) << "RooAbsArg::recursiveRedirectServers(" << arg << "," << arg->GetName()
1111 << ") newSet = " << newSet << " mustReplaceAll = " << (mustReplaceAll ? "T" : "F")
1112 << " nameChange = " << (nameChange ? "T" : "F")
1113 << " recurseInNewSet = " << (recurseInNewSet ? "T" : "F") << std::endl;
1114
1115 // Do redirect on self (identify operation as recursion step)
1117
1118 // Do redirect on servers
1119 for (const auto server : arg->servers()) {
1121 }
1122
1123 callStack.erase(arg);
1124 return ret;
1125}
1126
1127} // namespace
1128
1129/// Recursively replace all servers with the new servers in `newSet`.
1130/// This substitutes objects that we receive values from (also indirectly
1131/// through other objects) with new objects that have the same name.
1132///
1133/// *Copied from redirectServers:*
1134///
1135/// \copydetails RooAbsArg::redirectServers
1136/// \param newSet Roo collection
1137/// \param recurseInNewSet be recursive
1139 bool recurseInNewSet)
1140{
1141 // For cyclic recursion protection
1142 std::set<const RooAbsArg *> callStack;
1143
1145}
1146
1147/// Function that is called at the end of redirectServers(). Can be overloaded
1148/// to inject some class-dependent behavior after server redirection, e.g.
1149/// resetting of caches. The return value is meant to be an error flag, so in
1150/// case something goes wrong the function should return `true`. If you
1151/// overload this function, don't forget to also call the function of the
1152/// base class.
1153///
1154/// See: redirectServers() For a detailed explanation of the function parameters.
1155///
1156// \param[in] newServerList One of the original parameters passed to redirectServers().
1157// \param[in] mustReplaceAll One of the original parameters passed to redirectServers().
1158// \param[in] nameChange One of the original parameters passed to redirectServers().
1159// \param[in] isRecursiveStep One of the original parameters passed to redirectServers().
1160bool RooAbsArg::redirectServersHook(const RooAbsCollection & /*newServerList*/, bool /*mustReplaceAll*/,
1161 bool /*nameChange*/, bool /*isRecursiveStep*/)
1162{
1163 setProxyNormSet(nullptr);
1164 return false;
1165}
1166
1167/// Register an RooArgProxy in the proxy list. This function is called by owned
1168/// proxies upon creation. After registration, this arg will forward pointer
1169/// changes from serverRedirects and updates in cached normalization sets
1170/// to the proxies immediately after they occur. The proxied argument is
1171/// also added as value and/or shape server
1172
1174{
1175 // Every proxy can be registered only once
1176 if (_proxyList.FindObject(&proxy)) {
1177 coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named " << proxy.GetName()
1178 << " for arg " << proxy.absArg()->GetName() << " already registered" << std::endl;
1179 return;
1180 }
1181
1182 // std::cout << (void*)this << " " << GetName() << ": registering proxy "
1183 // << (void*)&proxy << " with name " << proxy.name() << " in mode "
1184 // << (proxy.isValueServer()?"V":"-") << (proxy.isShapeServer()?"S":"-") << std::endl ;
1185
1186 // Register proxied object as server
1187 if (proxy.absArg()) {
1188 addServer(*proxy.absArg(), proxy.isValueServer(), proxy.isShapeServer());
1189 }
1190
1191 // Register proxy itself
1193 _proxyListCache.isDirty = true;
1194}
1195
1196/// Remove proxy from proxy list. This functions is called by owned proxies
1197/// upon their destruction.
1198
1205
1206/// Register an RooSetProxy in the proxy list. This function is called by owned
1207/// proxies upon creation. After registration, this arg will forward pointer
1208/// changes from serverRedirects and updates in cached normalization sets
1209/// to the proxies immediately after they occur.
1210
1212{
1213 // Every proxy can be registered only once
1214 if (_proxyList.FindObject(&proxy)) {
1215 coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named " << proxy.GetName()
1216 << " already registered" << std::endl;
1217 return;
1218 }
1219
1220 // Register proxy itself
1222 _proxyListCache.isDirty = true;
1223}
1224
1225/// Remove proxy from proxy list. This functions is called by owned proxies
1226/// upon their destruction.
1227
1234
1235/// Register an RooListProxy in the proxy list. This function is called by owned
1236/// proxies upon creation. After registration, this arg will forward pointer
1237/// changes from serverRedirects and updates in cached normalization sets
1238/// to the proxies immediately after they occur.
1239
1241{
1242 // Every proxy can be registered only once
1243 if (_proxyList.FindObject(&proxy)) {
1244 coutE(LinkStateMgmt) << "RooAbsArg::registerProxy(" << GetName() << "): proxy named " << proxy.GetName()
1245 << " already registered" << std::endl;
1246 return;
1247 }
1248
1249 // Register proxy itself
1252 _proxyListCache.isDirty = true;
1253 if (_proxyList.GetEntries() != nProxyOld + 1) {
1254 std::cout << "RooAbsArg::registerProxy(" << GetName() << ") proxy registration failure! nold=" << nProxyOld
1255 << " nnew=" << _proxyList.GetEntries() << std::endl;
1256 }
1257}
1258
1259/// Remove proxy from proxy list. This functions is called by owned proxies
1260/// upon their destruction.
1261
1268
1269/// Return the nth proxy from the proxy list.
1270
1272{
1273 // Cross cast: proxy list returns TObject base pointer, we need
1274 // a RooAbsProxy base pointer. C++ standard requires
1275 // a dynamic_cast for this.
1276 return dynamic_cast<RooAbsProxy *>(_proxyList.At(index));
1277}
1278
1279/// Return the number of registered proxies.
1280
1282{
1283 return _proxyList.GetEntriesFast();
1284}
1285
1286/// Forward a change in the cached normalization argset
1287/// to all the registered proxies.
1288
1290{
1292 // First time we loop over proxies: cache the results to avoid future
1293 // costly dynamic_casts
1294 _proxyListCache.cache.clear();
1295 for (int i = 0; i < numProxies(); i++) {
1296 RooAbsProxy *p = getProxy(i);
1297 if (!p)
1298 continue;
1299 _proxyListCache.cache.push_back(p);
1300 }
1301 _proxyListCache.isDirty = false;
1302 }
1303
1304 for (auto &p : _proxyListCache.cache) {
1305 p->changeNormSet(nset);
1306 }
1307
1308 // If the proxy normSet changed, we also have to set our value dirty flag.
1309 // Otherwise, value for the new normalization set might not get recomputed!
1310 setValueDirty();
1311}
1312
1313/// Overloadable function for derived classes to implement
1314/// attachment as branch to a TTree
1315
1317{
1318 coutE(Contents) << "RooAbsArg::attachToTree(" << GetName() << "): Cannot be attached to a TTree" << std::endl;
1319}
1320
1321/// WVE (08/21/01) Probably obsolete now
1322
1324{
1325 return true;
1326}
1327
1328/// Print object name
1329
1330void RooAbsArg::printName(std::ostream &os) const
1331{
1332 os << GetName();
1333}
1334
1335/// Print object title
1336
1337void RooAbsArg::printTitle(std::ostream &os) const
1338{
1339 os << GetTitle();
1340}
1341
1342/// Print object class name
1343
1344void RooAbsArg::printClassName(std::ostream &os) const
1345{
1346 os << ClassName();
1347}
1348
1349/// Print address of this RooAbsArg.
1350void RooAbsArg::printAddress(std::ostream &os) const
1351{
1352 os << this;
1353}
1354
1355/// Print object arguments, ie its proxies
1356
1357void RooAbsArg::printArgs(std::ostream &os) const
1358{
1359 // Print nothing if there are no dependencies
1360 if (numProxies() == 0)
1361 return;
1362
1363 os << "[ ";
1364 for (Int_t i = 0; i < numProxies(); i++) {
1365 RooAbsProxy *p = getProxy(i);
1366 if (p == nullptr)
1367 continue;
1368 if (!TString(p->name()).BeginsWith("!")) {
1369 p->print(os);
1370 os << " ";
1371 }
1372 }
1373 printMetaArgs(os);
1374 os << "]";
1375}
1376
1377/// Define default contents to print
1378
1380{
1381 return kName | kClassName | kValue | kArgs;
1382}
1383
1384/// Implement multi-line detailed printing
1385
1386void RooAbsArg::printMultiline(std::ostream &os, Int_t /*contents*/, bool /*verbose*/, TString indent) const
1387{
1388 os << indent << "--- RooAbsArg ---" << std::endl;
1389 // dirty state flags
1390 os << indent << " Value State: ";
1391 switch (_operMode) {
1392 case ADirty: os << "FORCED DIRTY"; break;
1393 case AClean: os << "FORCED clean"; break;
1394 case Auto: os << (isValueDirty() ? "DIRTY" : "clean"); break;
1395 }
1396 os << std::endl << indent << " Shape State: " << (isShapeDirty() ? "DIRTY" : "clean") << std::endl;
1397 // attribute list
1398 os << indent << " Attributes: ";
1399 printAttribList(os);
1400 os << std::endl;
1401 // our memory address (for x-referencing with client addresses of other args)
1402 os << indent << " Address: " << (void *)this << std::endl;
1403 // client list
1404 os << indent << " Clients: " << std::endl;
1405 for (const auto client : _clientList) {
1406 os << indent << " (" << (void *)client << "," << (_clientListValue.containsByNamePtr(client) ? "V" : "-")
1407 << (_clientListShape.containsByNamePtr(client) ? "S" : "-") << ") ";
1408 client->printStream(os, kClassName | kTitle | kName, kSingleLine);
1409 }
1410
1411 // server list
1412 os << indent << " Servers: " << std::endl;
1413 for (const auto server : _serverList) {
1414 os << indent << " (" << (void *)server << "," << (server->_clientListValue.containsByNamePtr(this) ? "V" : "-")
1415 << (server->_clientListShape.containsByNamePtr(this) ? "S" : "-") << ") ";
1416 server->printStream(os, kClassName | kName | kTitle, kSingleLine);
1417 }
1418
1419 // proxy list
1420 os << indent << " Proxies: " << std::endl;
1421 for (int i = 0; i < numProxies(); i++) {
1423 if (!proxy)
1424 continue;
1425 os << indent << " " << proxy->name() << " -> ";
1426 if (auto *argProxy = dynamic_cast<RooArgProxy *>(proxy)) {
1427 if (RooAbsArg *parg = argProxy->absArg()) {
1428 parg->printStream(os, kName, kSingleLine);
1429 } else {
1430 os << " (empty)" << std::endl;
1431 }
1432 // If a RooAbsProxy is not a RooArgProxy, it is a RooSetProxy or a
1433 // RooListProxy. However, they are treated the same in this function, so
1434 // we try the dynamic cast to their common base class, RooAbsCollection.
1435 } else if (auto *collProxy = dynamic_cast<RooAbsCollection *>(proxy)) {
1436 os << std::endl;
1438 moreIndent.Append(" ");
1439 collProxy->printStream(os, kName, kStandard, moreIndent.Data());
1440 } else {
1441 throw std::runtime_error("Unsupported proxy type.");
1442 }
1443 }
1444}
1445
1446/// Print object tree structure
1447
1448void RooAbsArg::printTree(std::ostream &os, TString /*indent*/) const
1449{
1450 const_cast<RooAbsArg *>(this)->printCompactTree(os);
1451}
1452
1453/// Ostream operator
1454
1455std::ostream &operator<<(std::ostream &os, RooAbsArg const &arg)
1456{
1457 arg.writeToStream(os, true);
1458 return os;
1459}
1460
1461/// Istream operator
1462
1463std::istream &operator>>(std::istream &is, RooAbsArg &arg)
1464{
1465 arg.readFromStream(is, true, false);
1466 return is;
1467}
1468
1469/// Print the attribute list
1470
1471void RooAbsArg::printAttribList(std::ostream &os) const
1472{
1473 std::set<std::string>::const_iterator iter = _boolAttrib.begin();
1474 bool first(true);
1475 while (iter != _boolAttrib.end()) {
1476 os << (first ? " [" : ",") << *iter;
1477 first = false;
1478 ++iter;
1479 }
1480 if (!first)
1481 os << "] ";
1482}
1483
1484/// Bind this node to objects in `set`.
1485/// Search the set for objects that have the same name as our servers, and
1486/// attach ourselves to those. After this operation, this node is computing its
1487/// values based on the new servers. This can be used to e.g. read values from
1488// a dataset.
1489
1491{
1493 branchNodeServerList(&branches, nullptr, true);
1494
1495 for (auto const &branch : branches) {
1496 branch->redirectServers(set, false, false);
1497 }
1498}
1499
1500/// Replace server nodes with names matching the dataset variable names
1501/// with those data set variables, making this PDF directly dependent on the dataset.
1502
1504{
1505 attachArgs(*data.get());
1506}
1507
1508/// Replace server nodes with names matching the dataset variable names
1509/// with those data set variables, making this PDF directly dependent on the dataset
1510
1515
1516/// Utility function used by TCollection::Sort to compare contained TObjects
1517/// We implement comparison by name, resulting in alphabetical sorting by object name.
1518
1520{
1521 return strcmp(GetName(), other->GetName());
1522}
1523
1524/// Print information about current value dirty state information.
1525/// If depth flag is true, information is recursively printed for
1526/// all nodes in this arg tree.
1527
1529{
1530 if (depth) {
1531
1534 for (RooAbsArg *branch : branchList) {
1535 branch->printDirty(false);
1536 }
1537
1538 } else {
1539 std::cout << GetName() << " : ";
1540 switch (_operMode) {
1541 case AClean: std::cout << "FORCED clean"; break;
1542 case ADirty: std::cout << "FORCED DIRTY"; break;
1543 case Auto: std::cout << "Auto " << (isValueDirty() ? "DIRTY" : "clean");
1544 }
1545 std::cout << std::endl;
1546 }
1547}
1548
1549/// Activate cache mode optimization with given definition of observables.
1550/// The cache operation mode of all objects in the expression tree will
1551/// modified such that all nodes that depend directly or indirectly on
1552/// any of the listed observables will be set to ADirty, as they are
1553/// expected to change every time. This save change tracking overhead for
1554/// nodes that are a priori known to change every time
1555
1557{
1559 RooArgSet opt;
1560 optimizeCacheMode(observables, opt, proc);
1561
1562 coutI(Optimization) << "RooAbsArg::optimizeCacheMode(" << GetName() << ") nodes " << opt
1563 << " depend on observables, "
1564 << "changing cache operation mode from change tracking to unconditional evaluation" << std::endl;
1565}
1566
1567/// Activate cache mode optimization with given definition of observables.
1568/// The cache operation mode of all objects in the expression tree will
1569/// modified such that all nodes that depend directly or indirectly on
1570/// any of the listed observables will be set to ADirty, as they are
1571/// expected to change every time. This save change tracking overhead for
1572/// nodes that are a priori known to change every time
1573
1576{
1577 // Optimization applies only to branch nodes, not to leaf nodes
1578 if (!isDerived()) {
1579 return;
1580 }
1581
1582 // Terminate call if this node was already processed (tree structure may be cyclical)
1583 // LM : RooLinkedList::findArg looks by name and not but by object pointer,
1584 // should one use RooLinkedList::FindObject (look by pointer) instead of findArg when
1585 // tree contains nodes with the same name ?
1586 // Add an info message if the require node does not exist but a different node already exists with same name
1587
1588 if (processedNodes.FindObject(this))
1589 return;
1590
1591 // check if findArgs returns something different (i.e. a different node with same name) when
1592 // this node has not been processed (FindObject returns a null pointer)
1593 auto obj = processedNodes.findArg(this);
1594 assert(obj != this); // obj == this cannot happen
1595 if (obj) {
1596 // here for nodes with duplicate names
1597 cxcoutI(Optimization) << "RooAbsArg::optimizeCacheMode(" << GetName() << " node " << this << " exists already as "
1598 << obj << " but with the SAME name !" << std::endl;
1599 }
1600
1601 processedNodes.Add(this);
1602
1603 // Set cache mode operator to 'AlwaysDirty' if we depend on any of the given observables
1604 if (dependsOnValue(observables)) {
1605
1606 if (dynamic_cast<RooRealIntegral *>(this)) {
1607 cxcoutI(Integration)
1608 << "RooAbsArg::optimizeCacheMode(" << GetName()
1609 << ") integral depends on value of one or more observables and will be evaluated for every event"
1610 << std::endl;
1611 }
1612 optimizedNodes.add(*this, true);
1613 if (operMode() == AClean) {
1614 } else {
1615 setOperMode(ADirty, true); // WVE propagate flag recursively to top of tree
1616 }
1617 } else {
1618 }
1619 // Process any RooAbsArgs contained in any of the caches of this object
1620 for (Int_t i = 0; i < numCaches(); i++) {
1622 }
1623
1624 // Forward calls to all servers
1625 for (const auto server : _serverList) {
1626 server->optimizeCacheMode(observables, optimizedNodes, processedNodes);
1627 }
1628}
1629
1630/// Find branch nodes with all-constant parameters, and add them to the list of
1631/// nodes that can be cached with a dataset in a test statistic calculation
1632
1634{
1636 bool ret = findConstantNodes(observables, cacheList, proc);
1637
1638 // If node can be optimized and hasn't been identified yet, add it to the list
1639 coutI(Optimization) << "RooAbsArg::findConstantNodes(" << GetName() << "): components " << cacheList
1640 << " depend exclusively on constant parameters and will be precalculated and cached"
1641 << std::endl;
1642
1643 return ret;
1644}
1645
1646/// Find branch nodes with all-constant parameters, and add them to the list of
1647/// nodes that can be cached with a dataset in a test statistic calculation
1648
1650{
1651 // Caching only applies to branch nodes
1652 if (!isDerived()) {
1653 return false;
1654 }
1655
1656 // Terminate call if this node was already processed (tree structure may be cyclical)
1657 if (processedNodes.findArg(this)) {
1658 return false;
1659 } else {
1660 processedNodes.Add(this);
1661 }
1662
1663 // Check if node depends on any non-constant parameter
1664 bool canOpt(true);
1666 getParameters(&observables, paramSet);
1667 for (RooAbsArg *param : paramSet) {
1668 if (!param->isConstant()) {
1669 canOpt = false;
1670 break;
1671 }
1672 }
1673
1674 if (getAttribute("NeverConstant")) {
1675 canOpt = false;
1676 }
1677
1678 if (canOpt) {
1679 setAttribute("ConstantExpression");
1680 }
1681
1682 // If yes, list node eligible for caching, if not test nodes one level down
1683 if (canOpt || getAttribute("CacheAndTrack")) {
1684
1685 if (!cacheList.find(*this) && dependsOnValue(observables) && !observables.find(*this)) {
1686
1687 // Add to cache list
1688 cxcoutD(Optimization) << "RooAbsArg::findConstantNodes(" << GetName()
1689 << ") adding self to list of constant nodes" << std::endl;
1690
1691 if (canOpt)
1692 setAttribute("ConstantExpressionCached");
1693 cacheList.add(*this, false);
1694 }
1695 }
1696
1697 if (!canOpt) {
1698
1699 // If not, see if next level down can be cached
1700 for (const auto server : _serverList) {
1701 if (server->isDerived()) {
1702 server->findConstantNodes(observables, cacheList, processedNodes);
1703 }
1704 }
1705 }
1706
1707 // Forward call to all cached contained in current object
1708 for (Int_t i = 0; i < numCaches(); i++) {
1710 }
1711
1712 return false;
1713}
1714
1715/// Interface function signaling a request to perform constant term
1716/// optimization. This default implementation takes no action other than to
1717/// forward the calls to all servers
1718
1720{
1721 for (const auto server : _serverList) {
1722 server->constOptimizeTestStatistic(opcode, doAlsoTrackingOpt);
1723 }
1724}
1725
1726/// Change cache operation mode to given mode. If recurseAdirty
1727/// is true, then a mode change to AlwaysDirty will automatically
1728/// be propagated recursively to all client nodes
1729
1731{
1732 // Prevent recursion loops
1733 if (mode == _operMode)
1734 return;
1735
1736 _operMode = mode;
1737 _fast = ((mode == AClean) || dynamic_cast<RooRealVar *>(this) || dynamic_cast<RooConstVar *>(this));
1738 for (Int_t i = 0; i < numCaches(); i++) {
1739 getCache(i)->operModeHook();
1740 }
1741 operModeHook();
1742
1743 // Propagate to all clients
1744 if (mode == ADirty && recurseADirty) {
1745 for (auto clientV : _clientListValue) {
1746 clientV->setOperMode(mode);
1747 }
1748 }
1749}
1750
1751/// Print tree structure of expression tree on stdout, or to file if filename is specified.
1752/// If namePat is not "*", only nodes with names matching the pattern will be printed.
1753/// The client argument is used in recursive calls to properly display the value or shape nature
1754/// of the client-server links. It should be zero in calls initiated by users.
1755
1756void RooAbsArg::printCompactTree(const char *indent, const char *filename, const char *namePat, RooAbsArg *client)
1757{
1758 if (filename) {
1759 std::ofstream ofs(filename);
1761 } else {
1762 printCompactTree(std::cout, indent, namePat, client);
1763 }
1764}
1765
1766/// Print tree structure of expression tree on given ostream.
1767/// If namePat is not "*", only nodes with names matching the pattern will be printed.
1768/// The client argument is used in recursive calls to properly display the value or shape nature
1769/// of the client-server links. It should be zero in calls initiated by users.
1770
1771void RooAbsArg::printCompactTree(std::ostream &os, const char *indent, const char *namePat, RooAbsArg *client)
1772{
1773 if (!namePat || TString(GetName()).Contains(namePat)) {
1774 os << indent << this;
1775 if (client) {
1776 os << "/";
1777 if (isValueServer(*client))
1778 os << "V";
1779 else
1780 os << "-";
1781 if (isShapeServer(*client))
1782 os << "S";
1783 else
1784 os << "-";
1785 }
1786 os << " ";
1787
1788 os << ClassName() << "::" << GetName() << " = ";
1789 printValue(os);
1790
1791 if (!_serverList.empty()) {
1792 switch (operMode()) {
1793 case Auto: os << " [Auto," << (isValueDirty() ? "Dirty" : "Clean") << "] "; break;
1794 case AClean: os << " [ACLEAN] "; break;
1795 case ADirty: os << " [ADIRTY] "; break;
1796 }
1797 }
1798 os << std::endl;
1799
1800 for (Int_t i = 0; i < numCaches(); i++) {
1802 }
1804 }
1805
1807 indent2 += " ";
1808 for (const auto arg : _serverList) {
1809 arg->printCompactTree(os, indent2, namePat, this);
1810 }
1811}
1812
1813/// Print tree structure of expression tree on given ostream, only branch nodes are printed.
1814/// Lead nodes (variables) will not be shown
1815///
1816/// If namePat is not "*", only nodes with names matching the pattern will be printed.
1817
1819{
1820 if (nLevel == 0)
1821 return;
1822 if (isFundamental())
1823 return;
1824 auto rmodel = dynamic_cast<RooResolutionModel *>(this);
1825 if (rmodel && rmodel->isConvolved())
1826 return;
1827 if (InheritsFrom("RooConstVar"))
1828 return;
1829
1830 if (!namePat || TString(GetName()).Contains(namePat)) {
1831 std::cout << indent;
1832 Print();
1833 }
1834
1836 indent2 += " ";
1837 for (const auto arg : _serverList) {
1838 arg->printComponentTree(indent2.Data(), namePat, nLevel - 1);
1839 }
1840}
1841
1842/// Construct a mangled name from the actual name that
1843/// is free of any math symbols that might be interpreted by TTree
1844
1846{
1847 // Check for optional alternate name of branch for this argument
1849 if (getStringAttribute("BranchName")) {
1850 rawBranchName = getStringAttribute("BranchName");
1851 }
1852
1854 cleanName.ReplaceAll("/", "D");
1855 cleanName.ReplaceAll("-", "M");
1856 cleanName.ReplaceAll("+", "P");
1857 cleanName.ReplaceAll("*", "X");
1858 cleanName.ReplaceAll("[", "L");
1859 cleanName.ReplaceAll("]", "R");
1860 cleanName.ReplaceAll("(", "L");
1861 cleanName.ReplaceAll(")", "R");
1862 cleanName.ReplaceAll("{", "L");
1863 cleanName.ReplaceAll("}", "R");
1864
1865 return cleanName;
1866}
1867
1868/// Hook function interface for object to insert additional information
1869/// when printed in the context of a tree structure. This default
1870/// implementation prints nothing
1871
1872void RooAbsArg::printCompactTreeHook(std::ostream &, const char *) {}
1873
1874/// Register RooAbsCache with this object. This function is called
1875/// by RooAbsCache constructors for objects that are a datamember
1876/// of this RooAbsArg. By registering itself the RooAbsArg is aware
1877/// of all its cache data members and will forward server change
1878/// and cache mode change calls to the cache objects, which in turn
1879/// can forward them their contents
1880
1882{
1883 _cacheList.push_back(&cache);
1884}
1885
1886/// Unregister a RooAbsCache. Called from the RooAbsCache destructor
1887
1889{
1890 _cacheList.erase(std::remove(_cacheList.begin(), _cacheList.end(), &cache), _cacheList.end());
1891}
1892
1893/// Return number of registered caches
1894
1896{
1897 return _cacheList.size();
1898}
1899
1900/// Return registered cache object by index
1901
1903{
1904 return _cacheList[index];
1905}
1906
1907/// Return RooArgSet with all variables (tree leaf nodes of expression tree)
1908
1913
1914/// Create a GraphViz .dot file visualizing the expression tree headed by
1915/// this RooAbsArg object. Use the GraphViz tool suite to make e.g. a gif
1916/// or ps file from the .dot file.
1917/// If a node derives from RooAbsReal, its current (unnormalised) value is
1918/// printed as well.
1919///
1920/// Based on concept developed by Kyle Cranmer.
1921
1922void RooAbsArg::graphVizTree(const char *fileName, const char *delimiter, bool useTitle, bool useLatex)
1923{
1924 std::ofstream ofs(fileName);
1925 if (!ofs) {
1926 coutE(InputArguments) << "RooAbsArg::graphVizTree() ERROR: Cannot open graphViz output file with name "
1927 << fileName << std::endl;
1928 return;
1929 }
1931}
1932
1933/// Write the GraphViz representation of the expression tree headed by
1934/// this RooAbsArg object to the given ostream.
1935/// If a node derives from RooAbsReal, its current (unnormalised) value is
1936/// printed as well.
1937///
1938/// Based on concept developed by Kyle Cranmer.
1939
1940void RooAbsArg::graphVizTree(std::ostream &os, const char *delimiter, bool useTitle, bool useLatex)
1941{
1942 if (!os) {
1943 coutE(InputArguments)
1944 << "RooAbsArg::graphVizTree() ERROR: output stream provided as input argument is in invalid state"
1945 << std::endl;
1946 }
1947
1948 // silent warning messages coming when evaluating a RooAddPdf without a normalization set
1950
1951 // Write header
1952 os << "digraph \"" << GetName() << "\"{" << std::endl;
1953
1954 // First list all the tree nodes
1957
1958 // iterate over nodes
1959 for (RooAbsArg *node : nodeSet) {
1960 std::string nodeName = node->GetName();
1961 std::string nodeTitle = node->GetTitle();
1962 std::string nodeLabel = (useTitle && !nodeTitle.empty()) ? nodeTitle : nodeName;
1963
1964 // if using latex, replace ROOT's # with normal latex backslash
1965 std::string::size_type position = nodeLabel.find('#');
1966 while (useLatex && position != nodeLabel.npos) {
1967 nodeLabel.replace(position, 1, "\\");
1968 }
1969
1970 std::string typeFormat = "\\texttt{";
1971 std::string nodeType = (useLatex) ? typeFormat + node->ClassName() + "}" : node->ClassName();
1972
1973 os << "\"" << nodeName << "\" [ color=" << (node->isFundamental() ? "blue" : "red") << ", label=\"" << nodeType
1974 << delimiter << nodeLabel;
1975
1976 if (auto realNode = dynamic_cast<RooAbsReal *>(node)) {
1977 os << delimiter << realNode->getVal();
1978 }
1979
1980 os << "\"];" << std::endl;
1981 }
1982
1983 // Get set of all server links
1984 std::set<std::pair<RooAbsArg *, RooAbsArg *>> links;
1986
1987 // And write them out
1988 for (auto const &link : links) {
1989 os << "\"" << link.first->GetName() << "\" -> \"" << link.second->GetName() << "\";" << std::endl;
1990 }
1991
1992 // Write trailer
1993 os << "}" << std::endl;
1994}
1995
1996/// Utility function that inserts all point-to-point client-server connections
1997/// between any two RooAbsArgs in the expression tree headed by this object
1998/// in the linkSet argument.
1999
2000void RooAbsArg::graphVizAddConnections(std::set<std::pair<RooAbsArg *, RooAbsArg *>> &linkSet)
2001{
2002 for (const auto server : _serverList) {
2003 linkSet.insert(std::make_pair(this, server));
2004 server->graphVizAddConnections(linkSet);
2005 }
2006}
2007
2008/// Take ownership of the contents of 'comps'.
2009
2011{
2012 if (!_ownedComponents) {
2013 _ownedComponents = new RooArgSet("owned components");
2014 }
2016}
2017
2018/// Take ownership of the contents of 'comps'. Different from the overload that
2019/// takes the RooArgSet by `const&`, this version can also take an owning
2020/// RooArgSet without error, because the ownership will not be ambiguous afterwards.
2021
2023{
2024 if (!_ownedComponents) {
2025 _ownedComponents = new RooArgSet("owned components");
2026 }
2027 return _ownedComponents->addOwned(std::move(comps));
2028}
2029
2030/// \copydoc RooAbsArg::addOwnedComponents(RooAbsCollection&& comps)
2031
2033{
2034 return addOwnedComponents(static_cast<RooAbsCollection &&>(std::move(comps)));
2035}
2036
2037/// Clone tree expression of objects. All tree nodes will be owned by
2038/// the head node return by cloneTree()
2039
2041{
2042 // In the RooHelpers, there is a more general implementation that we will reuse here
2044
2045 // Adjust name of head node if requested
2046 if (newname) {
2047 head->SetName(newname);
2048 }
2049
2050 // Return the head
2051 return head;
2052}
2053
2055{
2056 if (dynamic_cast<RooTreeDataStore *>(&store)) {
2057 attachToTree(*static_cast<RooTreeDataStore &>(store).tree());
2058 } else if (dynamic_cast<RooVectorDataStore *>(&store)) {
2059 attachToVStore(static_cast<RooVectorDataStore &>(store));
2060 }
2061}
2062
2064{
2065 if (_eocache) {
2066 return *_eocache;
2067 } else {
2069 }
2070}
2071
2073{
2074 std::string suffix;
2075
2078 for (RooAbsArg *arg : branches) {
2079 const char *tmp = arg->cacheUniqueSuffix();
2080 if (tmp)
2081 suffix += tmp;
2082 }
2083 return Form("%s", suffix.c_str());
2084}
2085
2087{
2090 for (auto const &arg : branches) {
2091 for (auto const &arg2 : arg->_cacheList) {
2092 arg2->wireCache();
2093 }
2094 }
2095}
2096
2097void RooAbsArg::SetName(const char *name)
2098{
2100 auto newPtr = RooNameReg::instance().constPtr(GetName());
2101 if (newPtr != _namePtr) {
2102 // cout << "Rename '" << _namePtr->GetName() << "' to '" << name << "' (set flag in new name)" << std::endl;
2103 _namePtr = newPtr;
2106 }
2107}
2108
2109void RooAbsArg::SetNameTitle(const char *name, const char *title)
2110{
2111 TNamed::SetTitle(title);
2112 SetName(name);
2113}
2114
2115/// Stream an object of class RooAbsArg.
2116
2118{
2119 if (R__b.IsReading()) {
2120 ioReadStack().push(this);
2121 R__b.ReadClassBuffer(RooAbsArg::Class(), this);
2122 ioReadStack().pop();
2123 _namePtr = RooNameReg::instance().constPtr(GetName());
2124 _isConstant = getAttribute("Constant");
2125 } else {
2126 R__b.WriteClassBuffer(RooAbsArg::Class(), this);
2127 }
2128}
2129
2130void RooAbsArg::addToIoEvoList(RooAbsArg *newObj, TRefArray const &onfileProxyList)
2131{
2132 ioEvoList()[newObj] = std::make_unique<TRefArray>(onfileProxyList);
2133}
2134
2135/// Method called by workspace container to finalize schema evolution issues
2136/// that cannot be handled in a single ioStreamer pass.
2137///
2138/// A second pass is typically needed when evolving data member of RooAbsArg-derived
2139/// classes that are container classes with references to other members, which may
2140/// not yet be 'live' in the first ioStreamer() evolution pass.
2141///
2142/// Classes may overload this function, but must call the base method in the
2143/// overloaded call to ensure base evolution is handled properly
2144
2146{
2147 // Handling of v5-v6 migration (TRefArray _proxyList --> RooRefArray _proxyList)
2148 auto iter = ioEvoList().find(this);
2149 if (iter != ioEvoList().end()) {
2150
2151 // Transfer contents of saved TRefArray to RooRefArray now
2153 _proxyList.Expand(iter->second->GetEntriesFast());
2154 for (int i = 0; i < iter->second->GetEntriesFast(); i++) {
2155 _proxyList.Add(iter->second->At(i));
2156 }
2157 // Delete TRefArray and remove from list
2158 ioEvoList().erase(iter);
2159 }
2160}
2161
2162/// Method called by workspace container to finalize schema evolution issues
2163/// that cannot be handled in a single ioStreamer pass. This static finalize method
2164/// is called after ioStreamerPass2() is called on each directly listed object
2165/// in the workspace. It's purpose is to complete schema evolution of any
2166/// objects in the workspace that are not directly listed as content elements
2167/// (e.g. analytical convolution tokens )
2168
2170{
2171 // Handling of v5-v6 migration (TRefArray _proxyList --> RooRefArray _proxyList)
2172 for (const auto &iter : ioEvoList()) {
2173
2174 // Transfer contents of saved TRefArray to RooRefArray now
2175 if (!iter.first->_proxyList.GetEntriesFast())
2176 iter.first->_proxyList.Expand(iter.second->GetEntriesFast());
2177 for (int i = 0; i < iter.second->GetEntriesFast(); i++) {
2178 iter.first->_proxyList.Add(iter.second->At(i));
2179 }
2180 }
2181
2182 ioEvoList().clear();
2183}
2184
2189
2190/// Stream an object of class RooRefArray.
2191
2193{
2194 UInt_t R__s;
2195 UInt_t R__c;
2196 if (R__b.IsReading()) {
2197
2198 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
2199 if (R__v) {
2200 }
2201
2202 // Make temporary refArray and read that from the streamer
2203 auto refArray = std::make_unique<TRefArray>();
2204 refArray->Streamer(R__b);
2205 R__b.CheckByteCount(R__s, R__c, refArray->IsA());
2206
2207 // Schedule deferred processing of TRefArray into proxy list. Doesn't
2208 // need to be done if there are no proxies anyway.
2209 if (!refArray->IsEmpty()) {
2210 ioEvoList()[ioReadStack().top()] = std::move(refArray);
2211 }
2212
2213 } else {
2214
2215 R__c = R__b.WriteVersion(RooRefArray::IsA(), true);
2216
2217 // Make a temporary refArray and write that to the streamer
2219 for (TObject *tmpObj : *this) {
2220 refArray.Add(tmpObj);
2221 }
2222
2223 refArray.Streamer(R__b);
2224 R__b.SetByteCount(R__c, true);
2225 }
2226}
2227
2228/// Print at the prompt
2229namespace cling {
2230std::string printValue(RooAbsArg *raa)
2231{
2232 std::stringstream s;
2233 if (0 == *raa->GetName() && 0 == *raa->GetTitle()) {
2234 s << "An instance of " << raa->ClassName() << ".";
2235 return s.str();
2236 }
2237 raa->printStream(s, raa->defaultPrintContents(""), raa->defaultPrintStyle(""));
2238 return s.str();
2239}
2240} // namespace cling
2241
2242/// Disables or enables the usage of squared weights. Needs to be overloaded in
2243/// the likelihood classes for which this is relevant.
2245{
2246 for (auto *server : servers()) {
2247 server->applyWeightSquared(flag);
2248 }
2249}
2250
2251std::unique_ptr<RooAbsArg>
2253{
2254 auto newArg = std::unique_ptr<RooAbsArg>{static_cast<RooAbsArg *>(Clone())};
2255 ctx.markAsCompiled(*newArg);
2257 return newArg;
2258}
2259
2260/// Sets the token for retrieving results in the BatchMode. For internal use only.
2262{
2263 if (_dataToken == index) {
2264 return;
2265 }
2266 if (_dataToken != std::numeric_limits<std::size_t>::max()) {
2267 std::stringstream errMsg;
2268 errMsg << "The data token for \"" << GetName() << "\" is already set!"
2269 << " Are you trying to evaluate the same object by multiple RooFit::Evaluator instances?"
2270 << " This is not allowed.";
2271 throw std::runtime_error(errMsg.str());
2272 }
2273 _dataToken = index;
2274}
std::ostream & operator<<(std::ostream &os, RooAbsArg const &arg)
Ostream operator.
std::istream & operator>>(std::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
General string (char)
Definition RtypesCore.h:76
short Version_t
Class version identifier (short)
Definition RtypesCore.h:79
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
static void indent(ostringstream &buf, int indent_level)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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:2496
const_iterator begin() const
const_iterator end() const
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:76
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:569
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, equal for all objects with the same name.
Definition RooAbsArg.h:655
void Print(Option_t *options=nullptr) const override
Print the object to the defaultPrintStream().
Definition RooAbsArg.h:238
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:502
std::map< std::string, std::string > _stringAttrib
Definition RooAbsArg.h:589
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:621
~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:648
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:431
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'.
bool isShapeServer(const RooAbsArg &arg) const
Check if this is serving shape to arg.
Definition RooAbsArg.h:161
bool isShapeDirty() const
Definition RooAbsArg.h:350
static void ioStreamerPass2Finalize()
Method called by workspace container to finalize schema evolution issues that cannot be handled in a ...
bool _fast
Definition RooAbsArg.h:645
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:642
void SetName(const char *name) override
Set the name of the TNamed.
RooSTLRefCountList< RooAbsArg > RefCountList_t
Definition RooAbsArg.h:78
std::set< std::string > _boolAttrib
Definition RooAbsArg.h:588
void unRegisterCache(RooAbsCache &cache)
Unregister a RooAbsCache. Called from the RooAbsCache destructor.
RefCountList_t _clientListValue
Definition RooAbsArg.h:567
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:624
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 expensive components.
Definition RooAbsArg.h:654
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:533
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:641
bool _prohibitServerRedirect
Set of owned component.
Definition RooAbsArg.h:650
virtual const char * cacheUniqueSuffix() const
Definition RooAbsArg.h:434
RefCountListLegacyIterator_t * makeLegacyIterator(const RefCountList_t &list) const
const RefCountList_t & servers() const
List of all servers of this object.
Definition RooAbsArg.h:145
std::size_t _dataToken
In which workspace do I live, if any.
Definition RooAbsArg.h:661
bool dependsOnValue(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=nullptr) const
Check whether this object depends on values from an element in the serverList.
Definition RooAbsArg.h:104
void addServer(RooAbsArg &server, bool valueProp=true, bool shapeProp=false, std::size_t refCount=1)
Register another RooAbsArg as a server to us, ie, declare that we depend on it.
void removeStringAttribute(const Text_t *key)
Delete a string attribute with a given key.
Int_t Compare(const TObject *other) const override
Utility function used by TCollection::Sort to compare contained TObjects We implement comparison by n...
Int_t defaultPrintContents(Option_t *opt) const override
Define default contents to print.
virtual bool isDerived() const
Does value or shape of this arg depend on any other arg?
Definition RooAbsArg.h:97
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:644
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:425
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:566
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:356
bool _localNoInhibitDirty
Cached isConstant status.
Definition RooAbsArg.h:657
virtual void printMetaArgs(std::ostream &) const
Definition RooAbsArg.h:249
virtual void applyWeightSquared(bool flag)
Disables or enables the usage of squared weights.
static bool _inhibitDirty
Definition RooAbsArg.h:625
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.
static TClass * Class()
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:565
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:88
RefCountList_t _serverList
Definition RooAbsArg.h:564
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:652
virtual bool isFundamental() const
Is this object a fundamental type that can be added to a dataset? Fundamental-type subclasses overrid...
Definition RooAbsArg.h:175
virtual bool isValid() const
WVE (08/21/01) Probably obsolete now.
std::set< std::string > _boolAttribTransient
Definition RooAbsArg.h:590
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::vector< RooAbsCache * > _cacheList
Definition RooAbsArg.h:571
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:526
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:157
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:79
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:419
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.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
RooAbsArg * find(const char *name) const
Find object with given name in list.
Abstract base class for a data collection.
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:57
virtual const RooArgSet * get() const
Definition RooAbsData.h:101
Abstract interface for proxy classes.
Definition RooAbsProxy.h:37
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
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
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Represents a constant real-valued object.
Definition RooConstVar.h:23
Singleton class that serves as repository for objects that are expensive to calculate.
static RooExpensiveObjectCache & instance()
Return reference to singleton instance.
void markAsCompiled(RooAbsArg &arg) const
void compileServers(RooAbsArg &arg, RooArgSet const &normSet)
Switches the message service to a different level while the instance is alive.
Definition RooHelpers.h:37
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
Registry for const char* names.
Definition RooNameReg.h:26
static RooNameReg & instance()
Return reference to singleton instance.
@ kRenamedArg
TNamed flag to indicate that some RooAbsArg has been renamed (flag set in new name)
Definition RooNameReg.h:46
static void incrementRenameCounter()
The renaming counter has to be incremented every time a RooAbsArg is renamed.
A 'mix-in' base class that define the standard RooFit plotting and printing methods.
virtual void printValue(std::ostream &os) const
Interface to print value of object.
Performs hybrid numerical/analytical integrals of RooAbsReal objects.
Variable that can be changed from the outside.
Definition RooRealVar.h:37
TClass * IsA() const override
Definition RooAbsArg.h:67
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...
TTree-backed data storage.
Uses std::vector to store data columns.
Buffer base class used for serializing objects.
Definition TBuffer.h:43
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:174
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
TString fName
Definition TNamed.h:32
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:150
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 * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:227
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:865
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:544
An array of references to TObjects.
Definition TRefArray.h:33
Basic string class.
Definition TString.h:138
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:631
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:640
A TTree represents a columnar dataset.
Definition TTree.h:89
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
Definition Config.h:35
RooAbsArg * cloneTreeWithSameParametersImpl(RooAbsArg const &arg, RooArgSet const *observables)
std::vector< RooAbsProxy * > cache
Definition RooAbsArg.h:618