Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
RooBinning.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\file RooBinning.cxx
19\class RooBinning
20\ingroup Roofitcore
21
22Implements a RooAbsBinning in terms
23of an array of boundary values, posing no constraints on the choice
24of binning, thus allowing variable bin sizes. Various methods allow
25the user to add single bin boundaries, mirrored pairs, or sets of
26uniformly spaced boundaries.
27**/
28
29#include <Riostream.h>
30#include <RooAbsPdf.h>
31#include <RooBinning.h>
32#include <RooDouble.h>
35#include <RooMsgService.h>
36#include <RooNumber.h>
37#include <RooRealVar.h>
38
39#include <TBuffer.h>
40#include <TList.h>
41
42#include <algorithm>
43#include <cmath>
44
45using std::endl;
46
47
48
49////////////////////////////////////////////////////////////////////////////////
50/// Constructor for an initially empty binning defining the range [xlo,xhi]
51
52RooBinning::RooBinning(double xlo, double xhi, const char* name) :
54{
55 setRange(xlo,xhi);
56}
57
58////////////////////////////////////////////////////////////////////////////////
59/// Constructor for a uniform binning in 'nbins' bins in the range [xlo,xhi]
60
61RooBinning::RooBinning(Int_t nbins, double xlo, double xhi, const char* name) :
63{
64 _boundaries.reserve(1 + nbins);
65 setRange(xlo, xhi);
66 addUniform(nbins, xlo, xhi);
67}
68
69////////////////////////////////////////////////////////////////////////////////
70/// Constructor for a binning in the range[xlo,xhi] with 'nbins' bin boundaries listed
71/// array 'boundaries'
72
73RooBinning::RooBinning(Int_t nbins, const double* boundaries, const char* name) :
75{
76 // Variable bin size constructor
77 _boundaries.reserve(1 + nbins);
78 setRange(boundaries[0], boundaries[nbins]);
79 while (nbins--) addBoundary(boundaries[nbins]);
80}
81
82////////////////////////////////////////////////////////////////////////////////
83/// Copy constructor
84
86 RooAbsBinning(name), _xlo(other._xlo), _xhi(other._xhi),
87 _ownBoundLo(other._ownBoundLo), _ownBoundHi(other._ownBoundHi),
88 _nbins(other._nbins), _boundaries(other._boundaries),
89 _blo(other._blo)
90{
91}
92
93////////////////////////////////////////////////////////////////////////////////
94/// Destructor
95
97{
98 delete[] _array;
99}
100
101////////////////////////////////////////////////////////////////////////////////
102/// Add bin boundary at given value
103
105{
106 auto it = std::lower_bound(_boundaries.begin(), _boundaries.end(), boundary);
107 if (_boundaries.end() != it && *it == boundary) {
108 // If boundary previously existed as range delimiter,
109 // convert to regular boundary now
110 if (boundary == _xlo) _ownBoundLo = false;
111 if (boundary == _xhi) _ownBoundHi = false;
112 return false;
113 }
114 // Add a new boundary
115 _boundaries.insert(it, boundary);
117 return true;
118}
119
120////////////////////////////////////////////////////////////////////////////////
121/// Add pair of boundaries: one at 'boundary' and one at 2*mirrorPoint-boundary
122
128
129////////////////////////////////////////////////////////////////////////////////
130/// Remove boundary at given value
131
133{
134 auto it = std::lower_bound(_boundaries.begin(), _boundaries.end(), boundary);
135 if (_boundaries.end() != it && *it == boundary) {
136 _boundaries.erase(it);
137 // if some moron deletes the boundaries corresponding to the current
138 // range, we need to make sure that we do not get into an undefined state,
139 // so _xlo and _xhi need to be set to some valid values
140 if (_boundaries.empty()) {
141 _xlo = _xhi = 0.;
142 } else {
143 if (boundary == _xlo) _xlo = _boundaries.front();
144 if (boundary == _xhi) _xhi = _boundaries.back();
145 }
147 return false;
148 }
149 // Return error status - no boundary found
150 return true;
151}
152
153////////////////////////////////////////////////////////////////////////////////
154/// Add array of nbins uniformly sized bins in range [xlo,xhi]
155
156void RooBinning::addUniform(Int_t nbins, double xlo, double xhi)
157{
158 _boundaries.reserve(_boundaries.size() + nbins + 1);
159 for (Int_t i = 0; i <= nbins; ++i) {
160 addBoundary((double(nbins - i) / double(nbins)) * xlo + (double(i) / double(nbins)) * xhi);
161 }
162}
163
164////////////////////////////////////////////////////////////////////////////////
165/// Return sequential bin number that contains value x where bin
166/// zero is the first bin with an upper boundary above the lower bound
167/// of the range
168
169void RooBinning::binNumbers(double const *x, int *bins, std::size_t n, int coef) const
170{
171 for (std::size_t i = 0; i < n; ++i) {
172 bins[i] += RooFit::Detail::MathFuncs::binNumber(x[i], coef, _boundaries.data(), _boundaries.size(), _nbins, _blo);
173 }
174}
175
176////////////////////////////////////////////////////////////////////////////////
177/// Return the value of the nearest boundary to x
178
179double RooBinning::nearestBoundary(double x) const
180{
181 double xl;
182 double xh;
183 if (binEdges(binNumber(x), xl, xh)) return 0;
184 return (std::abs(xl - x) < std::abs(xh - x)) ? xl : xh;
185}
186
187////////////////////////////////////////////////////////////////////////////////
188/// Return array of boundary values
189
190double* RooBinning::array() const
191{
192 delete[] _array;
193 _array = new double[numBoundaries()];
194 std::copy(_boundaries.begin()+_blo, _boundaries.begin()+_blo+_nbins+1, _array);
195 return _array;
196}
197
198////////////////////////////////////////////////////////////////////////////////
199/// Change the defined range associated with this binning.
200/// Bins that lie outside the new range [xlo,xhi] will not be
201/// removed, but will be 'inactive', i.e. the new 0 bin will
202/// be the first bin with an upper boundarie > xlo
203
204void RooBinning::setRange(double xlo, double xhi)
205{
206 if (xlo > xhi) {
207 coutE(InputArguments) << "RooBinning::setRange: ERROR low bound > high bound" << std::endl;
208 return;
209 }
210 // Remove previous boundaries
213 // Insert boundaries at range delimiter, if necessary
216 _xlo = xlo, _xhi = xhi;
217 // Count number of bins with new range
219}
220
221////////////////////////////////////////////////////////////////////////////////
222/// Update the internal bin counter
223
225{
226 if (_boundaries.size() <= 1) {
227 _nbins = -1;
228 return;
229 }
231 auto it = std::lower_bound(_boundaries.begin(), _boundaries.end(), _xhi);
232 if (_boundaries.begin() != it && (_boundaries.end() == it || _xhi < *it)) --it;
233 const Int_t bhi = it - _boundaries.begin();
234 _nbins = bhi - _blo;
235}
236
237////////////////////////////////////////////////////////////////////////////////
238/// Return upper and lower bound of bin 'bin'. If the return value
239/// is true an error occurred
240
241bool RooBinning::binEdges(Int_t bin, double& xlo, double& xhi) const
242{
243 if (0 > bin || bin >= _nbins) {
244 coutE(InputArguments) << "RooBinning::binEdges ERROR: bin number must be in range (0," << _nbins << ")" << std::endl;
245 return true;
246 }
247 xlo = _boundaries[bin + _blo], xhi = _boundaries[bin + _blo + 1];
248 return false;
249}
250
251////////////////////////////////////////////////////////////////////////////////
252/// Return the position of the center of bin 'bin'
253
255{
256 double xlo;
257 double xhi;
258 if (binEdges(bin, xlo, xhi)) return 0;
259 return 0.5 * (xlo + xhi);
260}
261
262////////////////////////////////////////////////////////////////////////////////
263/// Return the width of the requested bin
264
266{
267 double xlo;
268 double xhi;
269 if (binEdges(bin, xlo, xhi)) return 0;
270 return (xhi - xlo);
271}
272
273////////////////////////////////////////////////////////////////////////////////
274/// Return the lower bound of the requested bin
275
276double RooBinning::binLow(Int_t bin) const
277{
278 double xlo;
279 double xhi;
280 if (binEdges(bin, xlo, xhi)) return 0;
281 return xlo;
282}
283
284////////////////////////////////////////////////////////////////////////////////
285/// Return the upper bound of the requested bin
286
287double RooBinning::binHigh(Int_t bin) const
288{
289 double xlo;
290 double xhi;
291 if (binEdges(bin, xlo, xhi)) return 0;
292 return xhi;
293}
294
295////////////////////////////////////////////////////////////////////////////////
296/// Custom streamer that provides backward compatibility to read v1 data
297
299{
300 if (R__b.IsReading()) {
301
302 UInt_t R__s;
303 UInt_t R__c;
304 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
305 if (R__v) { }
306 switch (R__v) {
307 case 3:
308 // current version - fallthrough intended
309 case 2:
310 // older version with std::set<double> instead of
311 // std::vector<double>, apparently ROOT is clever enough to not care
312 // about set vs vector
313 R__b.ReadClassBuffer(RooBinning::Class(), this, R__v, R__s, R__c);
314 break;
315 case 1:
316 {
318 R__b >> _xlo;
319 R__b >> _xhi;
320 R__b >> _ownBoundLo;
321 R__b >> _ownBoundHi;
322 R__b >> _nbins;
323
324 _boundaries.clear();
325 // Convert TList to std::vector<double>
326 TList tmp;
327 tmp.Streamer(R__b);
328 _boundaries.reserve(tmp.GetSize());
329 for(auto * el : static_range_cast<RooDouble*>(tmp)) {
330 _boundaries.push_back(*el);
331 }
332 }
333 R__b.CheckByteCount(R__s, R__c, RooBinning::IsA());
334 break;
335 default:
336 throw std::string("Unknown class version!");
337 }
338 if (_boundaries.size() > 2) {
339 std::sort(_boundaries.begin(), _boundaries.end());
340 _boundaries.erase(std::unique(_boundaries.begin(), _boundaries.end()),
341 _boundaries.end());
342 }
343 } else {
344 R__b.WriteClassBuffer(RooBinning::Class(),this);
345 }
346}
347
349{
350 return ctx.buildCall("RooFit::Detail::MathFuncs::binNumber", var, coef, _boundaries, _boundaries.size(), _nbins, _blo);
351}
#define coutE(a)
short Version_t
Definition RtypesCore.h:65
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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
Abstract base class for RooRealVar binning definitions.
int binNumber(double x) const
Returns the bin number corresponding to the value x.
void Streamer(TBuffer &) override
Custom streamer implementing schema evolution between V1 and V2 persistent binnings.
Implements a RooAbsBinning in terms of an array of boundary values, posing no constraints on the choi...
Definition RooBinning.h:27
double binLow(Int_t bin) const override
Return the lower bound of the requested bin.
double * array() const override
Return array of boundary values.
void updateBinCount()
Update the internal bin counter.
static TClass * Class()
TClass * IsA() const override
Definition RooBinning.h:89
double _xhi
Upper bound.
Definition RooBinning.h:80
Int_t _blo
! bin number for _xlo
Definition RooBinning.h:87
std::vector< double > _boundaries
Boundaries.
Definition RooBinning.h:85
Int_t numBoundaries() const override
Return the number boundaries.
Definition RooBinning.h:38
~RooBinning() override
Destructor.
bool addBoundary(double boundary)
Add bin boundary at given value.
void binNumbers(double const *x, int *bins, std::size_t n, int coef) const override
Return sequential bin number that contains value x where bin zero is the first bin with an upper boun...
RooBinning(double xlo=-RooNumber::infinity(), double xhi=RooNumber::infinity(), const char *name=nullptr)
Constructor for an initially empty binning defining the range [xlo,xhi].
void addUniform(Int_t nBins, double xlo, double xhi)
Add array of nbins uniformly sized bins in range [xlo,xhi].
double binCenter(Int_t bin) const override
Return the position of the center of bin 'bin'.
std::string translateBinNumber(RooFit::Experimental::CodegenContext &ctx, RooAbsArg const &var, int coef) const override
double binHigh(Int_t bin) const override
Return the upper bound of the requested bin.
void Streamer(TBuffer &) override
Custom streamer that provides backward compatibility to read v1 data.
bool _ownBoundHi
Does the upper bound coincide with a bin boundary.
Definition RooBinning.h:82
double * _array
! Array of boundaries
Definition RooBinning.h:86
double binWidth(Int_t bin) const override
Return the width of the requested bin.
Int_t _nbins
Number of bins.
Definition RooBinning.h:83
void addBoundaryPair(double boundary, double mirrorPoint=0)
Add pair of boundaries: one at 'boundary' and one at 2*mirrorPoint-boundary.
bool _ownBoundLo
Does the lower bound coincide with a bin boundary.
Definition RooBinning.h:81
double _xlo
Lower bound.
Definition RooBinning.h:79
bool removeBoundary(double boundary)
Remove boundary at given value.
virtual double nearestBoundary(double x) const
Return the value of the nearest boundary to x.
bool binEdges(Int_t bin, double &xlo, double &xhi) const
Return upper and lower bound of bin 'bin'.
void setRange(double xlo, double xhi) override
Change the defined range associated with this binning.
A class to maintain the context for squashing of RooFit models into code.
std::string buildCall(std::string const &funcname, Args_t const &...args)
Build the code to call the function with name funcname, passing some arguments.
Buffer base class used for serializing objects.
Definition TBuffer.h:43
A doubly linked list.
Definition TList.h:38
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
unsigned int binNumber(double x, double coef, double const *boundaries, unsigned int nBoundaries, int nbins, int blo)
Definition MathFuncs.h:190
unsigned int rawBinNumber(double x, double const *boundaries, std::size_t nBoundaries)
Definition MathFuncs.h:178