ATLAS Offline Software
sTgcReadoutElement.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_STGCREADOUTELEMENT_ICC
5 #define MUONREADOUTGEOMETRYR4_STGCREADOUTELEMENT_ICC
6 
7 
8 namespace ActsTrk{
9  template <> inline Amg::Transform3D
10  TransformCacheDetEle<MuonGMR4::sTgcReadoutElement>::fetchTransform(const DetectorAlignStore* store) const{
11  return m_parent->toStation(store) * m_parent->fromGapToChamOrigin(hash());
12  }
13  template <> inline Identifier
14  TransformCacheDetEle<MuonGMR4::sTgcReadoutElement>::identify() const {
15  using RE = MuonGMR4::sTgcReadoutElement;
16  return m_parent->measurementId(RE::createHash(RE::gasGapNumber(hash()) + 1,
17  RE::chType(hash()), 1));
18  }
19 }
20 
21 
22 namespace MuonGMR4 {
23  namespace sTgcIdMeasHashFields {
24  constexpr unsigned int minusOne = -1;
25  /// Hash field layout
26  //// (wireInGrp) | (channel) [1-512] | IsWireInGrp (0,1) | (sTgcChannelType) [0-2] | (gasGap -1) [1-4]
27  constexpr unsigned int gasGapShift = 0;
28  constexpr unsigned int chTypeShift = 2;
29  constexpr unsigned int wireInGrpBit = chTypeShift+ 2;
30  constexpr unsigned int chanShift = chTypeShift + 3;
31  constexpr unsigned int wireInGrpShift = chanShift + 9;
32  }
33 
34 inline double sTgcReadoutElement::chamberHeight() const { return 2.* m_pars.halfChamberHeight; }
35 inline double sTgcReadoutElement::sChamberLength() const { return 2.* m_pars.sHalfChamberLength; }
36 inline double sTgcReadoutElement::lChamberLength() const { return 2.* m_pars.lHalfChamberLength; }
37 inline double sTgcReadoutElement::thickness() const { return 2.* m_pars.halfChamberTck; }
38 inline double sTgcReadoutElement::sFrameWidth() const { return m_pars.sFrameWidth; }
39 inline double sTgcReadoutElement::lFrameWidth() const { return m_pars.lFrameWidth; }
40 inline int sTgcReadoutElement::multilayer() const { return m_multiLayer; }
41 
42 inline unsigned int sTgcReadoutElement::numLayers() const { return m_pars.numLayers; }
43 inline unsigned int sTgcReadoutElement::nChTypes() const { return m_pars.nChTypes; }
44 inline double sTgcReadoutElement::gasGapThickness() const { return m_pars.gasTck; }
45 inline double sTgcReadoutElement::gasGapPitch() const { return m_gasGapPitch; }
46 
47 inline double sTgcReadoutElement::firstStripPitch(const IdentifierHash& measHash) const { return m_pars.firstStripPitch[gasGapNumber(measHash)]; }
48 inline double sTgcReadoutElement::firstStripPitch(const Identifier& measId) const { return firstStripPitch(measurementHash(measId)); }
49 
50 inline unsigned int sTgcReadoutElement::numChannels(const Identifier& measId) const { return numChannels(measurementHash(measId)); }
51 inline unsigned int sTgcReadoutElement::numChannels(const IdentifierHash& measHash) const {
52  switch (chType(measHash)) {
53  case ReadoutChannelType::Strip:
54  return stripDesign(measHash).numStrips();
55  case ReadoutChannelType::Pad:
56  return padDesign(measHash).numPads();
57  case ReadoutChannelType::Wire:
58  return wireDesign(measHash).numStrips();
59  case ReadoutChannelType::WireInGrp:
60  return wireDesign(measHash).nAllWires();
61  default:
62  ATH_MSG_WARNING("Channel type "<<chType(measHash)<<" is unknown.");
63  }
64  return 0;
65 }
66 
67 inline double sTgcReadoutElement::stripLength(const Identifier& measId) const { return stripLength(measurementHash(measId)); }
68 inline double sTgcReadoutElement::stripLength(const IdentifierHash& measHash) const {
69  return stripDesign(measHash).stripLength(channelNumber(measHash));
70 }
71 
72 inline unsigned int sTgcReadoutElement::numPadEta(const Identifier& measId) const { return numPadEta(measurementHash(measId)); }
73 inline unsigned int sTgcReadoutElement::numPadEta(const IdentifierHash& measHash) const { return padDesign(measHash).numPadEta(); }
74 inline unsigned int sTgcReadoutElement::numPadPhi(const Identifier& measId) const { return numPadPhi(measurementHash(measId)); }
75 inline unsigned int sTgcReadoutElement::numPadPhi(const IdentifierHash& measHash) const { return padDesign(measHash).numPadPhi(); }
76 
77 inline double sTgcReadoutElement::padHeight(const Identifier& measId) const { return padHeight(measurementHash(measId)); }
78 inline double sTgcReadoutElement::padHeight(const IdentifierHash& measHash) const { return (padEta(measHash) == 1) ?
79  padDesign(measHash).firstPadHeight() : padDesign(measHash).padHeight(); }
80 
81 inline double sTgcReadoutElement::padPhiShift(const Identifier& measId) const { return padPhiShift(measurementHash(measId)); }
82 inline double sTgcReadoutElement::padPhiShift(const IdentifierHash& measHash) const { return padDesign(measHash).padPhiShift(); }
83 
84 inline double sTgcReadoutElement::anglePadPhi(const Identifier& measId) const { return anglePadPhi(measurementHash(measId));}
85 inline double sTgcReadoutElement::anglePadPhi(const IdentifierHash& measHash) const { return padDesign(measHash).anglePadPhi(); }
86 
87 inline unsigned int sTgcReadoutElement::maxPadEta(const Identifier& measId) const { return maxPadEta(measurementHash(measId)); }
88 inline unsigned int sTgcReadoutElement::maxPadEta(const IdentifierHash& measHash) const { return padDesign(measHash).anglePadPhi(); }
89 inline unsigned int sTgcReadoutElement::padNumberSeq(const Identifier& measId) const { return padNumberSeq(measurementHash(measId)); }
90 inline unsigned int sTgcReadoutElement::padNumberSeq(const IdentifierHash& measHash) const {
91  int padEta = padEtaPhi(measHash).first;
92  int padPhi = padEtaPhi(measHash).second;
93  int numPadEta = padDesign(measHash).numPadEta();
94  int numPadPhi = padDesign(measHash).numPadPhi();
95  if((padEta > numPadEta) || (padPhi > numPadPhi)) {
96  ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" Pad Channel: "<< idHelperSvc()->toString(measurementId(measHash))
97  << " resulted in invalid (eta, phi): ("<<padEta<< ", " <<padPhi <<"), (maxEta, maxPhi): "<<numPadEta<<", "<<numPadPhi
98  <<"). total pads available: "<<padDesign(measHash).numPads());
99  return 0;
100  }
101  return (padPhi - 1) * numPadEta + padEta;
102 }
103 
104 inline std::pair<uint, uint> sTgcReadoutElement::padEtaPhi(const Identifier& measId) const { return padEtaPhi(measurementHash(measId)); }
105 inline std::pair<uint, uint> sTgcReadoutElement::padEtaPhi(const IdentifierHash& measHash) const { return padDesign(measHash).padEtaPhi(channelNumber(measHash)); }
106 inline unsigned int sTgcReadoutElement::padEta(const Identifier& measId) const { return padEta(measurementHash(measId)); }
107 inline unsigned int sTgcReadoutElement::padEta(const IdentifierHash& measHash) const { return padDesign(measHash).padEta(channelNumber(measHash)); }
108 inline unsigned int sTgcReadoutElement::padPhi(const Identifier& measId) const { return padPhi(measurementHash(measId)); }
109 inline unsigned int sTgcReadoutElement::padPhi(const IdentifierHash& measHash) const { return padDesign(measHash).padPhi(channelNumber(measHash)); }
110 inline double sTgcReadoutElement::beamlineRadius(const Identifier& measId) const { return padDesign(measId).beamlineRadius(); }
111 inline double sTgcReadoutElement::beamlineRadius(const IdentifierHash& measHash) const { return padDesign(measHash).beamlineRadius(); }
112 inline sTgcReadoutElement::localCornerArray sTgcReadoutElement::localPadCorners(const Identifier& measId) const { return localPadCorners(measurementHash(measId)); }
113 inline sTgcReadoutElement::localCornerArray sTgcReadoutElement::localPadCorners(const IdentifierHash& measHash) const { return padDesign(measHash).padCorners(channelNumber(measHash)); }
114 inline sTgcReadoutElement::globalCornerArray
115  sTgcReadoutElement::globalPadCorners(const ActsGeometryContext& ctx, const Identifier& measId) const {
116  return globalPadCorners(ctx, measurementHash(measId));
117 }
118 
119 inline const StripDesign& sTgcReadoutElement::stripDesign(const Identifier& measId) const {
120  return stripDesign(layerHash(measId));
121  }
122 inline const StripDesign& sTgcReadoutElement::stripDesign(const IdentifierHash& measHash) const {
123  return m_pars.stripLayers[gasGapNumber(measHash)].design();
124  }
125 
126 inline const WireGroupDesign& sTgcReadoutElement::wireDesign(const Identifier& measId) const {
127  return wireDesign(measurementHash(measId));
128  }
129 inline const WireGroupDesign& sTgcReadoutElement::wireDesign(const IdentifierHash& measHash) const {
130  return static_cast<const WireGroupDesign&>(m_pars.wireGroupLayers[gasGapNumber(measHash)].design());
131  }
132 inline const PadDesign& sTgcReadoutElement::padDesign(const Identifier& measId) const {
133  return padDesign(measurementHash(measId));
134  }
135 inline const PadDesign& sTgcReadoutElement::padDesign(const IdentifierHash& measHash) const {
136  return static_cast<const PadDesign&>(m_pars.padLayers[gasGapNumber(measHash)].design());
137  }
138 inline IdentifierHash sTgcReadoutElement::measurementHash(const Identifier& measId) const {
139  if (idHelperSvc()->detElId(measId) != identify()) {
140  ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
141  << " picks the wrong readout element " << idHelperSvc()->toStringDetEl(identify()));
142  }
143  return createHash(m_idHelper.gasGap(measId),
144  m_idHelper.channelType(measId),
145  m_idHelper.channel(measId));
146 }
147 inline IdentifierHash sTgcReadoutElement::createHash(const unsigned int gasGap,
148  const unsigned int channelType,
149  const unsigned int channel,
150  const unsigned int wireInGrp) {
151  using namespace sTgcIdMeasHashFields;
152  /// Construct the Hash such that (channel) | WireInGrpBit (0,1) | (channelType) | (gasGap -1)
153  if (channelType == ReadoutChannelType::WireInGrp) {
154  const unsigned int readOutHash = static_cast<unsigned int>(createHash(gasGap, ReadoutChannelType::Wire, channel));
155  return IdentifierHash {wireInGrp << wireInGrpShift | (1<<wireInGrpBit) | readOutHash};
156  }
157  return IdentifierHash{ channel << chanShift | channelType << chTypeShift | (gasGap -1) };
158 }
159 
160 inline IdentifierHash sTgcReadoutElement::layerHash(const IdentifierHash& measHash) {
161  using namespace sTgcIdMeasHashFields;
162  constexpr unsigned int mask = (minusOne << chanShift) | (1<<wireInGrpBit);
163  return IdentifierHash{static_cast<unsigned int>(measHash) & (~mask)};
164 }
165 
166 inline unsigned int sTgcReadoutElement::channelNumber(const IdentifierHash& measHash) {
167  using namespace sTgcIdMeasHashFields;
168  constexpr unsigned int mask = (minusOne << wireInGrpShift);
169  const unsigned int stripedHash = (~mask) & static_cast<unsigned int>(measHash);
170  return stripedHash >> chanShift;
171 }
172 inline unsigned int sTgcReadoutElement::chType(const IdentifierHash& measHash) {
173  using namespace sTgcIdMeasHashFields;
174  constexpr unsigned int mask = (minusOne << chanShift);
175  const unsigned int stripedHash = (~mask) & static_cast<unsigned int>(measHash);
176  return stripedHash >> chTypeShift;
177 
178 }
179 inline unsigned int sTgcReadoutElement::gasGapNumber(const IdentifierHash& measHash) {
180  using namespace sTgcIdMeasHashFields;
181  constexpr unsigned int mask = (minusOne << chTypeShift);
182  return (static_cast<unsigned int>(measHash) &(~mask) );
183 }
184 inline Identifier sTgcReadoutElement::measurementId(const IdentifierHash& measHash) const {
185  return m_idHelper.channelID(identify(), multilayer(), gasGapNumber(measHash) + 1, chType(measHash), channelNumber(measHash));
186 }
187 inline IdentifierHash sTgcReadoutElement::layerHash(const Identifier& measId) const {
188  if (m_idHelper.elementID(measId) != m_idHelper.elementID(identify()) ) {
189  ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
190  << " picks the wrong readout element " << idHelperSvc()->toStringDetEl(identify()));
191  }
192  return createHash(m_idHelper.gasGap(measId), m_idHelper.channelType(measId), 0);
193 }
194 
195 inline Amg::Vector2D sTgcReadoutElement::localChannelPosition(const Identifier& measId) const {
196  return localChannelPosition(measurementHash(measId));
197 }
198 
199 inline Amg::Vector3D sTgcReadoutElement::globalChannelPosition(const ActsGeometryContext& ctx, const Identifier& measId) const {
200  return globalChannelPosition(ctx, measurementHash(measId));
201 }
202 
203 inline const StripLayer& sTgcReadoutElement::stripLayer(const IdentifierHash& measHash) const {
204  unsigned int layIdx = static_cast<unsigned int>(measHash);
205  unsigned int gasGap = gasGapNumber(measHash);
206  if(chType(measHash) == ReadoutChannelType::Strip && gasGap < m_pars.stripLayers.size()) {
207  return m_pars.stripLayers[gasGap];
208  }
209  else if (chType(measHash) == ReadoutChannelType::Wire && gasGap < m_pars.wireGroupLayers.size()) {
210  return m_pars.wireGroupLayers[gasGap];
211  }
212  else if (chType(measHash) == ReadoutChannelType::Pad && gasGap < m_pars.padLayers.size()) {
213  return m_pars.padLayers[gasGap];
214  }
215  else {
216  unsigned int maxReadoutLayers = m_pars.stripLayers.size() + m_pars.wireGroupLayers.size() + m_pars.padLayers.size();
217  ATH_MSG_ERROR(__FILE__<<":"<<__LINE__<<" The layer hash "<<layIdx
218  <<" is out of range. Maximum range "<< maxReadoutLayers);
219  return m_pars.stripLayers[0];
220  }
221 }
222 inline const StripLayer& sTgcReadoutElement::stripLayer(const Identifier& measId) const {
223  return stripLayer(measurementHash(measId));
224 }
225 inline int sTgcReadoutElement::padNumber(const Amg::Vector2D& hitPos, const Identifier& measId) const {
226  return padNumber(hitPos, measurementHash(measId));
227 }
228 
229 } // namespace MuonGMR4
230 #endif