Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooLinearVar.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 RooLinearVar
19/// RooLinearVar is the most general form of a derived real-valued object that can
20/// be used by RooRealIntegral to integrate over. The requirements for this are
21/// * Can be modified directly (i.e. invertible formula)
22/// * Jacobian term in integral is constant (but not necessarily 1)
23///
24/// This class implements the most general form that satisfies these requirements
25/// \f[
26/// RLV = \mathrm{slope} \cdot x + \mathrm{offset}
27/// \f]
28/// \f$ x \f$ is required to be a RooRealVar to meet the invertibility criterium,
29/// `slope` and `offset` are RooAbsReals, but cannot overlap with \f$ x \f$,
30/// *i.e.*, \f$ x \f$ may not be a server of `slope` and `offset`.
31///
32/// In the context of a dataset, `slope` may not contain any real-valued dependents
33/// (to satisfyt the constant Jacobian requirement). This check cannot be enforced at
34/// construction time, but can be performed at run time through the isJacobianOK(depList)
35/// member function.
36///
37///
38
39#include <cmath>
40
41#include "TClass.h"
42#include "RooLinearVar.h"
43#include "RooStreamParser.h"
44#include "RooArgSet.h"
45#include "RooRealVar.h"
46#include "RooNumber.h"
47#include "RooBinning.h"
48#include "RooMsgService.h"
49
50
52
53
54////////////////////////////////////////////////////////////////////////////////
55/// Constructor with RooAbsRealLValue variable and RooAbsReal slope and offset
56
57RooLinearVar::RooLinearVar(const char *name, const char *title, RooAbsRealLValue& variable,
58 const RooAbsReal& slope, const RooAbsReal& offs, const char *unit) :
59 RooAbsRealLValue(name, title, unit),
60 _binning(variable.getBinning(),slope.getVal(),offs.getVal()),
61 _var("var","variable",this,variable,true,true),
62 _slope("slope","slope",this,(RooAbsReal&)slope),
63 _offset("offset","offset",this,(RooAbsReal&)offs)
64{
65 // Slope and offset may not depend on variable
66 if (slope.dependsOnValue(variable) || offs.dependsOnValue(variable)) {
67 std::stringstream ss;
68 ss << "RooLinearVar::RooLinearVar(" << GetName()
69 << "): ERROR, slope(" << slope.GetName() << ") and offset("
70 << offs.GetName() << ") may not depend on variable("
71 << variable.GetName() << ")";
72 const std::string errMsg = ss.str();
73 coutE(InputArguments) << errMsg << std::endl;
74 throw std::invalid_argument(errMsg);
75 }
76
77 // Initial plot range and number of bins from dependent variable
78// setPlotRange(variable.getPlotMin()*_slope + _offset,
79// variable.getPlotMax()*_slope + _offset) ;
80// setPlotBins(variable.getPlotBins()) ;
81
82}
83
84
85
86////////////////////////////////////////////////////////////////////////////////
87/// Copy constructor
88
89RooLinearVar::RooLinearVar(const RooLinearVar& other, const char* name) :
91 _binning(other._binning),
92 _var("var",this,other._var),
93 _slope("slope",this,other._slope),
94 _offset("offset",this,other._offset)
95{
96}
97
98
99
100////////////////////////////////////////////////////////////////////////////////
101/// Destructor
102
104{
106}
107
108
109
110////////////////////////////////////////////////////////////////////////////////
111/// Calculate current value of this object
112
114{
115 return _offset + _var * _slope ;
116}
117
118
119
120////////////////////////////////////////////////////////////////////////////////
121/// Assign given value to linear transformation: sets input variable to (value-offset)/slope
122/// If slope is zerom an error message is printed and no assignment is made
123
125{
126 //cout << "RooLinearVar::setVal(" << GetName() << "): new value = " << value << endl ;
127
128 // Prevent DIV0 problems
129 if (_slope == 0.) {
130 coutE(Eval) << "RooLinearVar::setVal(" << GetName() << "): ERROR: slope is zero, cannot invert relation" << std::endl ;
131 return ;
132 }
133
134 // Invert formula 'value = offset + slope*var'
135 _var->setVal((value - _offset) / _slope) ;
136
137}
138
139
140
141////////////////////////////////////////////////////////////////////////////////
142/// Returns true if Jacobian term associated with current
143/// expression tree is indeed constant.
144
145bool RooLinearVar::isJacobianOK(const RooArgSet& depList) const
146{
147 if (!_var->isJacobianOK(depList)) {
148 return false ;
149 }
150
151 // Check if jacobian has no real-valued dependents
152 for(RooAbsArg* arg : depList) {
153 if (arg->IsA()->InheritsFrom(RooAbsReal::Class())) {
154 if (_slope->dependsOnValue(*arg)) {
155// cout << "RooLinearVar::isJacobianOK(" << GetName() << ") return false because slope depends on value of " << arg->GetName() << endl ;
156 return false ;
157 }
158 }
159 }
160 // cout << "RooLinearVar::isJacobianOK(" << GetName() << ") return true" << endl ;
161 return true ;
162}
163
164
165
166////////////////////////////////////////////////////////////////////////////////
167/// Return value of Jacobian associated with the transformation
168
170{
171 return _slope*_var->jacobian() ;
172}
173
174
175
176////////////////////////////////////////////////////////////////////////////////
177/// Read object contents from stream
178
179bool RooLinearVar::readFromStream(std::istream& /*is*/, bool /*compact*/, bool /*verbose*/)
180{
181 return true ;
182}
183
184
185
186////////////////////////////////////////////////////////////////////////////////
187/// Write object contents to stream
188
189void RooLinearVar::writeToStream(std::ostream& os, bool compact) const
190{
191 if (compact) {
192 os << getVal() ;
193 } else {
194 os << _slope->GetName() << " * " << _var->GetName() << " + " << _offset->GetName() ;
195 }
196}
197
198
199
200////////////////////////////////////////////////////////////////////////////////
201/// Retrieve binning of this linear transformation. A RooLinearVar does not have its own
202/// binnings but uses linearly transformed binnings of the input variable. If a given
203/// binning exists on the input variable, it will also exist on this linear transformation,
204/// and a binning adaptor object is created on the fly.
205
206 RooAbsBinning& RooLinearVar::getBinning(const char* name, bool verbose, bool createOnTheFly)
207{
208 // Normalization binning
209 if (name==nullptr) {
211 return _binning ;
212 }
213
214 // Alternative named range binnings, look for existing translator binning first
215 auto* altBinning = static_cast<RooLinTransBinning*>(_altBinning.FindObject(name));
216 if (altBinning) {
217 altBinning->updateInput(_var->getBinning(name,verbose),_slope,_offset) ;
218 return *altBinning ;
219 }
220
221 // If binning is not found return default binning, if creation is not requested
222 if (!_var->hasRange(name) && !createOnTheFly) {
223 return _binning ;
224 }
225
226 // Create translator binning on the fly
227 RooAbsBinning& sourceBinning = _var->getBinning(name,verbose) ;
228 auto* transBinning = new RooLinTransBinning(sourceBinning,_slope,_offset) ;
229 _altBinning.Add(transBinning) ;
230
231 return *transBinning ;
232}
233
234
235////////////////////////////////////////////////////////////////////////////////
236/// Const version of getBinning()
237
238const RooAbsBinning& RooLinearVar::getBinning(const char* name, bool verbose, bool createOnTheFly) const
239{
240 return const_cast<RooLinearVar*>(this)->getBinning(name,verbose,createOnTheFly) ;
241}
242
243////////////////////////////////////////////////////////////////////////////////
244/// Get a list of all binning names. An empty name implies the default binning.
245/// A 0 pointer should be passed to getBinning in this case.
246
247std::list<std::string> RooLinearVar::getBinningNames() const
248{
249 std::list<std::string> binningNames(1, "");
250
251 for (TObject const* binning : _altBinning) {
252 binningNames.push_back(binning->GetName());
253 }
254
255 return binningNames;
256}
257
258////////////////////////////////////////////////////////////////////////////////
259/// Returns true if binning with given name exists.If a given binning
260/// exists on the input variable, it will also exists on this linear
261/// transformation.
262
263bool RooLinearVar::hasBinning(const char* name) const
264{
265 return _var->hasBinning(name) ;
266}
ROOT::Math::KahanSum< double > _offset
! Offset as KahanSum to avoid loss of precision
#define coutE(a)
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
Definition TGX11.cxx:110
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
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
Abstract base class for RooRealVar binning definitions.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
virtual double jacobian() const
virtual const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false) const =0
Retrieve binning configuration with given name or default binning.
virtual bool isJacobianOK(const RooArgSet &depList) const
virtual void setVal(double value)=0
Set the current value of the object. Needs to be overridden by implementations.
virtual bool hasBinning(const char *name) const =0
Check if binning with given name has been defined.
bool hasRange(const char *name) const override
Check if variable has a binning with given name.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:103
static TClass * Class()
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
Special binning implementation for RooLinearVar that transforms the binning of the RooLinearVar input...
void updateInput(const RooAbsBinning &input, double slope=1.0, double offset=0.0)
Update the slope and offset parameters and the pointer to the input binning.
RooLinearVar is the most general form of a derived real-valued object that can be used by RooRealInte...
RooRealProxy _slope
Slope of transformation.
bool hasBinning(const char *name) const override
Returns true if binning with given name exists.If a given binning exists on the input variable,...
RooLinkedList _altBinning
!
std::list< std::string > getBinningNames() const override
Get a list of all binning names.
RooLinTransBinning _binning
double jacobian() const override
Return value of Jacobian associated with the transformation.
double evaluate() const override
Calculate current value of this object.
void writeToStream(std::ostream &os, bool compact) const override
Write object contents to stream.
bool isJacobianOK(const RooArgSet &depList) const override
Returns true if Jacobian term associated with current expression tree is indeed constant.
void setVal(double value) override
Assign given value to linear transformation: sets input variable to (value-offset)/slope If slope is ...
RooRealProxy _offset
Offset of transformation.
bool readFromStream(std::istream &is, bool compact, bool verbose=false) override
Read object contents from stream.
RooTemplateProxy< RooAbsRealLValue > _var
Input observable.
const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false) const override
Const version of getBinning()
~RooLinearVar() override
Destructor.
void Delete(Option_t *o=nullptr) override
Remove all elements in collection and delete all elements NB: Collection does not own elements,...
virtual void Add(TObject *arg)
TObject * FindObject(const char *name) const override
Return pointer to object with given name.
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
Mother of all ROOT objects.
Definition TObject.h:41