ATLAS Offline Software
MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/RpcReadoutElement.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_RPCREADOUTELEMENT_ICC
5 #define MUONREADOUTGEOMETRYR4_RPCREADOUTELEMENT_ICC
6 
7 
8 namespace ActsTrk{
9  template <> inline Amg::Transform3D
10  TransformCacheDetEle<MuonGMR4::RpcReadoutElement>::fetchTransform(const DetectorAlignStore* store) const{
11  return m_parent->toStation(store) * m_parent->fromGapToChamOrigin(hash());
12  }
13 }
14 
15 namespace MuonGMR4 {
16  namespace RpcIdMeasHashFields{
17  constexpr unsigned int minOne = -1;
18  /// Bitwise layout of the measurement hash
19  /// ( strip | meashPhi | doubletPhi [1-2]| gasGap [1-3])
20  /// 1 bit 1 bit
21  constexpr unsigned int gasGapShift = 0;
22  /// @brief gasGap ranges from 1-3 -> 2 bits
23  constexpr unsigned int doubletPhiShift = 2;
24  /// @brief doubletPhi ranges from 1-2 -> 1 bit
25  constexpr unsigned int measPhiShift = doubletPhiShift + 1;
26  /// @brief measPhi is one bit
27  constexpr unsigned int channelShift = measPhiShift + 1;
28  }
29  inline double RpcReadoutElement::thickness() const { return 2.* m_pars.halfThickness; }
30  inline double RpcReadoutElement::gasGapPitch() const {return m_gasThickness; }
31  inline int RpcReadoutElement::doubletZ() const{ return m_doubletZ; }
32  inline int RpcReadoutElement::doubletR() const{ return m_doubletR; }
33  inline int RpcReadoutElement::doubletPhi() const{ return m_doubletPhi; }
34  inline unsigned int RpcReadoutElement::nGasGaps() const { return m_pars.nGasGaps; }
35  inline int RpcReadoutElement::nPhiPanels() const { return m_pars.nPanelsInPhi; }
36  inline int RpcReadoutElement::doubletPhiMax() const {return std::max(nPhiPanels(), doubletPhi()); }
37  inline unsigned int RpcReadoutElement::nEtaStrips() const { return (m_pars.etaDesign ? m_pars.etaDesign->numStrips(): 0u); }
38  inline unsigned int RpcReadoutElement::nPhiStrips() const { return (m_pars.phiDesign ? m_pars.phiDesign->numStrips(): 0u); }
39  inline double RpcReadoutElement::stripEtaPitch() const { return (m_pars.etaDesign ? m_pars.etaDesign->stripPitch() : 0.); }
40  inline double RpcReadoutElement::stripPhiPitch() const { return (m_pars.phiDesign ? m_pars.phiDesign->stripPitch() : 0.); }
41  inline double RpcReadoutElement::stripEtaWidth() const { return (m_pars.etaDesign ? m_pars.etaDesign->stripWidth() : 0.); }
42  inline double RpcReadoutElement::stripPhiWidth() const { return (m_pars.phiDesign ? m_pars.phiDesign->stripWidth() : 0.); }
43  inline double RpcReadoutElement::stripEtaLength() const { return (m_pars.etaDesign ? m_pars.etaDesign->longHalfHeight()*2. : 0.);}
44  inline double RpcReadoutElement::stripPhiLength() const { return (m_pars.phiDesign ? m_pars.phiDesign->longHalfHeight()*2. : 0.);}
45  inline IdentifierHash RpcReadoutElement::measurementHash(const Identifier& measId) const {
46  if (m_idHelper.doubletZ(measId) != doubletZ() ||
47  (doubletPhi() != 1 && m_idHelper.doubletPhi(measId) == 1) ||
48  m_idHelper.elementID(measId) != m_idHelper.elementID(identify()) ) {
49  ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
50  << " picks the wrong readout element " << idHelperSvc()->toStringDetEl(identify()));
51  }
52  return createHash(m_idHelper.strip(measId),
53  m_idHelper.gasGap(measId),
54  m_idHelper.doubletPhi(measId),
55  m_idHelper.measuresPhi(measId));
56  }
57  inline IdentifierHash RpcReadoutElement::layerHash(const Identifier& measId) const {
58  if (m_idHelper.doubletZ(measId) != doubletZ() ||
59  (doubletPhi() != 1 && m_idHelper.doubletPhi(measId) == 1) ||
60  m_idHelper.elementID(measId) != m_idHelper.elementID(identify()) ) {
61  ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
62  << " picks the wrong readout element " << idHelperSvc()->toStringDetEl(identify()));
63  }
64  return createHash(0, m_idHelper.gasGap(measId),
65  m_idHelper.doubletPhi(measId),
66  m_idHelper.measuresPhi(measId));
67  }
68 inline IdentifierHash RpcReadoutElement::layerHash(const IdentifierHash& measHash) const {
69  using namespace RpcIdMeasHashFields;
70  constexpr unsigned int mask = minOne << channelShift;
71  return IdentifierHash{static_cast<unsigned int>(measHash) & (~mask)};
72 }
73 inline IdentifierHash RpcReadoutElement::createHash(const unsigned int strip,
74  const unsigned int gasGap,
75  const unsigned int doubPhi,
76  const bool measPhi) {
77  using namespace RpcIdMeasHashFields;
78  const IdentifierHash hash{ strip << channelShift | measPhi << measPhiShift |
79  (doubPhi -1) << doubletPhiShift | (gasGap -1) << gasGapShift };
80  return hash;
81 }
82 inline unsigned int RpcReadoutElement::stripNumber(const IdentifierHash& measHash) {
83  using namespace RpcIdMeasHashFields;
84  return static_cast<unsigned int>(measHash) >> channelShift;
85 }
86 inline unsigned int RpcReadoutElement::gasGapNumber(const IdentifierHash& measHash) {
87  using namespace RpcIdMeasHashFields;
88  constexpr unsigned int mask = minOne << doubletPhiShift;
89  const unsigned int stripedHash = (~mask) & static_cast<unsigned int>(measHash);
90  return ( stripedHash >> gasGapShift);
91 }
92 inline unsigned int RpcReadoutElement::doubletPhiNumber(const IdentifierHash& measHash) {
93  using namespace RpcIdMeasHashFields;
94  constexpr unsigned int mask = minOne << measPhiShift;
95  const unsigned int stripedMask = (~mask) & static_cast<unsigned int>(measHash);
96  return (stripedMask >> doubletPhiShift);
97 }
98 inline bool RpcReadoutElement::measuresPhi(const IdentifierHash& measHash) {
99  using namespace RpcIdMeasHashFields;
100  constexpr unsigned int mask = minOne << channelShift;
101  const unsigned int stripedMask = (~mask) & static_cast<unsigned int>(measHash);
102  return (stripedMask >> measPhiShift);
103 }
104 inline const StripLayer& RpcReadoutElement::sensorLayout(const IdentifierHash& measHash) const {
105  const unsigned int layIdx{static_cast<unsigned int>(layerHash(measHash))};
106  if (layIdx >= m_pars.layers.size() || !m_pars.layers[layIdx]) {
107  ATH_MSG_FATAL("The sensorLayout does not exist for "<<idHelperSvc()->toStringDetEl(identify())
108  <<" gasGap "<<(gasGapNumber(measHash) +1)
109  <<" doubletPhi: "<<(doubletPhiNumber(measHash) + 1)
110  <<" isPhiChannel: "<<measuresPhi(measHash)
111  <<" strip: "<<stripNumber(measHash) );
112  throw std::runtime_error("Invalid sensor layout");
113  }
114  return (*m_pars.layers[layIdx]);
115 }
116 
117 inline Identifier RpcReadoutElement::measurementId(const IdentifierHash& measHash) const {
118  return m_idHelper.channelID(identify(), doubletZ(), doubletPhiNumber(measHash) + 1,
119  gasGapNumber(measHash) + 1, measuresPhi(measHash), stripNumber(measHash));
120 }
121 
122 inline Amg::Vector3D RpcReadoutElement::stripPosition(const ActsGeometryContext& ctx, const Identifier& measId) const {
123  return stripPosition(ctx, measurementHash(measId));
124 }
125 inline Amg::Vector3D RpcReadoutElement::rightStripEdge(const ActsGeometryContext& ctx, const Identifier& measId) const{
126  return rightStripEdge(ctx, measurementHash(measId));
127 }
128 inline Amg::Vector3D RpcReadoutElement::leftStripEdge(const ActsGeometryContext& ctx, const Identifier& measId) const{
129  return leftStripEdge(ctx, measurementHash(measId));
130 }
131 } // namespace MuonGMR4
132 #endif