00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "RooFit.h"
00029
00030 #include "Riostream.h"
00031 #include "Riostream.h"
00032 #include "RooBinning.h"
00033 #include "RooDouble.h"
00034 #include "RooAbsPdf.h"
00035 #include "RooRealVar.h"
00036 #include "RooNumber.h"
00037 #include "RooMsgService.h"
00038 #include "TList.h"
00039
00040 ClassImp(RooBinning)
00041 ;
00042
00043
00044
00045 RooBinning::RooBinning(Double_t xlo, Double_t xhi, const char* name) :
00046 RooAbsBinning(name),
00047 _xlo(0),
00048 _xhi(0),
00049 _ownBoundLo(kTRUE),
00050 _ownBoundHi(kTRUE),
00051 _array(0)
00052 {
00053
00054
00055 setRange(xlo,xhi) ;
00056 }
00057
00058
00059
00060
00061 RooBinning::RooBinning(Int_t nbins, Double_t xlo, Double_t xhi, const char* name) :
00062 RooAbsBinning(name),
00063 _xlo(0),
00064 _xhi(0),
00065 _ownBoundLo(kTRUE),
00066 _ownBoundHi(kTRUE),
00067 _array(0)
00068 {
00069
00070
00071
00072 setRange(xlo,xhi) ;
00073 addUniform(nbins,xlo,xhi) ;
00074 }
00075
00076
00077
00078
00079
00080 RooBinning::RooBinning(Int_t nbins, const Double_t* boundaries, const char* name) :
00081 RooAbsBinning(name),
00082 _xlo(0),
00083 _xhi(0),
00084 _ownBoundLo(kTRUE),
00085 _ownBoundHi(kTRUE),
00086 _array(0)
00087 {
00088
00089
00090
00091
00092 setRange(boundaries[0],boundaries[nbins]) ;
00093 while(nbins--) addBoundary(boundaries[nbins]) ;
00094 }
00095
00096
00097
00098
00099 RooBinning::RooBinning(const RooBinning& other, const char* name) :
00100 RooAbsBinning(name),
00101 _boundaries(other._boundaries),
00102 _array(0)
00103 {
00104
00105 _xlo = other._xlo ;
00106 _xhi = other._xhi ;
00107 _ownBoundLo = other._ownBoundLo ;
00108 _ownBoundHi = other._ownBoundHi ;
00109 _nbins = other._nbins ;
00110 }
00111
00112
00113
00114
00115 RooBinning::~RooBinning()
00116 {
00117
00118
00119 if (_array) delete[] _array ;
00120
00121 }
00122
00123
00124
00125 Bool_t RooBinning::addBoundary(Double_t boundary)
00126 {
00127
00128
00129 if (_boundaries.find(boundary)!=_boundaries.end()) {
00130
00131
00132 if (boundary==_xlo) _ownBoundLo = kFALSE ;
00133 if (boundary==_xhi) _ownBoundHi = kFALSE ;
00134 return kFALSE ;
00135 }
00136
00137
00138 _boundaries.insert(boundary) ;
00139 updateBinCount() ;
00140 return kTRUE ;
00141 }
00142
00143
00144
00145
00146 void RooBinning::addBoundaryPair(Double_t boundary, Double_t mirrorPoint)
00147 {
00148
00149
00150 addBoundary(boundary) ;
00151 addBoundary(2*mirrorPoint-boundary) ;
00152 }
00153
00154
00155
00156
00157 Bool_t RooBinning::removeBoundary(Double_t boundary)
00158 {
00159
00160
00161 if (_boundaries.find(boundary)!=_boundaries.end()) {
00162 _boundaries.erase(boundary) ;
00163 return kFALSE ;
00164 }
00165
00166
00167 return kTRUE ;
00168 }
00169
00170
00171
00172
00173 Bool_t RooBinning::hasBoundary(Double_t boundary)
00174 {
00175
00176
00177 return (_boundaries.find(boundary)!=_boundaries.end()) ;
00178 }
00179
00180
00181
00182
00183 void RooBinning::addUniform(Int_t nbins, Double_t xlo, Double_t xhi)
00184 {
00185
00186
00187 Int_t i ;
00188 Double_t binw = (xhi-xlo)/nbins ;
00189 for (i=0 ; i<=nbins ; i++)
00190 addBoundary(xlo+i*binw) ;
00191 }
00192
00193
00194
00195
00196 Int_t RooBinning::binNumber(Double_t x) const
00197 {
00198
00199
00200
00201
00202 Int_t n(0) ;
00203 for (set<Double_t>::const_iterator iter = _boundaries.begin() ; iter!=_boundaries.end() ; ++iter) {
00204 if (x<*iter) {
00205 return n ;
00206 }
00207
00208
00209 if (*iter> _xlo && n<_nbins-1) n++ ;
00210 }
00211 return n;
00212 }
00213
00214
00215
00216
00217 Int_t RooBinning::rawBinNumber(Double_t x) const
00218 {
00219
00220
00221
00222
00223
00224
00225 Int_t n(0) ;
00226
00227 for (set<Double_t>::const_iterator iter = _boundaries.begin() ; iter!=_boundaries.end() ; ++iter) {
00228 if (x<*iter) return n>0?n-1:0 ;
00229 n++ ;
00230 }
00231 return n-1;
00232 }
00233
00234
00235
00236
00237 Double_t RooBinning::nearestBoundary(Double_t x) const
00238 {
00239
00240
00241 Int_t bn = binNumber(x) ;
00242 if (fabs(binLow(bn)-x)<fabs(binHigh(bn)-x)) {
00243 return binLow(bn) ;
00244 } else {
00245 return binHigh(bn) ;
00246 }
00247 }
00248
00249
00250
00251
00252 Double_t* RooBinning::array() const
00253 {
00254
00255
00256 if (_array) delete[] _array ;
00257 _array = new Double_t[numBoundaries()] ;
00258
00259 Int_t i(0) ;
00260 for (set<Double_t>::const_iterator iter = _boundaries.begin() ; iter!=_boundaries.end() ; ++iter) {
00261 if (*iter>=_xlo && *iter <=_xhi) {
00262 _array[i++] = *iter ;
00263 }
00264 }
00265 return _array ;
00266 }
00267
00268
00269
00270
00271 void RooBinning::setRange(Double_t xlo, Double_t xhi)
00272 {
00273
00274
00275
00276
00277
00278 if (xlo>xhi) {
00279 coutE(InputArguments) << "RooUniformBinning::setRange: ERROR low bound > high bound" << endl ;
00280 return ;
00281 }
00282
00283
00284
00285 for (set<Double_t>::iterator iter = _boundaries.begin() ; iter!=_boundaries.end() ;) {
00286 if ((*iter == _xlo && _ownBoundLo) || (*iter == _xhi && _ownBoundHi)) {
00287 _boundaries.erase(iter++) ;
00288 } else {
00289 ++iter ;
00290 }
00291 }
00292
00293
00294 _ownBoundLo = kFALSE ;
00295 _ownBoundHi = kFALSE ;
00296 if (!hasBoundary(xlo)) {
00297 addBoundary(xlo) ;
00298 _ownBoundLo = kTRUE ;
00299 }
00300 if (!hasBoundary(xhi)) {
00301 addBoundary(xhi) ;
00302 _ownBoundHi = kTRUE ;
00303 }
00304
00305 _xlo = xlo ;
00306 _xhi = xhi ;
00307
00308
00309 updateBinCount() ;
00310 }
00311
00312
00313
00314
00315
00316 void RooBinning::updateBinCount()
00317 {
00318
00319
00320 Int_t i(-1) ;
00321 for (set<Double_t>::const_iterator iter = _boundaries.begin() ; iter!=_boundaries.end() ; ++iter) {
00322 if (*iter>=_xlo && *iter <=_xhi) {
00323 i++ ;
00324 }
00325 }
00326 _nbins = i ;
00327 }
00328
00329
00330
00331
00332 Bool_t RooBinning::binEdges(Int_t bin, Double_t& xlo, Double_t& xhi) const
00333 {
00334
00335
00336
00337 if (bin<0 || bin>= _nbins) {
00338 coutE(InputArguments) << "RooBinning::binEdges ERROR: bin number must be in range (0," << _nbins << ")" << endl ;
00339 return kTRUE ;
00340 }
00341
00342
00343 Int_t n(0) ;
00344 for (set<Double_t>::const_iterator iter = _boundaries.begin() ; iter!=_boundaries.end() ; ++iter) {
00345
00346 if (n==bin && *iter>=_xlo) {
00347 xlo = *iter ;
00348 iter++ ;
00349 xhi = *iter ;
00350 return kFALSE ;
00351 }
00352
00353
00354 if (*iter>= _xlo && n<_nbins-1) n++ ;
00355 }
00356
00357 return kTRUE ;
00358 }
00359
00360
00361
00362
00363 Double_t RooBinning::binCenter(Int_t bin) const
00364 {
00365
00366
00367 Double_t xlo,xhi ;
00368 if (binEdges(bin,xlo,xhi)) return 0 ;
00369 return (xlo+xhi)/2 ;
00370 }
00371
00372
00373
00374
00375 Double_t RooBinning::binWidth(Int_t bin) const
00376 {
00377
00378
00379 Double_t xlo,xhi ;
00380 if (binEdges(bin,xlo,xhi)) return 0 ;
00381 return (xhi-xlo);
00382 }
00383
00384
00385
00386
00387 Double_t RooBinning::binLow(Int_t bin) const
00388 {
00389
00390
00391 Double_t xlo,xhi ;
00392 if (binEdges(bin,xlo,xhi)) return 0 ;
00393 return xlo ;
00394 }
00395
00396
00397
00398
00399 Double_t RooBinning::binHigh(Int_t bin) const
00400 {
00401
00402
00403 Double_t xlo,xhi ;
00404 if (binEdges(bin,xlo,xhi)) return 0 ;
00405 return xhi ;
00406 }
00407
00408
00409
00410
00411 void RooBinning::Streamer(TBuffer &R__b)
00412 {
00413
00414
00415 if (R__b.IsReading()) {
00416
00417 UInt_t R__s, R__c;
00418 Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
00419 if (R__v>1) {
00420 R__b.ReadClassBuffer(RooBinning::Class(),this,R__v,R__s,R__c);
00421 } else {
00422 RooAbsBinning::Streamer(R__b);
00423 R__b >> _xlo;
00424 R__b >> _xhi;
00425 R__b >> _ownBoundLo;
00426 R__b >> _ownBoundHi;
00427 R__b >> _nbins;
00428
00429
00430 TList boundaries ;
00431 boundaries.Streamer(R__b);
00432 TIterator* iter = boundaries.MakeIterator() ;
00433 RooDouble* elem ;
00434 while((elem=(RooDouble*)iter->Next())) {
00435 _boundaries.insert(*elem) ;
00436 }
00437 delete iter ;
00438
00439 R__b.CheckByteCount(R__s, R__c, RooBinning::IsA());
00440 }
00441 } else {
00442 R__b.WriteClassBuffer(RooBinning::Class(),this);
00443 }
00444 }
00445
00446