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