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