Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:31:31

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