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