2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
4#ifndef MUONREADOUTGEOMETRYR4_MDTREADOUTELEMENT_ICC
5#define MUONREADOUTGEOMETRYR4_MDTREADOUTELEMENT_ICC
7#include <GaudiKernel/SystemOfUnits.h>
10 template <> inline Amg::Transform3D
11 TransformCacheDetEle<MuonGMR4::MdtReadoutElement>::fetchTransform(const DetectorAlignStore* store) const {
12 using RE = MuonGMR4::MdtReadoutElement;
13 const unsigned layerTube = m_parent->tubeNumber(RE::measurementHash(1, 0));
14 /// Check whether the hash represents a tube or the central layer
15 const unsigned tubeNum = m_parent->tubeNumber(hash());
16 if (tubeNum == layerTube) {
17 const Amg::Translation3D toCenter{0.5*m_parent->moduleHeight() * Amg::Vector3D::UnitY()};
18 return m_parent->toStation(store) * m_parent->toChamberLayer(hash()) *
19 toCenter * Amg::getRotateY3D(90*Gaudi::Units::deg);
21 return m_parent->toStation(store) *
22 m_parent->fromIdealToDeformed(hash(), store) * m_parent->toTubeFrame(hash());
24 template <> inline Identifier
25 TransformCacheDetEle<MuonGMR4::MdtReadoutElement>::identify() const {
26 using RE = MuonGMR4::MdtReadoutElement;
27 const unsigned layerTube = m_parent->tubeNumber(RE::measurementHash(1, 0));
28 /// Check whether the hash represents a tube or the central layer
29 const unsigned tubeNum = m_parent->tubeNumber(hash());
30 if (tubeNum == layerTube) {
31 return m_parent->measurementId(RE::measurementHash(RE::layerNumber(hash()) +1,
32 m_parent->numTubesInLay() +1));
34 return m_parent->measurementId(hash());
39inline unsigned MdtReadoutElement::multilayer() const { return m_stML; }
40inline unsigned MdtReadoutElement::numLayers() const { return m_pars.tubeLayers.size(); }
41inline unsigned MdtReadoutElement::numTubesInLay() const { return m_pars.tubeLayers.empty() ? 0 : m_pars.tubeLayers[0]->nTubes(); }
42inline double MdtReadoutElement::innerTubeRadius() const {return m_pars.tubeInnerRad;}
43inline double MdtReadoutElement::tubeRadius() const {return innerTubeRadius() + m_pars.tubeWall;}
44inline double MdtReadoutElement::tubePitch() const { return m_pars.tubePitch;}
45inline double MdtReadoutElement::thickness() const {return 2.* m_pars.halfHeight;}
46inline double MdtReadoutElement::moduleWidthS() const{ return 2.*m_pars.shortHalfX; }
47inline double MdtReadoutElement::moduleWidthL() const{ return 2.*m_pars.longHalfX; }
48inline double MdtReadoutElement::moduleHeight() const{ return 2.*m_pars.halfY; }
49inline double MdtReadoutElement::moduleThickness() const{ return 2.*m_pars.halfHeight; }
50inline const MdtReadoutElement* MdtReadoutElement::complementaryRE() const { return m_reOtherMl; }
51inline bool MdtReadoutElement::isValid(const IdentifierHash& measHash) const {
52 return layerNumber(measHash) < numLayers() &&
53 tubeNumber(measHash) < numTubesInLay() &&
54 !m_pars.removedTubes.count(measHash);
56inline IdentifierHash MdtReadoutElement::measurementHash(const Identifier& measId) const {
57 if (idHelperSvc()->detElId(measId) != identify()) {
58 ATH_MSG_WARNING("The measurement "
59 << idHelperSvc()->toString(measId)
60 << " picks the wrong readout element "
61 << idHelperSvc()->toStringDetEl(identify()));
63 IdentifierHash hash = measurementHash(m_idHelper.tubeLayer(measId),
64 m_idHelper.tube(measId));
65 ATH_MSG_VERBOSE("Translate measurement identifier "
66 << idHelperSvc()->toString(measId)
67 << " to measurement hash " << static_cast<int>(hash));
70inline IdentifierHash MdtReadoutElement::layerHash(const Identifier& measId) const {
71 return layerHash(measurementHash(measId));
73inline unsigned MdtReadoutElement::tubeNumber(const IdentifierHash& hash) {
74 return (static_cast<unsigned>(hash) >> 3) - 1u;
76/// Transforms the identifier hash into a layer number ranging from
78inline unsigned MdtReadoutElement::layerNumber(const IdentifierHash& hash) {
79 constexpr unsigned layMask = 0b111;
80 return static_cast<unsigned>(hash) & layMask;
82inline IdentifierHash MdtReadoutElement::measurementHash(unsigned layer, unsigned tube) {
84 return IdentifierHash{( tube << 3) | (layer-1)};
86inline IdentifierHash MdtReadoutElement::layerHash(const IdentifierHash& measHash) {
87 return measurementHash(layerNumber(measHash) + 1 , 0);
89inline bool MdtReadoutElement::isBarrel() const { return m_isBarrel; }
92inline Amg::Vector3D MdtReadoutElement::globalTubePos(const ActsTrk::GeometryContext& ctx,
93 const Identifier& measId) const {
94 return globalTubePos(ctx, measurementHash(measId));
96inline Amg::Vector3D MdtReadoutElement::readOutPos(const ActsTrk::GeometryContext& ctx,
97 const Identifier& measId) const{
98 return readOutPos(ctx, measurementHash(measId));
100inline Amg::Vector3D MdtReadoutElement::highVoltPos(const ActsTrk::GeometryContext& ctx,
101 const Identifier& measId) const {
102 return highVoltPos(ctx, measurementHash(measId));
104inline double MdtReadoutElement::distanceToReadout(const ActsTrk::GeometryContext& ctx,
105 const Identifier& measId,
106 const Amg::Vector3D& globPoint) const {
107 return distanceToReadout(ctx,measurementHash(measId), globPoint);
111} // namespace MuonGMR4