ATLAS Offline Software
Loading...
Searching...
No Matches
MuonPhaseII/MuonDetDescr/MuonGeoModelTestR4/src/GeoModelTgcTest.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 "GeoModelTgcTest.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 TgcIdHelper& idHelper{m_idHelperSvc->tgcIdHelper()};
22 auto translateTokenList = [this, &idHelper](const std::vector<std::string>& chNames){
23
24 std::set<Identifier> transcriptedIds{};
25 for (const std::string& token : chNames) {
26 if (token.size() != 7) {
27 ATH_MSG_WARNING("Wrong format given for "<<token<<". Expecting 7 characters");
28 continue;
29 }
31 const std::string statName = token.substr(0, 3);
32 const unsigned statEta = std::atoi(token.substr(3, 1).c_str()) * (token[4] == 'A' ? 1 : -1);
33 const unsigned statPhi = std::atoi(token.substr(5, 2).c_str());
34 bool isValid{false};
35 const Identifier eleId = idHelper.elementID(statName, statEta, statPhi, isValid);
36 if (!isValid) {
37 ATH_MSG_WARNING("Failed to deduce a station name for " << token);
38 continue;
39 }
40 transcriptedIds.insert(eleId);
41 }
42 return transcriptedIds;
43 };
44
45 std::vector <std::string>& selectedSt = m_selectStat.value();
46 const std::vector <std::string>& excludedSt = m_excludeStat.value();
47 selectedSt.erase(std::remove_if(selectedSt.begin(), selectedSt.end(),
48 [&excludedSt](const std::string& token){
49 return std::ranges::find(excludedSt, token) != excludedSt.end();
50 }), selectedSt.end());
51
52 if (selectedSt.size()) {
53 m_testStations = translateTokenList(selectedSt);
54 std::stringstream sstr{};
55 for (const Identifier& id : m_testStations) {
56 sstr<<" *** "<<m_idHelperSvc->toString(id)<<std::endl;
57 }
58 ATH_MSG_INFO("Test only the following stations "<<std::endl<<sstr.str());
59 } else {
60 const std::set<Identifier> excluded = translateTokenList(excludedSt);
62 for(auto itr = idHelper.detectorElement_begin();
63 itr!= idHelper.detectorElement_end();++itr){
64 if (!excluded.count(*itr)) {
65 m_testStations.insert(*itr);
66 }
67 }
69 if (!excluded.empty()) {
70 std::stringstream excluded_report{};
71 for (const Identifier& id : excluded){
72 excluded_report << " *** " << m_idHelperSvc->toStringDetEl(id) << std::endl;
73 }
74 ATH_MSG_INFO("Test all station except the following excluded ones " << std::endl << excluded_report.str());
75 }
76 }
77 ATH_CHECK(detStore()->retrieve(m_detMgr));
78 return StatusCode::SUCCESS;
79}
81 ATH_CHECK(m_tree.write());
82 return StatusCode::SUCCESS;
83}
84StatusCode GeoModelTgcTest::execute(const EventContext& ctx) {
85
86 const ActsTrk::GeometryContext* geoContextHandle{nullptr};
87 ATH_CHECK(SG::get(geoContextHandle, m_geoCtxKey, ctx));
88 const ActsTrk::GeometryContext& gctx{*geoContextHandle};
89
90 for (const Identifier& test_me : m_testStations) {
91 ATH_MSG_DEBUG("Test retrieval of Tgc detector element "<<m_idHelperSvc->toStringDetEl(test_me));
92 const TgcReadoutElement* reElement = m_detMgr->getTgcReadoutElement(test_me);
93 if (!reElement) {
94 continue;
95 }
97 if (reElement->identify() != test_me) {
98 ATH_MSG_FATAL("Expected to retrieve "<<m_idHelperSvc->toStringDetEl(test_me)
99 <<". But got instead "<<m_idHelperSvc->toStringDetEl(reElement->identify()));
100 return StatusCode::FAILURE;
101 }
102 const Amg::Transform3D globToLocal{reElement->globalToLocalTransform(gctx)};
103 const Amg::Transform3D& localToGlob{reElement->localToGlobalTransform(gctx)};
105 const Amg::Transform3D transClosure = globToLocal * localToGlob;
106 if (!Amg::doesNotDeform(transClosure)) {
107 ATH_MSG_FATAL("Closure test failed for "<<m_idHelperSvc->toStringDetEl(test_me)
108 <<". Ended up with "<< Amg::toString(transClosure) );
109 return StatusCode::FAILURE;
110 }
111 const TgcIdHelper& id_helper{m_idHelperSvc->tgcIdHelper()};
112 for (unsigned gasGap = 1; gasGap <= reElement->nGasGaps(); ++gasGap) {
113 for (bool isStrip : {false, true}) {
114 const IdentifierHash layHash = reElement->constructHash(0, gasGap, isStrip);
115 const unsigned nChan = reElement->numChannels(layHash);
116 for (unsigned chan = 1; chan <= nChan ; ++chan) {
117 bool isValid{false};
118 const Identifier channelId = id_helper.channelID(reElement->identify(),
119 gasGap, isStrip, chan, isValid);
120 if (!isValid) {
121 ATH_MSG_DEBUG("No valid Identifier constructed from the fields "
122 <<m_idHelperSvc->toStringDetEl(reElement->identify())
123 <<"isStrip: "<<(isStrip ? "yay" : "nay")<<" gasGap: "<<gasGap<<
124 " channel: "<<chan);
125 continue;
126 }
127 const IdentifierHash measHash{reElement->measurementHash(channelId)};
128 const Identifier backCnv = reElement->measurementId(measHash);
129 if (backCnv != channelId) {
130 ATH_MSG_FATAL("Forward-backward conversion of the Identifier "<<m_idHelperSvc->toString(channelId)
131 <<"failed. Got instead "<<m_idHelperSvc->toString(backCnv));
132 return StatusCode::FAILURE;
133 }
134 if (reElement->layerHash(channelId) != reElement->layerHash(measHash)) {
135 ATH_MSG_FATAL("The cosntruction of the layer hash from the Identifier "<<m_idHelperSvc->toString(channelId)
136 <<" gave something else than doing it from the measurement hash "<<measHash<<". "<<
137 reElement->layerHash(channelId)<<" vs. "<<reElement->layerHash(measHash));
138 }
139 }
140 }
141 }
142 ATH_CHECK(dumpToTree(ctx, gctx, reElement));
143 }
144 return StatusCode::SUCCESS;
145}
146StatusCode GeoModelTgcTest::dumpToTree(const EventContext& ctx,
147 const ActsTrk::GeometryContext& gctx,
148 const TgcReadoutElement* reElement) {
149
150 m_stIndex = reElement->stationName();
151 m_stEta = reElement->stationEta();
152 m_stPhi = reElement->stationPhi();
153 m_stLayout = reElement->chamberDesign();
154 m_nGasGaps = reElement->nGasGaps();
156
157 m_alignableNode = reElement->alignableTransform()->getDefTransform();
158
159 m_shortWidth = reElement->moduleWidthS();
160 m_longWidth = reElement->moduleWidthL();
161 m_height = reElement->moduleHeight();
162 m_thickness = reElement->moduleThickness();
163
164 for (unsigned gap = 1; gap <= reElement->nGasGaps(); ++gap) {
165 const IdentifierHash layHash = reElement->constructHash(0, gap, true);
167 for (unsigned strip = 1 ; strip <= reElement->numStrips(layHash); ++strip) {
168 const IdentifierHash measHash = reElement->constructHash(strip, gap, true);
169 const RadialStripDesign& layout{reElement->stripLayout(measHash)};
170
171 const Amg::Transform3D localToGlobal{reElement->localToGlobalTransform(gctx ,
172 reElement->layerHash(measHash)) *
173 (Amg::getRotateZ3D(-90.*Gaudi::Units::deg))};
174 if (strip == 1) {
175 m_layTans.push_back(localToGlobal);
176 m_layMeasPhi.push_back(true);
177 m_layNumber.push_back(gap);
178 m_layShortWidth.push_back(2.*layout.shortHalfHeight());
179 m_layLongWidth.push_back(2.*layout.longHalfHeight());
180 m_layHeight.push_back(2.*layout.halfWidth());
181 m_layNumWires.push_back(0);
182 }
183 m_stripGasGap.push_back(gap);
184 m_stripNum.push_back(strip);
185 m_stripCenter.push_back(reElement->channelPosition(gctx, measHash));
186 const auto sensor = reElement->sensorLayout(measHash);
187 const Amg::Vector2D locTop2D{layout.leftEdge(strip).value_or(Amg::Vector2D::Zero())};
188 const Amg::Vector2D locBot2D{layout.rightEdge(strip).value_or(Amg::Vector2D::Zero())};
189 const Amg::Vector3D globTop{localToGlobal * sensor->to3D(layout.leftEdge(strip), true)};
190 const Amg::Vector3D globBot{localToGlobal * sensor->to3D(layout.rightEdge(strip), true)};
191 m_stripBottom.push_back(globBot);
192 m_stripTop.push_back(globTop);
193 m_locStripTop.push_back(locTop2D);
194 m_locStripCenter.push_back(layout.center(strip).value_or(Amg::Vector2D::Zero()));
195 m_locStripBottom.push_back(locBot2D);
196
197 }
199 for (unsigned gang = 1; gang <= reElement->numWireGangs(layHash); ++gang) {
200 const IdentifierHash measHash = reElement->constructHash(gang, gap, false);
201 const WireGroupDesign& layout{reElement->wireGangLayout(measHash)};
202 if (gang == 1) {
203 m_layTans.push_back(reElement->localToGlobalTransform(gctx, reElement->layerHash(measHash)));
204 m_layMeasPhi.push_back(false);
205 m_layNumber.push_back(gap);
206 m_layShortWidth.push_back(2.*layout.shortHalfHeight());
207 m_layLongWidth.push_back(2.*layout.longHalfHeight());
208 m_layHeight.push_back(2.*layout.halfWidth());
209 m_layNumWires.push_back(layout.nAllWires());
210 }
211 m_gangNum.push_back(gang);
212 m_gangGasGap.push_back(gap);
213 m_gangCenter.push_back(reElement->channelPosition(gctx, measHash));
214 m_gangNumWires.push_back(layout.numWiresInGroup(gang));
215 m_locGangPos.push_back(layout.center(gang).value_or(Amg::Vector2D::Zero()));
216 m_gangLength.push_back(layout.stripLength(gang));
217 }
218 }
219 return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
220}
221
222}
223
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
const ServiceHandle< StoreGateSvc > & detStore() const
This is a "hash" representation of an Identifier.
std::set< Identifier > m_testStations
Set of stations to be tested.
StatusCode execute(const EventContext &ctx) override
Execute method.
StatusCode dumpToTree(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const TgcReadoutElement *readoutEle)
Gaudi::Property< std::vector< std::string > > m_selectStat
String should be formated like <stationName><stationEta><A/C><stationPhi>.
MuonVal::CoordTransformBranch m_readoutTransform
Transformation of the readout element (Translation, ColX, ColY, ColZ).
MuonVal::ScalarBranch< unsigned short > & m_stIndex
Identifier of the readout element.
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.
const StripLayerPtr & sensorLayout(const IdentifierHash &hash) const
Returns the pointer to the strip layer associated with the gas gap.
unsigned numWireGangs(const IdentifierHash &layHash) const
Returns the number of wire gangs for a given gasGap [1-3].
Amg::Vector3D channelPosition(const ActsTrk::GeometryContext &ctx, const Identifier &measId) const
Returns the center of the measurement channel eta measurement: wire gang center phi measurement: stri...
double moduleWidthS() const
Returns the length of the bottom edge of the chamber (short width).
const RadialStripDesign & stripLayout(const IdentifierHash &layHash) const
Returns access to the strip design of the given gasGap [1-3] If the gap does not have strips an excep...
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 measurementHash(const Identifier &measId) const override final
Constructs the identifier hash from the full measurement Identifier.
static IdentifierHash constructHash(unsigned measCh, unsigned gasGap, const bool isStrip)
Constructs the Hash out of the Identifier fields (channel, gasGap, isStrip).
const WireGroupDesign & wireGangLayout(const IdentifierHash &layHash) const
Returns access to the wire group design of the given gasGap [1-3] If the gap does not have a wires an...
double moduleHeight() const
Returns the height of the chamber (Distance bottom - topWidth).
unsigned numChannels(const IdentifierHash &measHash) const
Returns the number of readout channels.
double moduleWidthL() const
Returns the length of the top edge of the chamber (top width).
unsigned nGasGaps() const
Returns the number of gasgaps described by this ReadOutElement (usally 2 or 3).
double moduleThickness() const
Returns the thickness of the chamber.
unsigned numStrips(const IdentifierHash &layHash) const
Returns the number of strips for a given gasGap [1-3].
IdentifierHash layerHash(const Identifier &measId) const override final
The layer hash removes the bits from the IdentifierHash corresponding to the measurement's channel nu...
const_id_iterator detectorElement_begin() const
Iterators over full set of ids.
const_id_iterator detectorElement_end() const
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Identifier channelID(int stationName, int stationEta, int stationPhi, int gasGap, int isStrip, int channel) 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.
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
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.