Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-08 22:57:13

0001 #ifndef RecoCaloTools_Navigation_CaloRectangle_H
0002 #define RecoCaloTools_Navigation_CaloRectangle_H
0003 
0004 #include "Geometry/CaloTopology/interface/CaloSubdetectorTopology.h"
0005 #include "Geometry/CaloTopology/interface/CaloTopology.h"
0006 
0007 /*
0008  * CaloRectangle is a class to create a rectangular range of DetIds around a
0009  * central DetId. Meant to be used for range-based loops to calculate cluster
0010  * shape variables.
0011  */
0012 
0013 struct CaloRectangle {
0014   const int iEtaOrIXMin;
0015   const int iEtaOrIXMax;
0016   const int iPhiOrIYMin;
0017   const int iPhiOrIYMax;
0018 
0019   template <class T>
0020   auto operator()(T home, CaloTopology const& topology);
0021 };
0022 
0023 template <class T>
0024 T offsetBy(T start, CaloSubdetectorTopology const* topo, int dIEtaOrIX, int dIPhiOrIY) {
0025   if (topo) {
0026     for (int i = 0; i < std::abs(dIEtaOrIX) && start != T(0); i++) {
0027       start = dIEtaOrIX > 0 ? topo->goEast(start) : topo->goWest(start);
0028     }
0029 
0030     for (int i = 0; i < std::abs(dIPhiOrIY) && start != T(0); i++) {
0031       start = dIPhiOrIY > 0 ? topo->goNorth(start) : topo->goSouth(start);
0032     }
0033   }
0034   return start;
0035 }
0036 
0037 template <class T>
0038 class CaloRectangleRange {
0039 public:
0040   class Iterator {
0041   public:
0042     Iterator(T const& home,
0043              int iEtaOrIX,
0044              int iPhiOrIY,
0045              CaloRectangle const rectangle,
0046              CaloSubdetectorTopology const* topology)
0047         : home_(home), rectangle_(rectangle), topology_(topology), iEtaOrIX_(iEtaOrIX), iPhiOrIY_(iPhiOrIY) {}
0048 
0049     Iterator& operator++() {
0050       if (iPhiOrIY_ == rectangle_.iPhiOrIYMax) {
0051         iPhiOrIY_ = rectangle_.iPhiOrIYMin;
0052         iEtaOrIX_++;
0053       } else
0054         ++iPhiOrIY_;
0055       return *this;
0056     }
0057 
0058     int iEtaOrIX() const { return iEtaOrIX_; }
0059     int iPhiOrIY() const { return iPhiOrIY_; }
0060 
0061     bool operator==(Iterator const& other) const {
0062       return iEtaOrIX_ == other.iEtaOrIX() && iPhiOrIY_ == other.iPhiOrIY();
0063     }
0064     bool operator!=(Iterator const& other) const {
0065       return iEtaOrIX_ != other.iEtaOrIX() || iPhiOrIY_ != other.iPhiOrIY();
0066     }
0067 
0068     T operator*() const { return offsetBy(home_, topology_, iEtaOrIX_, iPhiOrIY_); }
0069 
0070   private:
0071     const T home_;
0072 
0073     const CaloRectangle rectangle_;
0074     CaloSubdetectorTopology const* topology_;
0075 
0076     int iEtaOrIX_;
0077     int iPhiOrIY_;
0078   };
0079 
0080 public:
0081   CaloRectangleRange(CaloRectangle rectangle, T home, CaloTopology const& topology)
0082       : home_(home), rectangle_(rectangle), topology_(topology.getSubdetectorTopology(home)) {}
0083 
0084   CaloRectangleRange(int size, T home, CaloTopology const& topology)
0085       : home_(home), rectangle_{-size, size, -size, size}, topology_(topology.getSubdetectorTopology(home)) {}
0086 
0087   auto begin() { return Iterator(home_, rectangle_.iEtaOrIXMin, rectangle_.iPhiOrIYMin, rectangle_, topology_); }
0088   auto end() { return Iterator(home_, rectangle_.iEtaOrIXMax + 1, rectangle_.iPhiOrIYMin, rectangle_, topology_); }
0089 
0090 private:
0091   const T home_;
0092   const CaloRectangle rectangle_;
0093   CaloSubdetectorTopology const* topology_;
0094 };
0095 
0096 template <class T>
0097 auto CaloRectangle::operator()(T home, CaloTopology const& topology) {
0098   return CaloRectangleRange<T>(*this, home, topology);
0099 }
0100 
0101 #endif