CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoMuon/DetLayers/src/GeneralBinFinderInPhi.h

Go to the documentation of this file.
00001 #ifndef GeneralBinFinderInPhi_H
00002 #define GeneralBinFinderInPhi_H
00003 
00012 #include "Utilities/BinningTools/interface/BaseBinFinder.h"
00013 #include "PhiBorderFinder.h"
00014 #include "DataFormats/GeometryVector/interface/Pi.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 
00017 #include <vector>
00018 
00019 template <class T>
00020 class GeneralBinFinderInPhi : public BaseBinFinder<T> {
00021 public:
00022 
00023   typedef PhiBorderFinder::Det Det; //FIXME!!!
00024 
00025   GeneralBinFinderInPhi() : theNbins(0) {}
00026 
00028   GeneralBinFinderInPhi(const PhiBorderFinder& bf) {
00029     theBorders=bf.phiBorders();
00030     theBins=bf.phiBins();
00031     theNbins=theBins.size();
00032   }
00033 
00035   GeneralBinFinderInPhi(std::vector<Det*>::const_iterator first,
00036                         std::vector<Det*>::const_iterator last)
00037     : theNbins( last-first)
00038   {
00039     std::vector<Det*> dets(first,last);
00040     PhiBorderFinder bf(dets);
00041     theBorders=bf.phiBorders();
00042     theBins=bf.phiBins();
00043     theNbins=theBins.size();
00044   }
00045 
00046   virtual ~GeneralBinFinderInPhi(){};
00047 
00050   virtual int binIndex( T phi) const {
00051     
00052     const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|GeneralBinFinderInPhi";
00053 
00054     static T epsilon = 10*std::numeric_limits<T>::epsilon();
00055     // Assume -pi, pi range in pi (which is the case for Geom::Phi
00056 
00057     LogTrace(metname) << "GeneralBinFinderInPhi::binIndex,"
00058                       << " Nbins: "<< theNbins;
00059 
00060     for (int i = 0; i< theNbins; i++) {
00061 
00062       T cur = theBorders[i];
00063       T next = theBorders[binIndex(i+1)];
00064       T phi_ = phi;
00065 
00066       LogTrace(metname) << "bin: " << i 
00067                         << " border min " << cur << " border max: " << next << " phi: "<< phi_;
00068 
00069       if ( cur > next ) // we are crossing the pi edge: so move the edge to 0!
00070         {
00071           cur = positiveRange(cur);
00072           next = positiveRange(next);
00073           phi_ = positiveRange(phi_); 
00074         }
00075       if (phi_ > cur-epsilon && phi_ < next) return i;
00076     }
00077     throw cms::Exception("UnexpectedState") << "GeneralBinFinderInPhi::binIndex( T phi) bin not found!";
00078   }
00079   
00081   virtual int binIndex( int i) const {
00082     int ind = i % (int)theNbins;
00083     return (ind < 0) ? ind+theNbins : ind;
00084   }
00085 
00087   virtual T binPosition( int ind) const {
00088     return theBins[binIndex(ind)];
00089   }
00090 
00091 
00092 private:
00093   int theNbins;
00094   std::vector<T> theBorders;
00095   std::vector<T> theBins;
00096 
00097   // returns a positive angle; does NOT reduce the range to 2 pi
00098   inline T positiveRange (T phi) const
00099   {
00100     return (phi > 0) ? phi : phi + Geom::twoPi();
00101   }
00102 
00103 };
00104 #endif
00105