Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef TrackingTools_DetLayers_GeneralBinFinderInPhi_H
0002 #define TrackingTools_DetLayers_GeneralBinFinderInPhi_H
0003 
0004 /** \class GeneralBinFinderInPhi
0005  * A phi bin finder for a non-periodic group of detectors.
0006  *
0007  *  \author N. Amapane - INFN Torino
0008  */
0009 
0010 #include "Utilities/BinningTools/interface/BaseBinFinder.h"
0011 #include "TrackingTools/DetLayers/interface/PhiBorderFinder.h"
0012 #include "DataFormats/GeometryVector/interface/Pi.h"
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 
0015 #include <vector>
0016 
0017 template <class T>
0018 class GeneralBinFinderInPhi : public BaseBinFinder<T> {
0019 public:
0020   typedef PhiBorderFinder::Det Det;  //FIXME!!!
0021 
0022   GeneralBinFinderInPhi() : theNbins(0) {}
0023 
0024   /// Construct from an already initialized PhiBorderFinder
0025   GeneralBinFinderInPhi(const PhiBorderFinder& bf) {
0026     theBorders = bf.phiBorders();
0027     theBins = bf.phiBins();
0028     theNbins = theBins.size();
0029   }
0030 
0031   /// Construct from the list of Det*
0032   GeneralBinFinderInPhi(std::vector<Det*>::const_iterator first, std::vector<Det*>::const_iterator last)
0033       : theNbins(last - first) {
0034     std::vector<const Det*> dets(first, last);
0035     PhiBorderFinder bf(dets);
0036     theBorders = bf.phiBorders();
0037     theBins = bf.phiBins();
0038     theNbins = theBins.size();
0039   }
0040 
0041   ~GeneralBinFinderInPhi() override{};
0042 
0043   /// Returns an index in the valid range for the bin that contains
0044   /// AND is closest to phi
0045   int binIndex(T phi) const override {
0046     const std::string metname = "Muon|RecoMuon|RecoMuonDetLayers|GeneralBinFinderInPhi";
0047 
0048     static const T epsilon = 10 * std::numeric_limits<T>::epsilon();
0049     // Assume -pi, pi range in pi (which is the case for Geom::Phi
0050 
0051     LogTrace(metname) << "GeneralBinFinderInPhi::binIndex,"
0052                       << " Nbins: " << theNbins;
0053 
0054     for (int i = 0; i < theNbins; i++) {
0055       T cur = theBorders[i];
0056       T next = theBorders[binIndex(i + 1)];
0057       T phi_ = phi;
0058 
0059       LogTrace(metname) << "bin: " << i << " border min " << cur << " border max: " << next << " phi: " << phi_;
0060 
0061       if (cur > next)  // we are crossing the pi edge: so move the edge to 0!
0062       {
0063         cur = positiveRange(cur);
0064         next = positiveRange(next);
0065         phi_ = positiveRange(phi_);
0066       }
0067       if (phi_ > cur - epsilon && phi_ < next)
0068         return i;
0069     }
0070     throw cms::Exception("UnexpectedState") << "GeneralBinFinderInPhi::binIndex( T phi) bin not found!";
0071   }
0072 
0073   /// Returns an index in the valid range, modulo Nbins
0074   int binIndex(int i) const override {
0075     int ind = i % (int)theNbins;
0076     return (ind < 0) ? ind + theNbins : ind;
0077   }
0078 
0079   /// the middle of the bin in radians
0080   T binPosition(int ind) const override { return theBins[binIndex(ind)]; }
0081 
0082 private:
0083   int theNbins;
0084   std::vector<T> theBorders;
0085   std::vector<T> theBins;
0086 
0087   // returns a positive angle; does NOT reduce the range to 2 pi
0088   inline T positiveRange(T phi) const { return (phi > 0) ? phi : phi + Geom::twoPi(); }
0089 };
0090 #endif