2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4 #ifndef MUONREADOUTGEOMETRYR4_TGCREADOUTELEMENT_ICC
5 #define MUONREADOUTGEOMETRYR4_TGCREADOUTELEMENT_ICC
9 template <> inline Amg::Transform3D
10 TransformCacheDetEle<MuonGMR4::TgcReadoutElement>::fetchTransform(const DetectorAlignStore* store) const{
11 return m_parent->toStation(store) * m_parent->fromGapToChamOrigin(hash());
16 inline double TgcReadoutElement::moduleWidthS() const { return 2.*m_pars.halfWidthShort; }
17 inline double TgcReadoutElement::moduleWidthL() const { return 2.*m_pars.halfWidthLong; }
18 inline double TgcReadoutElement::moduleHeight() const { return 2.*m_pars.halfHeight; }
19 inline double TgcReadoutElement::moduleThickness() const { return 2.*m_pars.halfThickness; }
20 inline double TgcReadoutElement::thickness() const { return moduleThickness(); }
21 inline double TgcReadoutElement::gasGapPitch() const {return m_gasThickness; }
23 inline IdentifierHash TgcReadoutElement::constructHash(unsigned int measCh,
26 /// Bit mask layout (measurment channel) | (gasGap [1-3]) | isStrip
27 constexpr unsigned gapShift = 1;
28 constexpr unsigned chanShift = 2 + gapShift;
29 return IdentifierHash{measCh << chanShift | (gasGap -1) << gapShift | isStrip};
31 inline IdentifierHash TgcReadoutElement::measurementHash(const Identifier& measId) const {
32 if (m_idHelper.elementID(measId) != m_idHelper.elementID(identify())) {
33 ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
34 << " picks the wrong readout element " << idHelperSvc()->toStringDetEl(identify()));
36 return constructHash(m_idHelper.channel(measId),
37 m_idHelper.gasGap(measId),
38 m_idHelper.isStrip(measId));
40 inline IdentifierHash TgcReadoutElement::layerHash(const Identifier& measId) const {
41 if (m_idHelper.elementID(measId) != m_idHelper.elementID(identify()) ) {
42 ATH_MSG_WARNING("The measurement " << idHelperSvc()->toString(measId)
43 << " picks the wrong readout element " << idHelperSvc()->toStringDetEl(identify()));
45 return constructHash(0, m_idHelper.gasGap(measId),
46 m_idHelper.isStrip(measId));
48 inline IdentifierHash TgcReadoutElement::layerHash(const IdentifierHash& measHash) const {
49 constexpr unsigned gapStripMask{(1<<2) | (1<<1) | 1};
50 return IdentifierHash{static_cast<unsigned int>(measHash) & gapStripMask};
52 inline unsigned int TgcReadoutElement::channelNumber(const IdentifierHash& measHash) {
53 constexpr unsigned int chanShift = 3;
54 return static_cast<unsigned>(measHash) >> chanShift;
56 inline unsigned int TgcReadoutElement::gasGapNumber(const IdentifierHash& measHash) {
57 /// The hash is (0/1/2/ | 0/1) -> 3 bits for the gasgap + 1 bit strip
58 constexpr unsigned gapMask{(1<<1) | 1};
59 constexpr unsigned stripBit{1};
60 unsigned int unstripped = static_cast<unsigned>(measHash) >> stripBit;
61 return (unstripped & gapMask) + 1;
63 inline bool TgcReadoutElement::isStrip(const IdentifierHash& measHash) {
64 constexpr unsigned stripBit{1};
65 return static_cast<unsigned>(measHash) & stripBit;
68 inline Identifier TgcReadoutElement::measurementId(const IdentifierHash& measHash) const {
69 return m_idHelper.channelID(identify(),
70 gasGapNumber(measHash),
72 channelNumber(measHash));
74 inline unsigned int TgcReadoutElement::nGasGaps() const { return m_pars.nGasGaps; }
76 inline unsigned int TgcReadoutElement::numChannels(const IdentifierHash& measHash) const {
77 return isStrip(measHash) ? numStrips(gasGapNumber(measHash))
78 : numWireGangs(gasGapNumber(measHash));
80 inline unsigned int TgcReadoutElement::numStrips(unsigned int gasGap) const {
81 const StripLayerPtr& sensor{sensorLayout(constructHash(0, gasGap, true))};
82 return sensor ? sensor->design().numStrips() : 0;
84 inline unsigned int TgcReadoutElement::numWireGangs(unsigned int gasGap) const {
85 const StripLayerPtr& sensor{sensorLayout(constructHash(0, gasGap, false))};
86 return sensor ? sensor->design().numStrips() : 0;
88 inline const StripLayerPtr& TgcReadoutElement::sensorLayout(const IdentifierHash& measHash) const {
89 return m_pars.sensorLayouts.at(layerHash(measHash));
91 inline const WireGroupDesign& TgcReadoutElement::wireGangLayout(unsigned int gasGap) const {
92 const StripLayerPtr& layerPtr = sensorLayout(constructHash(0, gasGap, false));
94 THROW_EXCEPTION(" Gas gap "<<gasGap<<" has no wire gangs in "<<idHelperSvc()->toStringDetEl(identify()));
96 return static_cast<const WireGroupDesign&>(layerPtr->design());
98 inline const RadialStripDesign& TgcReadoutElement::stripLayout(unsigned int gasGap) const {
99 const StripLayerPtr& layerPtr = sensorLayout(constructHash(0, gasGap, true));
101 THROW_EXCEPTION(" Gas gap "<<gasGap<<" has no strips in "<<idHelperSvc()->toStringDetEl(identify()));
103 return static_cast<const RadialStripDesign&>(layerPtr->design());
105 inline Amg::Vector3D TgcReadoutElement::channelPosition(const ActsGeometryContext& ctx, const Identifier& measId) const {
106 return channelPosition(ctx, measurementHash(measId));
109 } // namespace MuonGMR4