Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:31:45

0001 #ifndef BinningTools_GenericBinFinderInZ_H
0002 #define BinningTools_GenericBinFinderInZ_H
0003 
0004 /** \class GenericBinFinderInZ
0005  * A Z bin finder for a non-periodic group of detectors.
0006  * The template argument G should be something
0007  * with a surface() method, such as a GeomDet
0008  * or a GeometricSearchDet
0009  */
0010 
0011 #include "Utilities/BinningTools/interface/BaseBinFinder.h"
0012 #include <cmath>
0013 #include <vector>
0014 
0015 template <class T, class G>
0016 class GenericBinFinderInZ : public BaseBinFinder<T> {
0017 public:
0018   typedef typename std::vector<const G*>::const_iterator ConstItr;
0019   GenericBinFinderInZ() : theNbins(0), theZStep(0), theZOffset(0) {}
0020 
0021   GenericBinFinderInZ(ConstItr first, ConstItr last) : theNbins(last - first) {
0022     theBins.reserve(theNbins);
0023     theBorders.reserve(theNbins - 1);
0024     for (ConstItr i = first; i < last - 1; i++) {
0025       theBins.push_back((**i).position().z());
0026       theBorders.push_back(((**i).position().z() + (**(i + 1)).position().z()) / 2.);
0027     }
0028     theBins.push_back((**(last - 1)).position().z());
0029 
0030     theZOffset = theBorders.front();
0031     theZStep = (theBorders.back() - theBorders.front()) / (theNbins - 2);
0032   }
0033 
0034   /// returns an index in the valid range for the bin closest to Z
0035   int binIndex(T z) const override {
0036     int bin = binIndex(int((z - theZOffset) / theZStep) + 1);
0037 
0038     // check left border
0039     if (bin > 0) {
0040       if (z < theBorders[bin - 1]) {
0041         // z is to the left of the left border, the correct bin is left
0042         for (int i = bin - 1;; i--) {
0043           if (i <= 0)
0044             return 0;
0045           if (z > theBorders[i - 1])
0046             return i;
0047         }
0048       }
0049     } else
0050       return 0;
0051 
0052     // check right border
0053     if (bin < theNbins - 1) {
0054       if (z > theBorders[bin]) {
0055         // z is to the right of the right border, the correct bin is right
0056         for (int i = bin + 1;; i++) {
0057           if (i >= theNbins - 1)
0058             return theNbins - 1;
0059           if (z < theBorders[i])
0060             return i;
0061         }
0062       }
0063     } else
0064       return theNbins - 1;
0065 
0066     // if we arrive here it means that the bin is ok
0067     return bin;
0068   }
0069 
0070   /// returns an index in the valid range
0071   int binIndex(int i) const override { return std::min(std::max(i, 0), theNbins - 1); }
0072 
0073   /// the middle of the bin.
0074   T binPosition(int ind) const override { return theBins[binIndex(ind)]; }
0075 
0076   static double pi() { return 3.141592653589793238; }
0077   static double twoPi() { return 2. * pi(); }
0078 
0079 private:
0080   int theNbins;
0081   T theZStep;
0082   T theZOffset;
0083   std::vector<float> theBorders;
0084   std::vector<T> theBins;
0085 };
0086 #endif