00001 #ifndef BinningTools_GenericBinFinderInZ_H 00002 #define BinningTools_GenericBinFinderInZ_H 00003 00011 #include "Utilities/BinningTools/interface/BaseBinFinder.h" 00012 #include <cmath> 00013 #include <vector> 00014 00015 template <class T, class G> 00016 class GenericBinFinderInZ : public BaseBinFinder<T> { 00017 public: 00018 typedef typename std::vector<const G*>::const_iterator ConstItr; 00019 GenericBinFinderInZ() : theNbins(0), theZStep(0), theZOffset(0) {} 00020 00021 GenericBinFinderInZ(ConstItr first, ConstItr last) : 00022 theNbins( last-first) 00023 { 00024 theBins.reserve(theNbins); 00025 for (ConstItr i=first; i<last-1; i++) { 00026 theBins.push_back((**i).position().z()); 00027 theBorders.push_back(((**i).position().z() + 00028 (**(i+1)).position().z()) / 2.); 00029 } 00030 00031 theZOffset = theBorders.front(); 00032 theZStep = (theBorders.back() - theBorders.front()) / (theNbins-2); 00033 } 00034 00036 virtual int binIndex( T z) const { 00037 int bin = binIndex( int((z-theZOffset)/theZStep)+1); 00038 00039 // check left border 00040 if (bin > 0) { 00041 if ( z < theBorders[bin-1]) { 00042 // z is to the left of the left border, the correct bin is left 00043 for (int i=bin-1; ; i--) { 00044 if (i <= 0) return 0; 00045 if ( z > theBorders[i-1]) return i; 00046 } 00047 } 00048 } 00049 else return 0; 00050 00051 // check right border 00052 if (bin < theNbins-1) { 00053 if ( z > theBorders[bin]) { 00054 // z is to the right of the right border, the correct bin is right 00055 for (int i=bin+1; ; i++) { 00056 if (i >= theNbins-1) return theNbins-1; 00057 if ( z < theBorders[i]) return i; 00058 } 00059 } 00060 } 00061 else return theNbins-1; 00062 00063 // if we arrive here it means that the bin is ok 00064 return bin; 00065 } 00066 00068 virtual int binIndex( int i) const { 00069 return std::min( std::max( i, 0), theNbins-1); 00070 } 00071 00073 virtual T binPosition( int ind) const { 00074 return theBins[binIndex(ind)]; 00075 } 00076 00077 static double pi() { return 3.141592653589793238;} 00078 static double twoPi() { return 2.*pi();} 00079 00080 private: 00081 00082 int theNbins; 00083 T theZStep; 00084 T theZOffset; 00085 std::vector<float> theBorders; 00086 std::vector<T> theBins; 00087 }; 00088 #endif