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}
90 const EventContext& ctx{Gaudi::Hive::currentContext()};
91 const ActsTrk::GeometryContext* geoContextHandle{nullptr};
92 ATH_CHECK(SG::get(geoContextHandle, m_geoCtxKey, ctx));
93 const ActsTrk::GeometryContext& gctx{*geoContextHandle};
94
95 for (const Identifier& test_me : m_testStations) {
96 ATH_MSG_DEBUG("Test retrieval of Mm detector element "<<m_idHelperSvc->toStringDetEl(test_me));
97 const MmReadoutElement* reElement = m_detMgr->getMmReadoutElement(test_me);
98 if (!reElement) {
99 continue;
100 }
102 if (reElement->identify() != test_me) {
103 ATH_MSG_FATAL("Expected to retrieve "<<m_idHelperSvc->toStringDetEl(test_me)
104 <<". But got instead "<<m_idHelperSvc->toStringDetEl(reElement->identify()));
105 return StatusCode::FAILURE;
106 }
107 const Amg::Transform3D globToLocal{reElement->globalToLocalTrans(gctx)};
108 const Amg::Transform3D& localToGlob{reElement->localToGlobalTrans(gctx)};
110 if (!Amg::doesNotDeform(globToLocal * localToGlob)) {
111 ATH_MSG_FATAL("Closure test failed for "<<m_idHelperSvc->toStringDetEl(test_me)
112 <<" "<<Amg::toString(globToLocal * localToGlob));
113 return StatusCode::FAILURE;
114 }
115 const MmIdHelper& id_helper{m_idHelperSvc->mmIdHelper()};
116 for (unsigned int layer = 1; layer <= reElement->nGasGaps(); ++layer) {
118 const int numStrips = reElement->numStrips(layerHash);
119 const int fStrip = reElement->firstStrip(layerHash);
120 const int lStrip = fStrip+numStrips-1;
121
122 for (int strip = fStrip; strip < lStrip; ++strip) {
123 bool isValid{false};
124
125 const Identifier chId = id_helper.channelID(reElement->identify(),
126 reElement->multilayer(),
127 layer, strip, isValid);
128 if (!isValid) {
129 continue;
130 }
131
133 const IdentifierHash channelHash = reElement->measurementHash(chId);
134 const IdentifierHash layHash = reElement->layerHash(chId);
135 const Identifier backCnv = reElement->measurementId(channelHash);
136 if (backCnv != chId) {
137 ATH_MSG_FATAL("The back and forth conversion of "<<m_idHelperSvc->toString(chId)
138 <<" failed. Got "<<m_idHelperSvc->toString(backCnv));
139 return StatusCode::FAILURE;
140 }
141 if (layHash != reElement->layerHash(channelHash)) {
142 ATH_MSG_FATAL("Constructing the layer hash from the identifier "<<
143 m_idHelperSvc->toString(chId)<<" leads to different layer hashes "<<
144 layHash<<" vs. "<< reElement->layerHash(channelHash));
145 return StatusCode::FAILURE;
146 }
147 const MuonGMR4::StripDesign& design{reElement->stripLayer(layHash).design()};
148 const Amg::Vector3D stripPos = reElement->stripPosition(gctx, channelHash);
149 const Amg::Vector3D locStripPos = reElement->globalToLocalTrans(gctx, layHash) * stripPos;
150 const Amg::Vector2D stripPos2D{locStripPos.block<2,1>(0,0)};
151 const double stripLen{design.stripLength(strip)};
152 if (stripLen && (design.stripNumber(stripPos2D) != strip ||
153 design.stripNumber(stripPos2D - 0.49 * stripLen * Amg::Vector2D::UnitY()) != strip ||
154 design.stripNumber(stripPos2D + 0.49 * stripLen * Amg::Vector2D::UnitY()) != strip)) {
155 ATH_MSG_FATAL("Conversion channel -> strip -> channel failed for "
156 <<m_idHelperSvc->toString(chId)<<" "<<Amg::toString(stripPos)<<", local: "
157 <<Amg::toString(locStripPos)<<" got "<<design.stripNumber(stripPos2D)
158 <<", first strip: "<<fStrip<<std::endl<<design);
159 return StatusCode::FAILURE;
160 }
161 ATH_MSG_VERBOSE("first strip "<<fStrip<<", numStrips "<< numStrips << ", channel "
162 << m_idHelperSvc->toString(chId) <<", strip position " << Amg::toString(stripPos));
163 }
164 }
165 ATH_CHECK(dumpToTree(ctx,gctx,reElement));
166 }
167
168 return StatusCode::SUCCESS;
169}
170StatusCode GeoModelMmTest::dumpToTree(const EventContext& ctx,
171 const ActsTrk::GeometryContext& gctx,
172 const MmReadoutElement* reElement) {
173
174
175
176 m_stIndex = reElement->stationName();
177 m_stEta = reElement->stationEta();
178 m_stPhi = reElement->stationPhi();
179 m_stML = reElement->multilayer();
180 m_chamberDesign = reElement->chamberDesign();
184 const Amg::Transform3D& transform{reElement->localToGlobalTrans(gctx)};
185 m_readoutTransform = transform;
186 m_alignableNode = reElement->alignableTransform()->getDefTransform();
187
189 m_moduleHeight = reElement->moduleHeight();
190 m_moduleWidthS = reElement->moduleWidthS();
191 m_moduleWidthL = reElement->moduleWidthL();
192
193 const MmIdHelper& id_helper{m_idHelperSvc->mmIdHelper()};
194 for (unsigned int layer = 1; layer <= reElement->nGasGaps(); ++layer) {
195
197 unsigned int numStrips = reElement->numStrips(layHash);
198 unsigned int fStrip = reElement->firstStrip(layHash);
199 unsigned int lStrip = fStrip+numStrips-1;
200
201 for (unsigned int strip = fStrip; strip <= lStrip ; ++strip) {
202 bool isValid{false};
203 const Identifier chId = id_helper.channelID(reElement->identify(),
204 reElement->multilayer(),
205 layer, strip, isValid);
206 if (!isValid) {
207 ATH_MSG_WARNING("Invalid Identifier detected for readout element "
208 <<m_idHelperSvc->toStringDetEl(reElement->identify())
209 <<" layer: "<<layer<<" strip: "<<strip);
210 continue;
211 }
212 const IdentifierHash measHash{reElement->measurementHash(chId)};
213
214 const MuonGMR4::StripDesign& design{reElement->stripLayer(measHash).design()};
215 if (strip == fStrip) {
216 const Amg::Transform3D stripLocalToGlob = reElement->localToGlobalTrans(gctx, chId);
217 ATH_MSG_VERBOSE(m_idHelperSvc->toStringGasGap(chId)<<" "<< "transform: "
218 << Amg::toString(stripLocalToGlob)<<", perp: "<<stripLocalToGlob.translation().perp());
219 m_stripRot.push_back(stripLocalToGlob);
220 m_stripRotGasGap.push_back(layer);
221 m_firstStripPos.push_back(design.firstStripPos());
222 m_readoutSide.push_back(reElement->readoutSide(measHash));
223
224 m_ActiveWidthS = reElement->gapLengthS(measHash);
225 m_ActiveWidthL = reElement->gapLengthL(measHash);
226 m_ActiveHeightR = reElement->gapHeight(measHash);
227 m_firstStrip.push_back(design.firstStripNumber());
228 m_nStrips.push_back(design.numStrips());
229 }
230 CheckVector2D center = design.center(strip);
231 if (!center) {
232 ATH_MSG_WARNING("Strip "<<m_idHelperSvc->toString(chId)<<" is outside bounds "<<design);
233 continue;
234 }
235 m_stripLength.push_back(reElement->stripLength(measHash));
236 m_locStripCenter.push_back(center.value());
237 m_isStereo.push_back(design.hasStereoAngle());
238 m_stripCenter.push_back(reElement->stripPosition(gctx, measHash));
239 m_stripLeftEdge.push_back(reElement->leftStripEdge(gctx,measHash));
240 m_stripRightEdge.push_back(reElement->rightStripEdge(gctx,measHash));
241 m_gasGap.push_back(layer);
242 m_channel.push_back(strip);
243 }
244 }
245 return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
246}
247
248}
249
#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)
bool isValid(const T &p)
Av: we implement here an ATLAS-sepcific convention: all particles which are 99xxxxx are fine.
Definition AtlasPID.h:878
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.
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
Converts the measurement hash back to the full Identifier.
IdentifierHash layerHash(const Identifier &measId) const override final
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)
int stationEta() const
Returns the stationEta (positive A site, negative O site)
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
const std::string & chamberDesign() const
The chamber design refers to the construction parameters of a readout element.
Identifier identify() const override final
Return the athena 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
Returnsthe alignable transform of the readout element.
Amg::Transform3D globalToLocalTrans(const ActsTrk::GeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
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.