Logo ROOT  
Reference Guide
RooTemplateProxy.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * File: $Id: RooRealProxy.h,v 1.23 2007/07/12 20:30:28 wouter Exp $
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 #ifndef ROO_TEMPLATE_PROXY
17 #define ROO_TEMPLATE_PROXY
18 
19 #include "RooAbsReal.h"
20 #include "RooArgProxy.h"
21 #include "RooAbsRealLValue.h"
22 #include "RooAbsCategory.h"
23 #include "RooMsgService.h"
24 
25 /**
26 \class RooTemplateProxy
27 \ingroup Roofitcore
28 
29 ## Introduction
30 A RooTemplateProxy is used to hold references to other RooFit objects in an expression tree.
31 A `RooGaussian(..., x, mean, sigma)` can e.g. store references to `x, mean, sigma` as
32 ```
33 RooTemplateProxy<RooAbsReal> _x;
34 RooTemplateProxy<RooAbsReal> _mean;
35 RooTemplateProxy<RooAbsReal> _sigma;
36 ```
37 Now, the values of these three can be accessed, and the template argument ensures that only objects that evaluate
38 to real numbers (RooAbsReal) can be stored in such a proxy. These can e.g. be variables, PDFs and functions.
39 To store an object that's a `RooCategory`, one would, for example, use
40 ```
41 RooTemplateProxy<RooCategory> _category;
42 ```
43 
44 Since %ROOT 6.22, the proxy can be used like a pointer to an instance of the template argument.
45 For this, it provides `operator*` and `operator->`, e.g.
46 ```
47 double oldValue = _x->getVal(normalisationSet);
48 *_x = 17.;
49 ```
50 
51 RooTemplateProxy's base class RooArgProxy registers the proxied objects as "servers" of the object
52 that holds the proxy. When the value of the proxied object is changed, the owner is
53 notified, and can recalculate its own value. Renaming or exchanging objects that
54 serve values to the owner of the proxy is handled automatically.
55 
56 ## Modernisation of proxies in %ROOT 6.22
57 In ROOT 6.22, the classes RooRealProxy and RooCategoryProxy were replaced by RooTemplateProxy<class T>.
58 
59 Two typedefs have been defined for backward compatibility:
60 - `RooRealProxy = RooTemplateProxy<RooAbsReal>`. Any generic object that converts to a real value.
61 - `RooCategoryProxy = RooTemplateProxy<RooAbsCategory>`. Any category object.
62 
63 To modernise a class, one can change the template argument of the proxy to the most appropriate type,
64 and increment the class version of the owner.
65 
66 <table>
67 <tr><th> %RooFit before %ROOT 6.22 <th> %RooFit starting with %ROOT 6.22
68 <tr><td>
69 ~~~{.cpp}
70 // In .h: Declare member
71 RooRealProxy pdfProxy;
72 
73 ClassDef(MyPdf, 1)
74 };
75 
76 // In .cxx: Initialise proxy in constructor
77 // The proxy will accept any RooAbsArg, so the type of
78 // "thePdf" has to be checked manually.
79 MyPdf::MyPdf(name, title, ...) :
80  pdfProxy("pdfProxy", "Proxy holding a PDF", this, thePdf) {
81  [ Extra checking here ... ]
82 }
83 
84 
85 // In .cxx: Accessing the proxy
86 RooAbsArg* absArg = pdfProxy.absArg();
87 RooAbsPdf* pdf = dynamic_cast<RooAbsPdf*>(absArg);
88 assert(pdf); // Manual type checking ...
89 pdf->fitTo(...);
90 ~~~
91 <td>
92 ~~~{.cpp}
93 // In .h: Declare member
94 RooTemplateProxy<RooAbsPdf> pdfProxy;
95 
96 ClassDef(MyPdf, 2)
97 };
98 
99 // In .cxx: Initialise proxy in constructor
100 // The program will not compile if "thePdf" is not a
101 // type deriving from RooAbsPdf
102 MyPdf::MyPdf(name, title, ...) :
103  pdfProxy("pdfProxy", "Proxy holding a PDF", this, thePdf) {
104 
105 }
106 
107 
108 // In .cxx: Accessing the proxy
109 
110 
111 
112 pdfProxy->fitTo(...);
113 ~~~
114 </table>
115 
116 
117 ### How to modernise old code
118 
119 1. Choose the proper template argument for the proxy.
120  - If a PDF is stored: `RooTemplateProxy<RooAbsPdf>`.
121  - If a real-valued object is stored: `RooTemplateProxy<RooAbsReal>`.
122  - If a category is stored: `RooTemplateProxy<RooCategory>`.
123  - If a variable is stored (i.e. one want to be able to assign values to it): `RooTemplateProxy<RooRealVar>`
124  Other template arguments are possible, as long as they derive from RooAbsArg.
125 2. Increment the class version of the owning class.
126 3. Make sure that the right type is passed in the constructor of the proxy.
127 4. Always use `proxy->` and `*proxy` to work with the stored object. No need to cast.
128 5. **Only if necessary** If errors about missing symbols connected to RooTemplateProxy appear at link time,
129  a specific template instantiation for RooTemplateProxy is not yet in ROOT's dictionaries.
130  These two lines should be added to the LinkDef.h of the project:
131  ~~~{.cpp}
132  #pragma link C++ class RooTemplateProxy<RooMultiCategory>+;
133  #pragma read sourceClass="RooCategoryProxy" targetClass="RooTemplateProxy<RooMultiCategory>"
134  ~~~
135  Replace `RooMultiCategory` by the proper type. If the proxy was holding a real-valued object, use `sourceClass="RooRealProxy"`.
136 
137  The first line adds the proxy class to the dictionary, the second line enables reading a legacy
138  `RooCategoryProxy` from a file, and converting it to the new type-safe proxy. If no old proxies
139  have to be read from files, this line can be omitted.
140 
141  If the template instantiation that triggered the missing symbols seems to be a very common instantiation,
142  request for it to be added to RooFit by creating a pull request for ROOT. If it is rather uncommon,
143  it is sufficient to add it to the LinkDef.h of the local project only.
144 
145 **/
146 
147 template<class T>
149 public:
150 
152 
153  ////////////////////////////////////////////////////////////////////////////////
154  /// Constructor with owner.
155  /// \param[in] theName Name of this proxy (for printing).
156  /// \param[in] desc Description what this proxy should act as.
157  /// \param[in] owner The object that owns the proxy. This is important for tracking
158  /// of client-server dependencies.
159  /// \param[in] valueServer Notify the owner if value changes.
160  /// \param[in] shapeServer Notify the owner if shape (e.g. binning) changes.
161  /// \param[in] proxyOwnsArg Proxy will delete the payload if owning.
162  RooTemplateProxy(const char* theName, const char* desc, RooAbsArg* owner,
163  Bool_t valueServer=true, Bool_t shapeServer=false, Bool_t proxyOwnsArg=false)
164  : RooArgProxy(theName, desc, owner, valueServer, shapeServer, proxyOwnsArg) { }
165 
166  ////////////////////////////////////////////////////////////////////////////////
167  /// Constructor with owner and proxied object.
168  /// \param[in] theName Name of this proxy (for printing).
169  /// \param[in] desc Description what this proxy should act as.
170  /// \param[in] owner The object that owns the proxy. This is important for tracking
171  /// of client-server dependencies.
172  /// \param[in] ref Reference to the object that the proxy should hold.
173  /// \param[in] valueServer Notify the owner if value changes.
174  /// \param[in] shapeServer Notify the owner if shape (e.g. binning) changes.
175  /// \param[in] proxyOwnsArg Proxy will delete the payload if owning.
176  RooTemplateProxy(const char* theName, const char* desc, RooAbsArg* owner, T& ref,
177  Bool_t valueServer=true, Bool_t shapeServer=false, Bool_t proxyOwnsArg=false) :
178  RooArgProxy(theName, desc, owner, ref, valueServer, shapeServer, proxyOwnsArg) { }
179 
180 
181  ////////////////////////////////////////////////////////////////////////////////
182  /// Copy from an existing proxy.
183  /// It will accept any RooTemplateProxy instance, and attempt a dynamic_cast on its payload.
184  /// \param[in] theName Name of this proxy.
185  /// \param[in] owner Pointer to the owner this proxy should be registered to.
186  /// \param[in] other Instance of a differen proxy whose payload should be copied.
187  /// \param[in] allowWrongTypes Instead of throwing a std::invalid_argument, only issue an
188  /// error message when payload with wrong type is found. This is unsafe, but may be necessary
189  /// when reading back legacy types. Defaults to false.
190  /// \throw std::invalid_argument if the types of the payloads are incompatible.
191  template<typename U>
192  RooTemplateProxy(const char* theName, RooAbsArg* owner, const RooTemplateProxy<U>& other, bool allowWrongTypes = false) :
193  RooArgProxy(theName, owner, other) {
194  if (_arg && !dynamic_cast<const T*>(_arg)) {
195  if (allowWrongTypes) {
196  coutE(InputArguments) << "Error trying to copy an argument from a proxy with an incompatible payload." << std::endl;
197  } else {
198  throw std::invalid_argument("Tried to construct a RooTemplateProxy with incompatible payload.");
199  }
200  }
201  }
202 
203  virtual TObject* Clone(const char* newName=0) const { return new RooTemplateProxy<T>(newName,_owner,*this); }
204 
205 
206  /// Return reference to the proxied object.
207  T& operator*() const {
208  return static_cast<T&>(*_arg);
209  }
210 
211  /// Member access operator to proxied object.
212  T* operator->() const {
213  return static_cast<T*>(_arg);
214  }
215 
216 
217  /// Convert the proxy into a number.
218  /// \return A category proxy will return the index state, real proxies the result of RooAbsReal::getVal(normSet).
219  operator typename T::value_type() const {
220  return retrieveValue(arg());
221  }
222 
223 
224  ////////////////////////////////////////////////////////////////////////////////
225  /// Change object held in proxy into newRef
226  bool setArg(T& newRef) {
227  if (_arg) {
228  if (std::string(arg().GetName()) != newRef.GetName()) {
229  newRef.setAttribute(Form("ORIGNAME:%s", arg().GetName())) ;
230  }
231  return changePointer(RooArgSet(newRef), true);
232  } else {
233  return changePointer(RooArgSet(newRef), false, true);
234  }
235  }
236 
237 
238  /// \name Legacy interface
239  /// In ROOT versions before 6.22, RooFit didn't have this typed proxy. Therefore, a number of functions
240  /// for forwarding calls to the proxied objects were necessary. The functions in this group can all be
241  /// replaced by directly accessing the proxied objects using e.g. the member access operator like
242  /// `proxy->function()` or by dereferencing like `*proxy = value`.
243  /// For this to work, choose the template argument appropriately. That is, if the
244  /// proxy stores a PDF, use `RooTemplateProxy<RooAbsPdf>`, *etc.*.
245  /// @{
246 
247  /// Get the label of the current category state. This function only makes sense for category proxies.
248  const char* label() const {
249  return arg().getCurrentLabel();
250  }
251 
252  /// Check if the stored object has a range with the given name.
253  bool hasRange(const char* rangeName) const {
254  return arg().hasRange(rangeName);
255  }
256 
257 
258  /// Retrieve a batch of real or category data.
259  /// When retrieving real-valued data from e.g. a PDF, the normalisation set saved by this proxy will be passed
260  /// on the the proxied object.
261  /// \param[in] begin Begin of the range to be retrieved.
262  /// \param[in] batchSize Size of the range to be retrieved. Batch may be smaller if no more data available.
263  /// \return RooSpan<const double> for real-valued proxies, RooSpan<const int> for category proxies.
264  RooSpan<const typename T::value_type> getValBatch(std::size_t begin, std::size_t batchSize) const {
265  return retrieveBatchVal(begin, batchSize, arg());
266  }
267 
268 
269  /// Return reference to object held in proxy.
270  const T& arg() const { return static_cast<const T&>(*_arg); }
271 
272  /// Assign a new value to the object pointed to by the proxy.
273  /// This requires the payload to be assignable (RooAbsRealLValue or derived, RooAbsCategoryLValue).
274  RooTemplateProxy<T>& operator=(typename T::value_type value) {
275  lvptr(static_cast<T*>(nullptr))->operator=(value);
276  return *this;
277  }
278  /// Set a category state using its state name. This function can only work for category-type proxies.
279  RooTemplateProxy<T>& operator=(const std::string& newState) {
280  static_assert(std::is_base_of<RooAbsCategory, T>::value, "Strings can only be assigned to category proxies.");
281  lvptr(static_cast<RooAbsCategoryLValue*>(nullptr))->operator=(newState.c_str());
282  return *this;
283  }
284 
285  /// Query lower limit of range. This requires the payload to be RooAbsRealLValue or derived.
286  double min(const char* rname=0) const { return lvptr(static_cast<const T*>(nullptr))->getMin(rname) ; }
287  /// Query upper limit of range. This requires the payload to be RooAbsRealLValue or derived.
288  double max(const char* rname=0) const { return lvptr(static_cast<const T*>(nullptr))->getMax(rname) ; }
289  /// Check if the range has a lower bound. This requires the payload to be RooAbsRealLValue or derived.
290  bool hasMin(const char* rname=0) const { return lvptr(static_cast<const T*>(nullptr))->hasMin(rname) ; }
291  /// Check if the range has a upper bound. This requires the payload to be RooAbsRealLValue or derived.
292  bool hasMax(const char* rname=0) const { return lvptr(static_cast<const T*>(nullptr))->hasMax(rname) ; }
293 
294  /// @}
295 
296 
297 private:
298  /// Are we a real-valued proxy or a category proxy?
299  using LValue_t = typename std::conditional<std::is_base_of<RooAbsReal, T>::value,
301 
302  ////////////////////////////////////////////////////////////////////////////////
303  /// Return l-value pointer to contents. If the contents derive from RooAbsLValue or RooAbsCategoryLValue,
304  /// the conversion is safe, and the function directly returns the pointer using a static_cast.
305  /// If the template parameter of this proxy is not an LValue type, then
306  /// - in a debug build, a dynamic_cast with an assertion is used.
307  /// - in a release build, a static_cast is forced, irrespective of what the type of the object actually is. This
308  /// is dangerous, but equivalent to the behaviour before refactoring the RooFit proxies.
309  /// \deprecated This function is unneccessary if the template parameter is RooAbsRealLValue (+ derived types) or
310  /// RooAbsCategoryLValue (+derived types), as arg() will always return the correct type.
311  const LValue_t* lvptr(const LValue_t*) const {
312  return static_cast<const LValue_t*>(_arg);
313  }
314  /// \copydoc lvptr(const LValue_t*) const
316  return static_cast<LValue_t*>(_arg);
317  }
318  /// \copydoc lvptr(const LValue_t*) const
319  const LValue_t* lvptr(const RooAbsArg*) const
320  R__SUGGEST_ALTERNATIVE("The template argument of RooTemplateProxy needs to derive from RooAbsRealLValue or RooAbsCategoryLValue to safely call this function.") {
321 #ifdef NDEBUG
322  return static_cast<const LValue_t*>(_arg);
323 #else
324  auto theArg = dynamic_cast<const LValue_t*>(_arg);
325  assert(theArg);
326  return theArg;
327 #endif
328  }
329  /// \copydoc lvptr(const LValue_t*) const
331  R__SUGGEST_ALTERNATIVE("The template argument of RooTemplateProxy needs to derive from RooAbsRealLValue or RooAbsCategoryLValue to safely call this function.") {
332 #ifdef NDEBUG
333  return static_cast<LValue_t*>(_arg);
334 #else
335  auto theArg = dynamic_cast<LValue_t*>(_arg);
336  assert(theArg);
337  return theArg;
338 #endif
339  }
340 
341 
342  /// Retrieve index state from a category.
343  typename T::value_type retrieveValue(const RooAbsCategory& cat) const {
344  return cat.getCurrentIndex();
345  }
346 
347  /// Retrieve value from a real-valued object.
348  typename T::value_type retrieveValue(const RooAbsReal& real) const {
349  return real.getVal(_nset);
350  }
351 
352  /// Retrieve a batch of index states from a category.
353  RooSpan<const typename T::value_type> retrieveBatchVal(std::size_t begin, std::size_t batchSize, const RooAbsCategory& cat) const {
354  return cat.getValBatch(begin, batchSize);
355  }
356 
357  /// Retrieve a batch of values from a real-valued object. The current normalisation set associated to the proxy will be passed on.
358  RooSpan<const typename T::value_type> retrieveBatchVal(std::size_t begin, std::size_t batchSize, const RooAbsReal& real) const {
359  return real.getValBatch(begin, batchSize, _nset);
360  }
361 
362  ClassDef(RooTemplateProxy,1) // Proxy for a RooAbsReal object
363 };
364 
365 #endif
RooTemplateProxy< T > & operator=(const std::string &newState)
Set a category state using its state name. This function can only work for category-type proxies...
virtual Bool_t changePointer(const RooAbsCollection &newServerSet, Bool_t nameChange=kFALSE, Bool_t factoryInitMode=kFALSE)
Change proxied object to object of same name in given list.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
double max(const char *rname=0) const
Query upper limit of range. This requires the payload to be RooAbsRealLValue or derived.
#define coutE(a)
Definition: RooMsgService.h:33
A simple container to hold a batch of data values.
Definition: RooSpan.h:32
virtual TObject * Clone(const char *newName=0) const
Make a clone of an object using the Streamer facility.
IntroductionA RooTemplateProxy is used to hold references to other RooFit objects in an expression t...
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
double T(double x)
Definition: ChebyshevPol.h:34
RooSpan< const typename T::value_type > retrieveBatchVal(std::size_t begin, std::size_t batchSize, const RooAbsReal &real) const
Retrieve a batch of values from a real-valued object. The current normalisation set associated to the...
RooAbsArg * _arg
Definition: RooArgProxy.h:52
RooTemplateProxy< T > & operator=(typename T::value_type value)
Assign a new value to the object pointed to by the proxy.
const LValue_t * lvptr(const LValue_t *) const
Return l-value pointer to contents.
double min(const char *rname=0) const
Query lower limit of range. This requires the payload to be RooAbsRealLValue or derived.
LValue_t * lvptr(RooAbsArg *)
Return l-value pointer to contents.
virtual value_type getCurrentIndex() const
Return index number of current state.
#define ClassDef(name, id)
Definition: Rtypes.h:322
RooSpan< const typename T::value_type > getValBatch(std::size_t begin, std::size_t batchSize) const
Retrieve a batch of real or category data.
RooTemplateProxy(const char *theName, RooAbsArg *owner, const RooTemplateProxy< U > &other, bool allowWrongTypes=false)
Copy from an existing proxy.
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
#define R__SUGGEST_ALTERNATIVE(ALTERNATIVE)
Definition: RConfig.hxx:530
bool setArg(T &newRef)
Change object held in proxy into newRef.
RooArgSet * _nset
Definition: RooAbsProxy.h:54
virtual RooSpan< const double > getValBatch(std::size_t begin, std::size_t maxSize, const RooArgSet *normSet=nullptr) const
Return value of object for all data events in the batch.
Definition: RooAbsReal.cxx:294
const T & arg() const
Return reference to object held in proxy.
T & operator*() const
Return reference to the proxied object.
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition: RooAbsReal.h:90
char * Form(const char *fmt,...)
RooTemplateProxy(const char *theName, const char *desc, RooAbsArg *owner, T &ref, Bool_t valueServer=true, Bool_t shapeServer=false, Bool_t proxyOwnsArg=false)
Constructor with owner and proxied object.
LValue_t * lvptr(LValue_t *)
Return l-value pointer to contents.
RooSpan< const typename T::value_type > retrieveBatchVal(std::size_t begin, std::size_t batchSize, const RooAbsCategory &cat) const
Retrieve a batch of index states from a category.
const LValue_t * lvptr(const RooAbsArg *) const
Return l-value pointer to contents.
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:60
typename std::conditional< std::is_base_of< RooAbsReal, T >::value, RooAbsRealLValue, RooAbsCategoryLValue >::type LValue_t
Are we a real-valued proxy or a category proxy?
int type
Definition: TGX11.cxx:120
Mother of all ROOT objects.
Definition: TObject.h:37
RooArgProxy is the abstract interface for RooAbsArg proxy classes.
Definition: RooArgProxy.h:24
T::value_type retrieveValue(const RooAbsReal &real) const
Retrieve value from a real-valued object.
const char * label() const
Get the label of the current category state. This function only makes sense for category proxies...
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
T::value_type retrieveValue(const RooAbsCategory &cat) const
Retrieve index state from a category.
RooAbsCategory is the base class for objects that represent a discrete value with a finite number of ...
RooTemplateProxy(const char *theName, const char *desc, RooAbsArg *owner, Bool_t valueServer=true, Bool_t shapeServer=false, Bool_t proxyOwnsArg=false)
Constructor with owner.
virtual RooSpan< const value_type > getValBatch(std::size_t, std::size_t) const
Retrieve a batch of category values for events in the range [begin, begin+batchSize).
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:73
bool hasMax(const char *rname=0) const
Check if the range has a upper bound. This requires the payload to be RooAbsRealLValue or derived...
RooAbsArg * _owner
Definition: RooArgProxy.h:51
bool hasMin(const char *rname=0) const
Check if the range has a lower bound. This requires the payload to be RooAbsRealLValue or derived...
T * operator->() const
Member access operator to proxied object.
bool hasRange(const char *rangeName) const
Check if the stored object has a range with the given name.