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