ATLAS Offline Software
MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/TgcReadoutElement.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #ifndef MUONREADOUTGEOMETRYR4_TGCREADOUTELEMENT_ICC
5 #define MUONREADOUTGEOMETRYR4_TGCREADOUTELEMENT_ICC
6 
7 
8 namespace ActsTrk{
9  template <> inline Amg::Transform3D
10  TransformCacheDetEle<MuonGMR4::TgcReadoutElement>::fetchTransform(const DetectorAlignStore* store) const{
11  return m_parent->toStation(store) * m_parent->fromGapToChamOrigin(hash());
12  }
13  template <> inline Identifier
14  TransformCacheDetEle<MuonGMR4::TgcReadoutElement>::identify() const {
15  using RE = MuonGMR4::TgcReadoutElement;
16  return m_parent->measurementId(RE::constructHash(1, RE::gasGapNumber(hash()), RE::isStrip(hash())));
17  }
18 }
19 
20 namespace MuonGMR4 {
21  inline double TgcReadoutElement::moduleWidthS() const { return 2.*m_pars.halfWidthShort; }
22  inline double TgcReadoutElement::moduleWidthL() const { return 2.*m_pars.halfWidthLong; }
23  inline double TgcReadoutElement::moduleHeight() const { return 2.*m_pars.halfHeight; }
24  inline double TgcReadoutElement::moduleThickness() const { return 2.*m_pars.halfThickness; }
25  inline double TgcReadoutElement::thickness() const { return moduleThickness(); }
26  inline double TgcReadoutElement::gasGapPitch() const {return m_gasThickness; }
27 
28  inline IdentifierHash TgcReadoutElement::constructHash(unsigned measCh,
29  unsigned gasGap,
30  const bool isStrip) {
31  /// Bit mask layout (measurment channel) | (gasGap [1-3]) | isStrip
32  constexpr unsigned gapShift = 1;
33  constexpr unsigned chanShift = 2 + gapShift;
34  assert(gasGap > 0);
35  return IdentifierHash{measCh << chanShift | (gasGap -1) << gapShift | isStrip};
36  }
37  inline IdentifierHash TgcReadoutElement::measurementHash(const Identifier& measId) const {
38  if (m_idHelper.elementID(measId) != m_idHelper.elementID(identify())) {
39  ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
40  << " picks the wrong readout element " << idHelperSvc()->toStringDetEl(identify()));
41  }
42  return constructHash(m_idHelper.channel(measId), m_idHelper.gasGap(measId), m_idHelper.isStrip(measId));
43  }
44  inline IdentifierHash TgcReadoutElement::layerHash(const Identifier& measId) const {
45  if (m_idHelper.elementID(measId) != m_idHelper.elementID(identify()) ) {
46  ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
47  << " picks the wrong readout element " << idHelperSvc()->toStringDetEl(identify()));
48  }
49  return constructHash(0, m_idHelper.gasGap(measId), m_idHelper.isStrip(measId));
50  }
51  inline IdentifierHash TgcReadoutElement::layerHash(const IdentifierHash& measHash) const {
52  return constructHash(0, gasGapNumber(measHash), isStrip(measHash));
53  }
54  inline unsigned TgcReadoutElement::channelNumber(const IdentifierHash& measHash) {
55  constexpr unsigned chanShift = 3;
56  return static_cast<unsigned>(measHash) >> chanShift;
57  }
58  inline unsigned TgcReadoutElement::gasGapNumber(const IdentifierHash& measHash) {
59  /// The hash is (0/1/2/ | 0/1) -> 3 bits for the gasgap + 1 bit strip
60  constexpr unsigned gapMask{(1<<1) | 1};
61  constexpr unsigned stripBit{1};
62  unsigned unstripped = static_cast<unsigned>(measHash) >> stripBit;
63  return (unstripped & gapMask) + 1;
64  }
65  inline bool TgcReadoutElement::isStrip(const IdentifierHash& measHash) {
66  constexpr unsigned stripBit{1};
67  return static_cast<unsigned>(measHash) & stripBit;
68  }
69  inline Identifier TgcReadoutElement::measurementId(const IdentifierHash& measHash) const {
70  return m_idHelper.channelID(identify(),
71  gasGapNumber(measHash),
72  isStrip(measHash),
73  channelNumber(measHash));
74  }
75  inline unsigned TgcReadoutElement::nGasGaps() const { return m_pars.nGasGaps; }
76 
77  inline unsigned TgcReadoutElement::numChannels(const IdentifierHash& measHash) const {
78  return isStrip(measHash) ? numStrips(measHash) : numWireGangs(measHash);
79  }
80  inline unsigned TgcReadoutElement::numStrips(const IdentifierHash& measHash) const {
81  const StripLayerPtr& sensor{sensorLayout(flipIsStrip(measHash, true))};
82  return sensor && (sensor->hasPhiDesign() || isStrip(sensor->hash())) ? sensor->design(true).numStrips() : 0;
83  }
84  inline IdentifierHash TgcReadoutElement::flipIsStrip(const IdentifierHash& meashHash,
85  const bool isStrip) {
86  return constructHash(channelNumber(meashHash), gasGapNumber(meashHash), isStrip);
87  }
88  inline unsigned TgcReadoutElement::numWireGangs(const IdentifierHash& measHash) const {
89  const StripLayerPtr& sensor{sensorLayout(flipIsStrip(measHash, false))};
90  if (!sensor) {
91  THROW_EXCEPTION("Arsch : gasGap"<<gasGapNumber(measHash)<<", "<<isStrip(measHash));
92  }
93  return sensor && !isStrip(sensor->hash()) ? sensor->design().numStrips() : 0;
94  }
95  inline const StripLayerPtr& TgcReadoutElement::sensorLayout(const IdentifierHash& measHash) const {
96  return m_pars.sensorLayouts.at(layerHash(measHash));
97  }
98  inline const WireGroupDesign& TgcReadoutElement::wireGangLayout(const IdentifierHash& measHash) const {
99  const StripLayerPtr& layerPtr = sensorLayout(flipIsStrip(measHash, false));
100  if (!layerPtr || isStrip(layerPtr->hash())) {
101  THROW_EXCEPTION(" Gas gap "<<gasGapNumber(measHash)<<" has no wire gangs in "<<idHelperSvc()->toStringDetEl(identify()));
102  }
103  return static_cast<const WireGroupDesign&>(layerPtr->design());
104  }
105  inline const RadialStripDesign& TgcReadoutElement::stripLayout(const IdentifierHash& measHash) const {
106  const StripLayerPtr& layerPtr = sensorLayout(flipIsStrip(measHash, true));
107  if (!layerPtr || !(layerPtr->hasPhiDesign() || isStrip(layerPtr->hash()))) {
108  THROW_EXCEPTION(" Gas gap "<<gasGapNumber(measHash)<<" has no strips in "<<idHelperSvc()->toStringDetEl(identify()));
109  }
110  return static_cast<const RadialStripDesign&>(layerPtr->design(true));
111  }
112  inline Amg::Vector3D TgcReadoutElement::channelPosition(const ActsGeometryContext& ctx, const Identifier& measId) const {
113  return channelPosition(ctx, measurementHash(measId));
114  }
115 } // namespace MuonGMR4
116 #endif