File indexing completed on 2024-04-06 12:24:37
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
0009
0010
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