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