53 RooBinning::RooBinning(Double_t xlo, Double_t xhi,
const char* name) :
55 _xlo(0), _xhi(0), _ownBoundLo(kTRUE), _ownBoundHi(kTRUE),
64 RooBinning::RooBinning(Int_t nbins, Double_t xlo, Double_t xhi,
const char* name) :
66 _xlo(0), _xhi(0), _ownBoundLo(kTRUE), _ownBoundHi(kTRUE),
69 _boundaries.reserve(1 + nbins);
71 addUniform(nbins, xlo, xhi);
78 RooBinning::RooBinning(Int_t nbins,
const Double_t* boundaries,
const char* name) :
80 _xlo(0), _xhi(0), _ownBoundLo(kTRUE), _ownBoundHi(kTRUE),
84 _boundaries.reserve(1 + nbins);
85 setRange(boundaries[0], boundaries[nbins]);
86 while (nbins--) addBoundary(boundaries[nbins]);
92 RooBinning::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),
103 RooBinning::~RooBinning()
111 Bool_t RooBinning::addBoundary(Double_t boundary)
113 std::vector<Double_t>::iterator it =
114 std::lower_bound(_boundaries.begin(), _boundaries.end(), boundary);
115 if (_boundaries.end() != it && *it == boundary) {
118 if (boundary == _xlo) _ownBoundLo = kFALSE;
119 if (boundary == _xhi) _ownBoundHi = kFALSE;
123 _boundaries.insert(it, boundary);
131 void RooBinning::addBoundaryPair(Double_t boundary, Double_t mirrorPoint)
133 addBoundary(boundary);
134 addBoundary(2. * mirrorPoint - boundary);
140 Bool_t RooBinning::removeBoundary(Double_t boundary)
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);
149 if (_boundaries.empty()) {
152 if (boundary == _xlo) _xlo = _boundaries.front();
153 if (boundary == _xhi) _xhi = _boundaries.back();
165 Bool_t RooBinning::hasBoundary(Double_t boundary)
167 return std::binary_search(_boundaries.begin(), _boundaries.end(), boundary);
173 void RooBinning::addUniform(Int_t nbins, Double_t xlo, Double_t xhi)
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);
186 Int_t RooBinning::binNumber(Double_t x)
const
188 return std::max(0, std::min(_nbins, rawBinNumber(x) - _blo));
196 Int_t RooBinning::rawBinNumber(Double_t x)
const
198 std::vector<Double_t>::const_iterator it = std::lower_bound(
199 _boundaries.begin(), _boundaries.end(), x);
201 while (_boundaries.begin() != it &&
202 (_boundaries.end() == it || _boundaries.end() == it + 1 || x < *it)) --it;
203 return it - _boundaries.begin();
209 Double_t RooBinning::nearestBoundary(Double_t x)
const
212 binEdges(binNumber(x), xl, xh);
213 return (std::abs(xl - x) < std::abs(xh - x)) ? xl : xh;
219 Double_t* RooBinning::array()
const
222 _array =
new Double_t[numBoundaries()];
223 std::copy(_boundaries.begin()+_blo, _boundaries.begin()+_blo+_nbins+1, _array);
233 void RooBinning::setRange(Double_t xlo, Double_t xhi)
236 coutE(InputArguments) <<
"RooBinning::setRange: ERROR low bound > high bound" << endl;
240 if (_ownBoundLo) removeBoundary(_xlo);
241 if (_ownBoundHi) removeBoundary(_xhi);
243 _ownBoundLo = addBoundary(xlo);
244 _ownBoundHi = addBoundary(xhi);
245 _xlo = xlo, _xhi = xhi;
253 void RooBinning::updateBinCount()
255 if (_boundaries.size() <= 1) {
259 _blo = rawBinNumber(_xlo);
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();
271 Bool_t RooBinning::binEdges(Int_t bin, Double_t& xlo, Double_t& xhi)
const
273 if (0 > bin || bin >= _nbins) {
274 coutE(InputArguments) <<
"RooBinning::binEdges ERROR: bin number must be in range (0," << _nbins <<
")" << endl;
277 xlo = _boundaries[bin + _blo], xhi = _boundaries[bin + _blo + 1];
284 Double_t RooBinning::binCenter(Int_t bin)
const
287 if (binEdges(bin, xlo, xhi))
return 0;
288 return 0.5 * (xlo + xhi);
294 Double_t RooBinning::binWidth(Int_t bin)
const
297 if (binEdges(bin, xlo, xhi))
return 0;
304 Double_t RooBinning::binLow(Int_t bin)
const
307 if (binEdges(bin, xlo, xhi))
return 0;
314 Double_t RooBinning::binHigh(Int_t bin)
const
317 if (binEdges(bin, xlo, xhi))
return 0;
324 void RooBinning::Streamer(TBuffer &R__b)
326 if (R__b.IsReading()) {
329 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v) { }
337 R__b.ReadClassBuffer(RooBinning::Class(),
this, R__v, R__s, R__c);
341 RooAbsBinning::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);
358 R__b.CheckByteCount(R__s, R__c, RooBinning::IsA());
361 throw std::string(
"Unknown class version!");
363 if (_boundaries.size() > 2) {
364 std::sort(_boundaries.begin(), _boundaries.end());
365 _boundaries.erase(std::unique(_boundaries.begin(), _boundaries.end()),
369 R__b.WriteClassBuffer(RooBinning::Class(),
this);