ATLAS Offline Software
WireGroupDesign.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 #ifndef MUONREADOUTGEOMETRYR4_WIREGROUPDESIGN_ICC
5 #define MUONREADOUTGEOMETRYR4_WIREGROUPDESIGN_ICC
6 
7 #include <MuonReadoutGeometryR4/WireGroupDesign.h>
8 
9 namespace MuonGMR4 {
10  using CheckVector2D = WireGroupDesign::CheckVector2D;
11  inline Amg::Vector2D WireGroupDesign::stripPosition(int groupNum) const {
12  if (groupNum >= static_cast<int>(m_groups.size())) {
13  ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The wire group number "<<groupNum
14  <<" is out of range.");
15  return Amg::Vector2D::Zero();
16  }
17  const wireGroup& wireGrp = m_groups[groupNum];
18  return firstStripPos() +
19  (1. * wireGrp.accumlWires + 0.5 * (wireGrp.numWires -1))*stripPitch() * stripNormal();
20  }
21  inline CheckVector2D WireGroupDesign::wirePosition(unsigned int groupNum,
22  unsigned int wireNum) const {
23  unsigned int grpIdx = groupNum - firstStripNumber();
24  if (grpIdx >= m_groups.size()) {
25  ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The wire group number "<<groupNum
26  <<"is out of range.");
27  return std::nullopt;
28  }
29  const wireGroup& wireGrp = m_groups[grpIdx];
30  if (wireNum > wireGrp.numWires){
31  ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The wire number "
32  <<wireNum<<" is out of range. Expect in group "<<groupNum<<
33  " [1-"<<wireGrp.numWires<<"] wires.");
34  return std::nullopt;
35  }
36  return std::make_optional<Amg::Vector2D>(firstStripPos() +
37  (wireGrp.accumlWires + (wireNum - 1))*stripPitch() * stripNormal());
38  }
39  inline CheckVector2D WireGroupDesign::leftWireEdge(unsigned int groupNum,
40  unsigned int wireNum) const {
41  CheckVector2D wPos{wirePosition(groupNum, wireNum)};
42  if(!wPos) return std::nullopt;
43  return leftInterSect(*wPos);
44  }
45 
46  inline CheckVector2D WireGroupDesign::rightWireEdge(unsigned int groupNum,
47  unsigned int wireNum) const {
48  CheckVector2D wPos{wirePosition(groupNum, wireNum)};
49  if(!wPos) return std::nullopt;
50  return rightInterSect(*wPos);
51  }
52  inline double WireGroupDesign::wireLength(unsigned int groupNum,
53  unsigned int wireNum) const{
54  CheckVector2D wirePos{}, lIsect{}, rIsect{};
55  if (!(wirePos = wirePosition(groupNum, wireNum)) ||
56  !(lIsect = leftInterSect(*wirePos)) ||
57  !(rIsect = rightInterSect(*wirePos))){
58  return 0;
59  }
60  return ((*lIsect)- (*rIsect)).mag();
61  }
62 
63  inline int WireGroupDesign::stripNumber(const Amg::Vector2D& extPos) const {
64  std::optional<double> wirePitches = Amg::intersect<2>(firstStripPos(), stripDir(),
65  extPos, - Amg::Vector2D::UnitX());
66  if (!wirePitches) {
67  return -1;
68  }
69  const double distFromFirst = (*wirePitches);
70  /// The external position is waaay before the first wire position
71  if (distFromFirst < 0 || !insideTrapezoid(extPos)){
72  return -1;
73  }
74  /// Find the first group whose first last wire is encapsulating the distance
75  wireGrpVectorItr strip_itr = std::upper_bound(m_groups.begin(), m_groups.end(),
76  distFromFirst,
77  [this]( const double dist, const wireGroup& grp) {
78  const double firstWire = stripPitch() *(grp.accumlWires -0.5);
79  return dist < firstWire;
80  });
81  if (strip_itr == m_groups.begin()) {
82  return -1;
83  }
84  return std::distance(m_groups.begin(), strip_itr) -1 + firstStripNumber();
85  }
86  inline std::pair<int, int> WireGroupDesign::wireNumber(const Amg::Vector2D& extPos) const {
87  const int wireGrp = stripNumber(extPos);
88  if (wireGrp < 0) {
89  return std::make_pair(wireGrp, wireGrp);
90  }
91  std::optional<double> wirePitches = Amg::intersect<2>(wirePosition(wireGrp, 1).value(), stripDir(),
92  extPos, - Amg::Vector2D::UnitX());
93  const int wire = std::round(wirePitches.value_or(-1.) / stripPitch()) +1;
94  return std::make_pair(wireGrp, wire);
95  }
96 
97 
98 
99 }
100 #endif