2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4 #ifndef MUONREADOUTGEOMETRYR4_WIREGROUPDESIGN_ICC
5 #define MUONREADOUTGEOMETRYR4_WIREGROUPDESIGN_ICC
7 #include <MuonReadoutGeometryR4/WireGroupDesign.h>
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();
17 const wireGroup& wireGrp = m_groups[groupNum];
18 return firstStripPos() +
19 (1. * wireGrp.accumlWires + 0.5 * (wireGrp.numWires -1))*stripPitch() * stripNormal();
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.");
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.");
36 return std::make_optional<Amg::Vector2D>(firstStripPos() +
37 (wireGrp.accumlWires + (wireNum - 1))*stripPitch() * stripNormal());
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);
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);
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))){
60 return ((*lIsect)- (*rIsect)).mag();
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());
69 const double distFromFirst = (*wirePitches);
70 /// The external position is waaay before the first wire position
71 if (distFromFirst < 0 || !insideTrapezoid(extPos)){
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(),
77 [this]( const double dist, const wireGroup& grp) {
78 const double firstWire = stripPitch() *(grp.accumlWires -0.5);
79 return dist < firstWire;
81 if (strip_itr == m_groups.begin()) {
84 return std::distance(m_groups.begin(), strip_itr) -1 + firstStripNumber();
86 inline std::pair<int, int> WireGroupDesign::wireNumber(const Amg::Vector2D& extPos) const {
87 const int wireGrp = stripNumber(extPos);
89 return std::make_pair(wireGrp, wireGrp);
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);