Logo ROOT  
Reference Guide
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
22Class RooBinning is an implements 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 "RooFit.h"
30
31#include "Riostream.h"
32#include "RooBinning.h"
33#include "RooDouble.h"
34#include "RooAbsPdf.h"
35#include "RooRealVar.h"
36#include "RooNumber.h"
37#include "RooMsgService.h"
38#include "TBuffer.h"
39#include "TList.h"
40
41#include <algorithm>
42#include <cmath>
43
44using namespace std;
45
47;
48
49
50////////////////////////////////////////////////////////////////////////////////
51/// Constructor for an initially empty binning defining the range [xlo,xhi]
52
55 _xlo(0), _xhi(0), _ownBoundLo(kTRUE), _ownBoundHi(kTRUE),
56 _array(0), _blo(0)
57{
58 setRange(xlo,xhi);
59}
60
61////////////////////////////////////////////////////////////////////////////////
62/// Constructor for a uniform binning in 'nbins' bins in the range [xlo,xhi]
63
64RooBinning::RooBinning(Int_t nbins, Double_t xlo, Double_t xhi, const char* name) :
66 _xlo(0), _xhi(0), _ownBoundLo(kTRUE), _ownBoundHi(kTRUE),
67 _array(0), _blo(0)
68{
69 _boundaries.reserve(1 + nbins);
70 setRange(xlo, xhi);
71 addUniform(nbins, xlo, xhi);
72}
73
74////////////////////////////////////////////////////////////////////////////////
75/// Constructor for a binning in the range[xlo,xhi] with 'nbins' bin boundaries listed
76/// array 'boundaries'
77
78RooBinning::RooBinning(Int_t nbins, const Double_t* boundaries, const char* name) :
80 _xlo(0), _xhi(0), _ownBoundLo(kTRUE), _ownBoundHi(kTRUE),
81 _array(0), _blo(0)
82{
83 // Variable bin size constructor
84 _boundaries.reserve(1 + nbins);
85 setRange(boundaries[0], boundaries[nbins]);
86 while (nbins--) addBoundary(boundaries[nbins]);
87}
88
89////////////////////////////////////////////////////////////////////////////////
90/// Copy constructor
91
92RooBinning::RooBinning(const RooBinning& other, const char* name) :
93 RooAbsBinning(name), _xlo(other._xlo), _xhi(other._xhi),
94 _ownBoundLo(other._ownBoundLo), _ownBoundHi(other._ownBoundHi),
95 _nbins(other._nbins), _boundaries(other._boundaries), _array(0),
96 _blo(other._blo)
97{
98}
99
100////////////////////////////////////////////////////////////////////////////////
101/// Destructor
102
104{
105 delete[] _array;
106}
107
108////////////////////////////////////////////////////////////////////////////////
109/// Add bin boundary at given value
110
112{
113 std::vector<Double_t>::iterator it =
114 std::lower_bound(_boundaries.begin(), _boundaries.end(), boundary);
115 if (_boundaries.end() != it && *it == boundary) {
116 // If boundary previously existed as range delimiter,
117 // convert to regular boundary now
118 if (boundary == _xlo) _ownBoundLo = kFALSE;
119 if (boundary == _xhi) _ownBoundHi = kFALSE;
120 return kFALSE;
121 }
122 // Add a new boundary
123 _boundaries.insert(it, boundary);
125 return kTRUE;
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// Add pair of boundaries: one at 'boundary' and one at 2*mirrorPoint-boundary
130
132{
133 addBoundary(boundary);
134 addBoundary(2. * mirrorPoint - boundary);
135}
136
137////////////////////////////////////////////////////////////////////////////////
138/// Remove boundary at given value
139
141{
142 std::vector<Double_t>::iterator it = std::lower_bound(_boundaries.begin(),
143 _boundaries.end(), boundary);
144 if (_boundaries.end() != it && *it == boundary) {
145 _boundaries.erase(it);
146 // if some moron deletes the boundaries corresponding to the current
147 // range, we need to make sure that we do not get into an undefined state,
148 // so _xlo and _xhi need to be set to some valid values
149 if (_boundaries.empty()) {
150 _xlo = _xhi = 0.;
151 } else {
152 if (boundary == _xlo) _xlo = _boundaries.front();
153 if (boundary == _xhi) _xhi = _boundaries.back();
154 }
156 return kFALSE;
157 }
158 // Return error status - no boundary found
159 return kTRUE;
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Check if boundary exists at given value
164
166{
167 return std::binary_search(_boundaries.begin(), _boundaries.end(), boundary);
168}
169
170////////////////////////////////////////////////////////////////////////////////
171/// Add array of nbins uniformly sized bins in range [xlo,xhi]
172
174{
175 _boundaries.reserve(_boundaries.size() + nbins + 1);
176 for (Int_t i = 0; i <= nbins; ++i)
177 addBoundary((double(nbins - i) / double(nbins)) * xlo +
178 (double(i) / double(nbins)) * xhi);
179}
180
181////////////////////////////////////////////////////////////////////////////////
182/// Return sequential bin number that contains value x where bin
183/// zero is the first bin with an upper boundary above the lower bound
184/// of the range
185
187{
188 return std::max(0, std::min(_nbins, rawBinNumber(x) - _blo));
189}
190
191////////////////////////////////////////////////////////////////////////////////
192/// Return sequential bin number that contains value x where bin
193/// zero is the first bin that is defined, regardless if that bin
194/// is outside the current defined range
195
197{
198 std::vector<Double_t>::const_iterator it = std::lower_bound(
199 _boundaries.begin(), _boundaries.end(), x);
200 // always return valid bin number
201 while (_boundaries.begin() != it &&
202 (_boundaries.end() == it || _boundaries.end() == it + 1 || x < *it)) --it;
203 return it - _boundaries.begin();
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// Return the value of the nearest boundary to x
208
210{
211 Double_t xl, xh;
212 binEdges(binNumber(x), xl, xh);
213 return (std::abs(xl - x) < std::abs(xh - x)) ? xl : xh;
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Return array of boundary values
218
220{
221 delete[] _array;
223 std::copy(_boundaries.begin()+_blo, _boundaries.begin()+_blo+_nbins+1, _array);
224 return _array;
225}
226
227////////////////////////////////////////////////////////////////////////////////
228/// Change the defined range associated with this binning.
229/// Bins that lie outside the new range [xlo,xhi] will not be
230/// removed, but will be 'inactive', i.e. the new 0 bin will
231/// be the first bin with an upper boundarie > xlo
232
234{
235 if (xlo > xhi) {
236 coutE(InputArguments) << "RooBinning::setRange: ERROR low bound > high bound" << endl;
237 return;
238 }
239 // Remove previous boundaries
242 // Insert boundaries at range delimiter, if necessary
245 _xlo = xlo, _xhi = xhi;
246 // Count number of bins with new range
248}
249
250////////////////////////////////////////////////////////////////////////////////
251/// Update the internal bin counter
252
254{
255 if (_boundaries.size() <= 1) {
256 _nbins = -1;
257 return;
258 }
260 std::vector<Double_t>::const_iterator it = std::lower_bound(
261 _boundaries.begin(), _boundaries.end(), _xhi);
262 if (_boundaries.begin() != it && (_boundaries.end() == it || _xhi < *it)) --it;
263 const Int_t bhi = it - _boundaries.begin();
264 _nbins = bhi - _blo;
265}
266
267////////////////////////////////////////////////////////////////////////////////
268/// Return upper and lower bound of bin 'bin'. If the return value
269/// is true an error occurred
270
272{
273 if (0 > bin || bin >= _nbins) {
274 coutE(InputArguments) << "RooBinning::binEdges ERROR: bin number must be in range (0," << _nbins << ")" << endl;
275 return kTRUE;
276 }
277 xlo = _boundaries[bin + _blo], xhi = _boundaries[bin + _blo + 1];
278 return kFALSE;
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// Return the position of the center of bin 'bin'
283
285{
286 Double_t xlo, xhi;
287 if (binEdges(bin, xlo, xhi)) return 0;
288 return 0.5 * (xlo + xhi);
289}
290
291////////////////////////////////////////////////////////////////////////////////
292/// Return the width of the requested bin
293
295{
296 Double_t xlo, xhi;
297 if (binEdges(bin, xlo, xhi)) return 0;
298 return (xhi - xlo);
299}
300
301////////////////////////////////////////////////////////////////////////////////
302/// Return the lower bound of the requested bin
303
305{
306 Double_t xlo, xhi;
307 if (binEdges(bin, xlo, xhi)) return 0;
308 return xlo;
309}
310
311////////////////////////////////////////////////////////////////////////////////
312/// Return the upper bound of the requested bin
313
315{
316 Double_t xlo, xhi;
317 if (binEdges(bin, xlo, xhi)) return 0;
318 return xhi;
319}
320
321////////////////////////////////////////////////////////////////////////////////
322/// Custom streamer that provides backward compatibility to read v1 data
323
324void RooBinning::Streamer(TBuffer &R__b)
325{
326 if (R__b.IsReading()) {
327
328 UInt_t R__s, R__c;
329 Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
330 switch (R__v) {
331 case 3:
332 // current version - fallthrough intended
333 case 2:
334 // older version with std::set<Double_t> instead of
335 // std::vector<Double_t>, apparently ROOT is clever enough to not care
336 // about set vs vector
337 R__b.ReadClassBuffer(RooBinning::Class(), this, R__v, R__s, R__c);
338 break;
339 case 1:
340 {
341 RooAbsBinning::Streamer(R__b);
342 R__b >> _xlo;
343 R__b >> _xhi;
344 R__b >> _ownBoundLo;
345 R__b >> _ownBoundHi;
346 R__b >> _nbins;
347
348 _boundaries.clear();
349 // Convert TList to std::vector<Double_t>
350 TList tmp;
351 tmp.Streamer(R__b);
352 _boundaries.reserve(tmp.GetSize());
353 TIterator* it = tmp.MakeIterator();
354 for (RooDouble* el = (RooDouble*) it->Next(); el;
355 el = (RooDouble*) it->Next()) _boundaries.push_back(*el);
356 delete it;
357 }
358 R__b.CheckByteCount(R__s, R__c, RooBinning::IsA());
359 break;
360 default:
361 throw std::string("Unknown class version!");
362 }
363 if (_boundaries.size() > 2) {
364 std::sort(_boundaries.begin(), _boundaries.end());
365 _boundaries.erase(std::unique(_boundaries.begin(), _boundaries.end()),
366 _boundaries.end());
367 }
368 } else {
370 }
371}
void Class()
Definition: Class.C:29
#define coutE(a)
Definition: RooMsgService.h:34
int Int_t
Definition: RtypesCore.h:41
short Version_t
Definition: RtypesCore.h:61
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
char name[80]
Definition: TGX11.cxx:109
RooAbsBinning is the abstract base class for RooRealVar binning definitions This class defines the in...
Definition: RooAbsBinning.h:26
Class RooBinning is an implements RooAbsBinning in terms of an array of boundary values,...
Definition: RooBinning.h:29
virtual void setRange(Double_t xlo, Double_t xhi)
Change the defined range associated with this binning.
Definition: RooBinning.cxx:233
virtual Int_t binNumber(Double_t x) const
Return sequential bin number that contains value x where bin zero is the first bin with an upper boun...
Definition: RooBinning.cxx:186
virtual Double_t binLow(Int_t bin) const
Return the lower bound of the requested bin.
Definition: RooBinning.cxx:304
Bool_t hasBoundary(Double_t boundary)
Check if boundary exists at given value.
Definition: RooBinning.cxx:165
virtual Double_t binCenter(Int_t bin) const
Return the position of the center of bin 'bin'.
Definition: RooBinning.cxx:284
void updateBinCount()
Update the internal bin counter.
Definition: RooBinning.cxx:253
virtual Int_t rawBinNumber(Double_t x) const
Return sequential bin number that contains value x where bin zero is the first bin that is defined,...
Definition: RooBinning.cxx:196
virtual Int_t numBoundaries() const
Definition: RooBinning.h:39
Double_t * _array
Definition: RooBinning.h:87
Double_t _xlo
Definition: RooBinning.h:80
Bool_t _ownBoundLo
Definition: RooBinning.h:82
Int_t _blo
Array of boundaries.
Definition: RooBinning.h:88
Bool_t _ownBoundHi
Definition: RooBinning.h:83
Bool_t binEdges(Int_t bin, Double_t &xlo, Double_t &xhi) const
Return upper and lower bound of bin 'bin'.
Definition: RooBinning.cxx:271
void addUniform(Int_t nBins, Double_t xlo, Double_t xhi)
Add array of nbins uniformly sized bins in range [xlo,xhi].
Definition: RooBinning.cxx:173
Bool_t addBoundary(Double_t boundary)
Add bin boundary at given value.
Definition: RooBinning.cxx:111
void addBoundaryPair(Double_t boundary, Double_t mirrorPoint=0)
Add pair of boundaries: one at 'boundary' and one at 2*mirrorPoint-boundary.
Definition: RooBinning.cxx:131
~RooBinning()
Destructor.
Definition: RooBinning.cxx:103
Bool_t removeBoundary(Double_t boundary)
Remove boundary at given value.
Definition: RooBinning.cxx:140
RooBinning(Double_t xlo=-RooNumber::infinity(), Double_t xhi=RooNumber::infinity(), const char *name=0)
Constructor for an initially empty binning defining the range [xlo,xhi].
Definition: RooBinning.cxx:53
virtual Double_t binHigh(Int_t bin) const
Return the upper bound of the requested bin.
Definition: RooBinning.cxx:314
virtual Double_t binWidth(Int_t bin) const
Return the width of the requested bin.
Definition: RooBinning.cxx:294
Int_t _nbins
Definition: RooBinning.h:84
virtual Double_t nearestBoundary(Double_t x) const
Return the value of the nearest boundary to x.
Definition: RooBinning.cxx:209
Double_t _xhi
Definition: RooBinning.h:81
std::vector< Double_t > _boundaries
Definition: RooBinning.h:86
virtual Double_t * array() const
Return array of boundary values.
Definition: RooBinning.cxx:219
RooDouble is a minimal implementation of a TObject holding a Double_t value.
Definition: RooDouble.h:22
Buffer base class used for serializing objects.
Definition: TBuffer.h:42
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
Bool_t IsReading() const
Definition: TBuffer.h:85
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
Iterator abstract base class.
Definition: TIterator.h:30
virtual TObject * Next()=0
A doubly linked list.
Definition: TList.h:44
virtual TIterator * MakeIterator(Bool_t dir=kIterForward) const
Return a list iterator.
Definition: TList.cxx:719
Double_t x[n]
Definition: legend1.C:17
@ InputArguments
Definition: RooGlobalFunc.h:68