ATLAS Offline Software
Loading...
Searching...
No Matches
MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/sTgcReadoutElement.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
5
7#include <GaudiKernel/SystemOfUnits.h>
8
9#ifndef SIMULATIONBASE
10# include "Acts/Surfaces/TrapezoidBounds.hpp"
11# include "Acts/Surfaces/Surface.hpp"
12#endif
13
14using namespace ActsTrk;
15
16namespace MuonGMR4 {
18std::ostream& operator<<(std::ostream& ostr, const parameterBook& pars) {
19 ostr<<"sTGC parameter halfX (S/L):"<<pars.sHalfChamberLength<<"/"<<pars.lHalfChamberLength
20 <<", halfY: "<<pars.halfChamberHeight<<", thickness: "<<pars.halfChamberTck;
21 return ostr;
22}
28
30
32 ATH_MSG_DEBUG("Parameter book "<<getParameters());
33
35#ifndef SIMULATIONBASE
37 m_pars.layerBounds->makeBounds<Acts::TrapezoidBounds>(m_pars.sHalfChamberLength,
38 m_pars.lHalfChamberLength,
39 m_pars.halfChamberHeight)));
40#endif
41
42 if (m_pars.stripLayers.empty()) {
43 ATH_MSG_FATAL("The readout element "<<idHelperSvc()->toStringDetEl(identify())<<" doesn't have any layers defined");
44 return StatusCode::FAILURE;
45 }
46 for (unsigned layer = 0; layer < m_pars.stripLayers.size(); ++layer) {
47 IdentifierHash layHash{layer};
48 if (gasGapNumber(m_pars.stripLayers[layer].hash()) != layHash) {
49 ATH_MSG_FATAL("Layer "<<m_pars.stripLayers[layer]<<" has a very strange hash. Expect "<<layer);
50 return StatusCode::FAILURE;
51 }
52 ATH_CHECK(insertTransform<sTgcReadoutElement>(m_pars.stripLayers[layer].hash()));
53
54#ifndef SIMULATIONBASE
55 const StripDesign& design{m_pars.stripLayers[layer].design()};
56 ATH_CHECK(planeSurfaceFactory(m_pars.stripLayers[layer].hash(),
57 m_pars.layerBounds->makeBounds<Acts::TrapezoidBounds>(design.shortHalfHeight(),
58 design.longHalfHeight(),
59 design.halfWidth(),
60 90.*Gaudi::Units::deg)));
61#endif
62
63 }
66 return StatusCode::SUCCESS;
67}
68
72
74 switch (chType(measHash)) {
76 Amg::Vector2D stripCenter{Amg::Vector2D::Zero()};
77 const StripDesign& design{stripDesign(measHash)};
78 const int ch = channelNumber(measHash);
79
80 std::optional<Amg::Vector2D> stripCenterOpt = design.center(ch);
81 if (!stripCenterOpt) {
82 ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The strip " << ch << " doesn't intersect with the edges of the trapezoid.");
83 return stripCenter;
84 }
85 ATH_MSG_VERBOSE("Fetch local strip position "<<idHelperSvc()->toString(measurementId(measHash))<<" "
86 <<" "<<Amg::toString(*stripCenterOpt)<<" "<<design);
87 stripCenter = std::move(*stripCenterOpt);
88 if (ch == 1 && firstStripPitch(measHash) < 0.75 * design.stripPitch()) {
89 stripCenter.x() += 0.25 * design.stripWidth();
90 }
91 if (ch == design.numStrips() && firstStripPitch(measHash) > 0.75 * design.stripPitch()) {
92 stripCenter.x() -= 0.25 * design.stripWidth();
93 }
94 return stripCenter;
96 Amg::Vector2D wireGroupCenter{Amg::Vector2D::Zero()};
97 const WireGroupDesign& design{wireDesign(measHash)};
98 const int ch = channelNumber(measHash);
99 std::optional<Amg::Vector2D> wireGroupCenterOpt = design.center(ch);
100 if (!wireGroupCenterOpt) {
101 ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The wireGroup" << ch
102 << "doesn't intersect with the edges of the trapezoid.");
103 return wireGroupCenter;
104 }
105 wireGroupCenter = std::move(*wireGroupCenterOpt);
106 ATH_MSG_VERBOSE("Fetch local wire position "<<idHelperSvc()->toString(measurementId(measHash))<<" "
107 <<" "<<Amg::toString(wireGroupCenter)<<" "<<design);
108 if (ch == 1) {
109 ATH_MSG_DEBUG("The first wiregroup width is " <<design.numWiresInGroup(ch) << " firstWirePos: " << design.firstStripPos());
110 ATH_MSG_DEBUG("The last wire pos is: " << wireGroupCenter.x() + (0.5 * (design.numWiresInGroup(ch) + 1) - 1) * design.stripPitch() );
112 wireGroupCenter.x() = wireGroupCenter.x() + (0.5 * (design.numWiresInGroup(ch) + 1) - 1) * design.stripPitch();
115 wireGroupCenter.x() = 0.5 * (wireGroupCenter.x() - design.longHalfHeight());
116 } else if (ch == design.numStrips()) {
117 ATH_MSG_VERBOSE("The actual center of the last wire group is: " << wireGroupCenter.x());
119 wireGroupCenter.x() = wireGroupCenter.x() - 0.5 * (design.numWiresInGroup(ch) + 1) * design.stripPitch();
120 ATH_MSG_VERBOSE("The last wire of the last second group is at: " << wireGroupCenter.x());
123 wireGroupCenter.x() = 0.5 * (wireGroupCenter.x() + design.longHalfHeight());
124 }
127 return wireGroupCenter;
129 std::optional<Amg::Vector2D> padCenterOpt = padDesign(measHash).stripPosition(channelNumber(measHash));
130 if (!padCenterOpt) {
131 ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The pad" << channelNumber(measHash)
132 << "doesn't is not a valid pad number.");
133 return Amg::Vector2D::Zero();
134 }
135 return padCenterOpt.value();
136 } default:
137 ATH_MSG_FATAL(__FILE__<<":"<<__LINE__<<"Invalid channel type: " << chType(measHash));
138 return Amg::Vector2D::Zero();
139 }
140}
141
143 return stripLayer(measHash).to3D(localChannelPosition(measHash),
144 chType(measHash) != ReadoutChannelType::Strip);
145}
146
151
152using localCornerArray = std::array<Amg::Vector2D, 4>;
153using globalCornerArray = std::array<Amg::Vector3D, 4>;
155 const IdentifierHash& measHash) const {
156 const IdentifierHash lHash = layerHash(measHash);
157 if (chType(measHash) == ReadoutChannelType::Pad && gasGapNumber(measHash) < m_pars.padLayers.size()) {
158 globalCornerArray gPadCorners{make_array<Amg::Vector3D, 4>(Amg::Vector3D::Zero())};
159 const auto& layer = stripLayer(lHash);
160 localCornerArray lPadCorners = localPadCorners(measHash);
161 for (unsigned corner = 0; corner < lPadCorners.size(); ++corner) {
162 gPadCorners[corner] = localToGlobalTransform(ctx, lHash)* layer.to3D(std::move(lPadCorners[corner]), true);
163 }
164 return gPadCorners;
165 }
166 ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<lHash
167 <<" is out of range. Maximum range "<<m_pars.padLayers.size());
168 return make_array<Amg::Vector3D, 4>(Amg::Vector3D::Zero());
169}
170
171int sTgcReadoutElement::padNumber(const Amg::Vector2D& hitPos, const IdentifierHash& measHash) const {
172 const auto& design{padDesign(measHash)};
173 int padEta = design.channelNumber(hitPos).first;
174 int padPhi = design.channelNumber(hitPos).second;
175 const Identifier padID = m_idHelper.padID(identify(), multilayer(), gasGapNumber(measHash) + 1, chType(measHash),
176 padEta, padPhi);
177 return m_idHelper.channel(padID);
178}
179
181 const IdentifierHash lHash = layerHash(measHash);
182 switch (chType(measHash)) {
185 return localToGlobalTransform(ctx, lHash) *
186 stripLayer(measHash).localStripLeftEdge(channelNumber(measHash),
187 chType(measHash) == ReadoutChannelType::Wire);
188 default:
189 break;
190 }
191 ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<lHash
192 <<" is not valid Type "<< chType(measHash));
193 return Amg::Vector3D::Zero();
194
195}
196
197
199 const IdentifierHash lHash = layerHash(measHash);
200 switch (chType(measHash)) {
203 return localToGlobalTransform(ctx, lHash) *
204 stripLayer(measHash).localStripRightEdge(channelNumber(measHash),
205 chType(measHash) == ReadoutChannelType::Wire);
206 default:
207 break;
208 }
209 ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" The layer hash "<<lHash
210 <<" is not valid Type "<< chType(measHash));
211 return Amg::Vector3D::Zero();
212
213
214}
215
217 if(std::abs(stationEta()) != 1 ) {
218 return false; // if we are not in a Q1 ro element we do not have to check further
219 }
220 const WireGroupDesign& design = wireDesign(measurementHash); // function is not checking for channel type so we just use its gas gap info
221 return localPosition.x() < design.halfWidth() - design.wireCutout();
222}
223
224
225} // namespace MuonGMR4
Scalar mag() const
mag method
constexpr std::array< T, N > make_array(const T &def_val)
Helper function to initialize in-place arrays with non-zero values.
Definition ArrayHelper.h:10
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This is a "hash" representation of an Identifier.
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the local coordinate system of the readout element into the global AT...
int stationEta() const
Returns the stationEta (positive A site, negative C site)
StatusCode planeSurfaceFactory(const IdentifierHash &hash, std::shared_ptr< const Acts::PlanarBounds > pBounds)
Invokes the factory to create plane surfaces && to associate them with the particular transform cache...
Identifier identify() const override final
Return the ATLAS identifier.
const Muon::IMuonIdHelperSvc * idHelperSvc() const
Returns the pointer to the muonIdHelperSvc.
StatusCode createGeoTransform()
Creates the TransformCacheDetEle corresponding the generic local -> global transformation of the read...
StatusCode insertTransform(const IdentifierHash &hash)
Constructs the TransformDetEleCache associated with the hash of the given Mdt tube or strip layer.
MuonReadoutElement(const defineArgs &args)
Constructor taking the basic define arguments.
static IdentifierHash geoTransformHash()
Returns the hash that is associated with the surface cache holding the transformation that is placing...
Amg::Vector2D stripPosition(int stripNum) const override final
Override from stripDesign. This function will give the center of the pad by taking the sequential cha...
double halfWidth() const
Returns the half height of the strip panel.
CheckVector2D center(int stripNumb) const
Returns the bisector of the strip (Global numbering scheme)
const Amg::Vector2D & firstStripPos() const
Vector indicating the first strip position.
double stripPitch() const
Distance between two adjacent strips.
double stripWidth() const
Width of a strip.
double shortHalfHeight() const
Returns the shorter half height of the panel.
double longHalfHeight() const
Returns the longer half height of the panel.
virtual int numStrips() const
Number of strips on the panel.
Amg::Vector3D localStripRightEdge(unsigned int stripNum, bool phiView=false) const
Returns the position of the right strip edge at (negative y in the strip design description) in the l...
Amg::Vector3D to3D(CheckVector2D &&vec, const bool phiView) const
Transforms the 2D vector from the strip design into a 3D vector If phi view is switched on,...
const Amg::Transform3D & toOrigin() const
Returns the transformation to go from the strip layer center to the origin of the Strip chamber.
Amg::Vector3D localStripLeftEdge(unsigned int stripNum, bool phiView=false) const
Returns the position of the strip edge at (positive y in the strip design description) in the local c...
unsigned int numWiresInGroup(unsigned int groupNum) const
Returns the number of wires in a given group.
double wireCutout() const
Extract the wireCutout for a wireGroup layer.
IdentifierHash measurementHash(const Identifier &measId) const override final
Constructs the identifier hash from the full measurement Identifier.
const PadDesign & padDesign(const IdentifierHash &measHash) const
Retrieves the readoutElement Layer given the Identifier/Hash.
Amg::Vector3D leftStripEdge(const ActsTrk::GeometryContext &ctx, const IdentifierHash &measHash) const
static unsigned gasGapNumber(const IdentifierHash &measHash)
Returns the gasGap (0 to 3) for a given identifierHash.
unsigned padEta(const IdentifierHash &measHash) const
Returns the Eta index of the pad for the given pad identifier.
double firstStripPitch(const IdentifierHash &measHash) const
Gas Gaps.
int multilayer() const
Returns the multilayer of the sTgcReadoutElement.
StatusCode initElement() override final
Initialization of the readout elements.
localCornerArray localPadCorners(const IdentifierHash &measHash) const
std::array< Amg::Vector3D, 4 > globalCornerArray
Returns an array of four 3D vectors representing corner positions of the pads.
std::array< Amg::Vector2D, 4 > localCornerArray
Returns an array of four 2D vectors representing corner positions of the pads.
Identifier measurementId(const IdentifierHash &measHash) const override final
Converts the measurement hash back to the full Identifier.
int padNumber(const Amg::Vector2D &hitPos, const IdentifierHash &measHash) const
Returns the pad Number given local position of hit and Identifier/Hash.
Amg::Vector3D rightStripEdge(const ActsTrk::GeometryContext &ctx, const IdentifierHash &measHash) const
const StripDesign & stripDesign(const IdentifierHash &measHash) const
Retrieves the readoutElement Layer given the Identifier/Hash.
globalCornerArray globalPadCorners(const ActsTrk::GeometryContext &ctx, const IdentifierHash &measHash) const
bool isEtaZero(const IdentifierHash &measurementHash, const Amg::Vector2D &localPosition) const
IdentifierHash layerHash(const Identifier &measId) const override final
Transforms the Identifier into a layer hash.
unsigned padPhi(const IdentifierHash &measHash) const
Returns the Phi index of the pad for the given pad identifier.
Amg::Vector3D localPosition(const IdentifierHash &measHash) const
Returns the local position in the local gasGap frame.
static unsigned channelNumber(const IdentifierHash &measHash)
Returns channel position for a given identifierHash.
Amg::Transform3D fromGapToChamOrigin(const IdentifierHash &layerHash) const
Returns the transform to go from the gasGap -> chamber origin.
Amg::Vector3D globalChannelPosition(const ActsTrk::GeometryContext &ctx, const IdentifierHash &measHash) const
Returns the global pad/strip/wireGroup position.
Amg::Vector2D localChannelPosition(const IdentifierHash &measHash) const
Returns the local position of the measurement in the repsective frame.
const WireGroupDesign & wireDesign(const IdentifierHash &measHash) const
Retrieves the readoutElement Layer given the Identifier/Hash.
static IdentifierHash createHash(const unsigned gasGap, const unsigned channelType, const unsigned channel, const unsigned wireInGrp=0)
Create a measurement hash from the Identifier fields.
const StripLayer & stripLayer(const IdentifierHash &measId) const
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
std::ostream & operator<<(std::ostream &ostr, const Chamber::defineArgs &args)
Definition Chamber.cxx:14
std::string toString(const MuonGMR4::MuonReadoutElement *re)
MmReadoutElement::parameterBook parameterBook
STL namespace.