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