ATLAS Offline Software
Loading...
Searching...
No Matches
MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/src/GeoModelMmTest.cxx
Go to the documentation of this file.
1
2/*
3 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4*/
5#include "GeoModelMmTest.h"
9#include <fstream>
10
11using namespace ActsTrk;
12
13namespace MuonGMR4{
14
16 ATH_CHECK(m_idHelperSvc.retrieve());
17 ATH_CHECK(m_geoCtxKey.initialize());
19 ATH_CHECK(m_tree.init(this));
20
21 const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
22
23 auto translateTokenList = [this, &idHelper](const std::vector<std::string>& chNames){
24
25 std::set<Identifier> transcriptedIds{};
26 for (const std::string& token : chNames) {
27 if (token.size() != 6) {
28 ATH_MSG_WARNING("Wrong format given for "<<token<<". Expecting 6 characters");
29 continue;
30 }
32 const std::string statName = token.substr(0, 3);
33 const unsigned statEta = std::atoi(token.substr(3, 1).c_str()) * (token[4] == 'A' ? 1 : -1);
34 const unsigned statPhi = std::atoi(token.substr(5, 1).c_str());
35 bool isValid{false};
36 const Identifier eleId = idHelper.elementID(statName, statEta, statPhi, isValid);
37 if (!isValid) {
38 ATH_MSG_WARNING("Failed to deduce a station name for " << token);
39 continue;
40 }
41 transcriptedIds.insert(eleId);
42 const Identifier secMlId = idHelper.multilayerID(eleId, 2, isValid);
43 if (isValid){
44 transcriptedIds.insert(secMlId);
45 }
46 }
47 return transcriptedIds;
48 };
49
50 std::vector <std::string>& selectedSt = m_selectStat.value();
51 const std::vector <std::string>& excludedSt = m_excludeStat.value();
52 selectedSt.erase(std::remove_if(selectedSt.begin(), selectedSt.end(),
53 [&excludedSt](const std::string& token){
54 return std::ranges::find(excludedSt, token) != excludedSt.end();
55 }), selectedSt.end());
56
57 if (selectedSt.size()) {
58 m_testStations = translateTokenList(selectedSt);
59 std::stringstream sstr{};
60 for (const Identifier& id : m_testStations) {
61 sstr<<" *** "<<m_idHelperSvc->toString(id)<<std::endl;
62 }
63 ATH_MSG_INFO("Test only the following stations "<<std::endl<<sstr.str());
64 } else {
65 const std::set<Identifier> excluded = translateTokenList(excludedSt);
67 for(auto itr = idHelper.detectorElement_begin();
68 itr!= idHelper.detectorElement_end();++itr){
69 if (!excluded.count(*itr)) {
70 m_testStations.insert(*itr);
71 }
72 }
74 if (!excluded.empty()) {
75 std::stringstream excluded_report{};
76 for (const Identifier& id : excluded){
77 excluded_report << " *** " << m_idHelperSvc->toStringDetEl(id) << std::endl;
78 }
79 ATH_MSG_INFO("Test all station except the following excluded ones " << std::endl << excluded_report.str());
80 }
81 }
82 ATH_CHECK(detStore()->retrieve(m_detMgr));
83 return StatusCode::SUCCESS;
84}
86 ATH_CHECK(m_tree.write());
87 return StatusCode::SUCCESS;
88}
89StatusCode GeoModelMmTest::execute(const EventContext& ctx) {
90 const ActsTrk::GeometryContext* geoContextHandle{nullptr};
91 ATH_CHECK(SG::get(geoContextHandle, m_geoCtxKey, ctx));
92 const ActsTrk::GeometryContext& gctx{*geoContextHandle};
93
94 for (const Identifier& test_me : m_testStations) {
95 ATH_MSG_DEBUG("Test retrieval of Mm detector element "<<m_idHelperSvc->toStringDetEl(test_me));
96 const MmReadoutElement* reElement = m_detMgr->getMmReadoutElement(test_me);
97 if (!reElement) {
98 continue;
99 }
101 if (reElement->identify() != test_me) {
102 ATH_MSG_FATAL("Expected to retrieve "<<m_idHelperSvc->toStringDetEl(test_me)
103 <<". But got instead "<<m_idHelperSvc->toStringDetEl(reElement->identify()));
104 return StatusCode::FAILURE;
105 }
106 const Amg::Transform3D globToLocal{reElement->globalToLocalTransform(gctx)};
107 const Amg::Transform3D& localToGlob{reElement->localToGlobalTransform(gctx)};
109 if (!Amg::doesNotDeform(globToLocal * localToGlob)) {
110 ATH_MSG_FATAL("Closure test failed for "<<m_idHelperSvc->toStringDetEl(test_me)
111 <<" "<<Amg::toString(globToLocal * localToGlob));
112 return StatusCode::FAILURE;
113 }
114 const MmIdHelper& id_helper{m_idHelperSvc->mmIdHelper()};
115 for (unsigned int layer = 1; layer <= reElement->nGasGaps(); ++layer) {
117 const int numStrips = reElement->numStrips(layerHash);
118 const int fStrip = reElement->firstStrip(layerHash);
119 const int lStrip = fStrip+numStrips-1;
120
121 for (int strip = fStrip; strip < lStrip; ++strip) {
122 bool isValid{false};
123
124 const Identifier chId = id_helper.channelID(reElement->identify(),
125 reElement->multilayer(),
126 layer, strip, isValid);
127 if (!isValid) {
128 continue;
129 }
130
132 const IdentifierHash channelHash = reElement->measurementHash(chId);
133 const IdentifierHash layHash = reElement->layerHash(chId);
134 const Identifier backCnv = reElement->measurementId(channelHash);
135 if (backCnv != chId) {
136 ATH_MSG_FATAL("The back and forth conversion of "<<m_idHelperSvc->toString(chId)
137 <<" failed. Got "<<m_idHelperSvc->toString(backCnv));
138 return StatusCode::FAILURE;
139 }
140 if (layHash != reElement->layerHash(channelHash)) {
141 ATH_MSG_FATAL("Constructing the layer hash from the identifier "<<
142 m_idHelperSvc->toString(chId)<<" leads to different layer hashes "<<
143 layHash<<" vs. "<< reElement->layerHash(channelHash));
144 return StatusCode::FAILURE;
145 }
146 const MuonGMR4::StripDesign& design{reElement->stripLayer(layHash).design()};
147 const Amg::Vector3D stripPos = reElement->stripPosition(gctx, channelHash);
148 const Amg::Vector3D locStripPos = reElement->globalToLocalTransform(gctx, layHash) * stripPos;
149 const Amg::Vector2D stripPos2D{locStripPos.block<2,1>(0,0)};
150 const double stripLen{design.stripLength(strip)};
151 if (stripLen && (design.stripNumber(stripPos2D) != strip ||
152 design.stripNumber(stripPos2D - 0.49 * stripLen * Amg::Vector2D::UnitY()) != strip ||
153 design.stripNumber(stripPos2D + 0.49 * stripLen * Amg::Vector2D::UnitY()) != strip)) {
154 ATH_MSG_FATAL("Conversion channel -> strip -> channel failed for "
155 <<m_idHelperSvc->toString(chId)<<" "<<Amg::toString(stripPos)<<", local: "
156 <<Amg::toString(locStripPos)<<" got "<<design.stripNumber(stripPos2D)
157 <<", first strip: "<<fStrip<<std::endl<<design);
158 return StatusCode::FAILURE;
159 }
160 ATH_MSG_VERBOSE("first strip "<<fStrip<<", numStrips "<< numStrips << ", channel "
161 << m_idHelperSvc->toString(chId) <<", strip position " << Amg::toString(stripPos));
162 }
163 }
164 ATH_CHECK(dumpToTree(ctx,gctx,reElement));
165 }
166
167 return StatusCode::SUCCESS;
168}
169StatusCode GeoModelMmTest::dumpToTree(const EventContext& ctx,
170 const ActsTrk::GeometryContext& gctx,
171 const MmReadoutElement* reElement) {
172
173
174
175 m_stIndex = reElement->stationName();
176 m_stEta = reElement->stationEta();
177 m_stPhi = reElement->stationPhi();
178 m_stML = reElement->multilayer();
179 m_chamberDesign = reElement->chamberDesign();
183 const Amg::Transform3D& transform{reElement->localToGlobalTransform(gctx)};
184 m_readoutTransform = transform;
185 m_alignableNode = reElement->alignableTransform()->getDefTransform();
186
188 m_moduleHeight = reElement->moduleHeight();
189 m_moduleWidthS = reElement->moduleWidthS();
190 m_moduleWidthL = reElement->moduleWidthL();
191
192 const MmIdHelper& id_helper{m_idHelperSvc->mmIdHelper()};
193 for (unsigned int layer = 1; layer <= reElement->nGasGaps(); ++layer) {
194
196 unsigned int numStrips = reElement->numStrips(layHash);
197 unsigned int fStrip = reElement->firstStrip(layHash);
198 unsigned int lStrip = fStrip+numStrips-1;
199
200 for (unsigned int strip = fStrip; strip <= lStrip ; ++strip) {
201 bool isValid{false};
202 const Identifier chId = id_helper.channelID(reElement->identify(),
203 reElement->multilayer(),
204 layer, strip, isValid);
205 if (!isValid) {
206 ATH_MSG_WARNING("Invalid Identifier detected for readout element "
207 <<m_idHelperSvc->toStringDetEl(reElement->identify())
208 <<" layer: "<<layer<<" strip: "<<strip);
209 continue;
210 }
211 const IdentifierHash measHash{reElement->measurementHash(chId)};
212
213 const MuonGMR4::StripDesign& design{reElement->stripLayer(measHash).design()};
214 if (strip == fStrip) {
215 const Amg::Transform3D stripLocalToGlob = reElement->localToGlobalTransform(gctx, chId);
216 ATH_MSG_VERBOSE(m_idHelperSvc->toStringGasGap(chId)<<" "<< "transform: "
217 << Amg::toString(stripLocalToGlob)<<", perp: "<<stripLocalToGlob.translation().perp());
218 m_stripRot.push_back(stripLocalToGlob);
219 m_stripRotGasGap.push_back(layer);
220 m_firstStripPos.push_back(design.firstStripPos());
221 m_readoutSide.push_back(reElement->readoutSide(measHash));
222
223 m_ActiveWidthS = reElement->gapLengthS(measHash);
224 m_ActiveWidthL = reElement->gapLengthL(measHash);
225 m_ActiveHeightR = reElement->gapHeight(measHash);
226 m_firstStrip.push_back(design.firstStripNumber());
227 m_nStrips.push_back(design.numStrips());
228 }
229 CheckVector2D center = design.center(strip);
230 if (!center) {
231 ATH_MSG_WARNING("Strip "<<m_idHelperSvc->toString(chId)<<" is outside bounds "<<design);
232 continue;
233 }
234 m_stripLength.push_back(reElement->stripLength(measHash));
235 m_locStripCenter.push_back(center.value());
236 m_isStereo.push_back(design.hasStereoAngle());
237 m_stripCenter.push_back(reElement->stripPosition(gctx, measHash));
238 m_stripLeftEdge.push_back(reElement->leftStripEdge(gctx,measHash));
239 m_stripRightEdge.push_back(reElement->rightStripEdge(gctx,measHash));
240 m_gasGap.push_back(layer);
241 m_channel.push_back(strip);
242 }
243 }
244 return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
245}
246
247}
248
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
const ServiceHandle< StoreGateSvc > & detStore() const
This is a "hash" representation of an Identifier.
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channel) const
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Identifier multilayerID(const Identifier &channeldID) const
MuonVal::ScalarBranch< unsigned short > & m_stIndex
Identifier of the readout element.
Gaudi::Property< std::vector< std::string > > m_selectStat
String should be formated like MM_<Large/Small Sector + Module type><Quadruplet number>.
MuonVal::CoordSystemsBranch m_stripRot
Rotation matrix of the respective strip layers.
StatusCode execute(const EventContext &ctx) override
Execute method.
MuonVal::ScalarBranch< float > & m_ActiveHeightR
GasGap Lengths for debug.
std::set< Identifier > m_testStations
Set of stations to be tested.
MuonVal::ScalarBranch< float > & m_moduleHeight
Chamber Length for debug.
MuonVal::CoordTransformBranch m_readoutTransform
Transformation of the readout element (Translation, ColX, ColY, ColZ).
StatusCode dumpToTree(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const MmReadoutElement *readoutEle)
double moduleHeight() const
Returns the height along the z-axis.
const StripLayer & stripLayer(const Identifier &measId) const
double gapLengthS(const IdentifierHash &layerHash) const
Length of gas Gap on short side.
IdentifierHash measurementHash(const Identifier &measId) const override final
Constructs the identifier hash from the full measurement Identifier.
unsigned int nGasGaps() const
Returns the number of gas gaps.
unsigned int numStrips(const IdentifierHash &layerHash) const
Returns the number of total active strips.
int multilayer() const
Returns the multi layer of the element [1-2].
Identifier measurementId(const IdentifierHash &measHash) const override final
Back conversion of the measurement hash to a full Athena Identifier The behaviour is undefined if a l...
IdentifierHash layerHash(const Identifier &measId) const override final
The layer hash removes the bits from the IdentifierHash corresponding to the measurement's channel nu...
Amg::Vector3D leftStripEdge(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the global position of the strip edge.
double moduleWidthL() const
Returns the width at the top edge.
double moduleWidthS() const
Returns the width at the short edge.
int readoutSide(const IdentifierHash &measHash) const
Returns the readout side.
double gapLengthL(const IdentifierHash &layerHash) const
Length of gas Gap on long side.
double stripLength(const IdentifierHash &measHash) const
Returns the strip length.
unsigned int firstStrip(const IdentifierHash &layerHash) const
Returns the first active strip.
double gapHeight(const IdentifierHash &layerHash) const
Height of gas Gap.
Amg::Vector3D stripPosition(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the position of the strip center.
Amg::Vector3D rightStripEdge(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the global position of the strip edge.
static IdentifierHash createHash(const int gasGap, const int strip)
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).
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the global ATLAS coordinate system into the local coordinate system o...
const std::string & chamberDesign() const
The chamber design refers to the construction parameters of a readout element.
Identifier identify() const override final
Return the ATLAS identifier.
int stationName() const
Returns the stationName (BIS, BOS, etc) encoded into the integer.
int stationPhi() const
Returns the stationPhi (1-8) -> sector (2*phi - (isSmall)).
const GeoAlignableTransform * alignableTransform() const
Return the alignable transform node of the readout element.
int firstStripNumber() const
Returns the number of the first strip.
CheckVector2D center(int stripNumb) const
Returns the bisector of the strip (Global numbering scheme).
virtual double stripLength(int stripNumb) const
Returns length of the strip.
const Amg::Vector2D & firstStripPos() const
Vector indicating the first strip position.
double stripPitch() const
Distance between two adjacent strips.
virtual int stripNumber(const Amg::Vector2D &pos) const
Calculates the number of the strip whose center is closest to the given point.
bool hasStereoAngle() const
Returns whether a stereo angle is defined.
virtual int numStrips() const
Number of strips on the panel.
const StripDesign & design(bool phiView=false) const
Returns the underlying strip design.
const_id_iterator detectorElement_begin() const
Iterators over full set of ids.
const_id_iterator detectorElement_end() 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.
bool doesNotDeform(const Amg::Transform3D &trans)
Checks whether the linear part of the transformation rotates or stetches any of the basis vectors.
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...
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.