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