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}
85 const EventContext& ctx{Gaudi::Hive::currentContext()};
86
87 const ActsTrk::GeometryContext* geoContextHandle{nullptr};
88 ATH_CHECK(SG::get(geoContextHandle, m_geoCtxKey, ctx));
89 const ActsTrk::GeometryContext& gctx{*geoContextHandle};
90
91 for (const Identifier& test_me : m_testStations) {
92 ATH_MSG_DEBUG("Test retrieval of Tgc detector element "<<m_idHelperSvc->toStringDetEl(test_me));
93 const TgcReadoutElement* reElement = m_detMgr->getTgcReadoutElement(test_me);
94 if (!reElement) {
95 continue;
96 }
98 if (reElement->identify() != test_me) {
99 ATH_MSG_FATAL("Expected to retrieve "<<m_idHelperSvc->toStringDetEl(test_me)
100 <<". But got instead "<<m_idHelperSvc->toStringDetEl(reElement->identify()));
101 return StatusCode::FAILURE;
102 }
103 const Amg::Transform3D globToLocal{reElement->globalToLocalTrans(gctx)};
104 const Amg::Transform3D& localToGlob{reElement->localToGlobalTrans(gctx)};
106 const Amg::Transform3D transClosure = globToLocal * localToGlob;
107 if (!Amg::doesNotDeform(transClosure)) {
108 ATH_MSG_FATAL("Closure test failed for "<<m_idHelperSvc->toStringDetEl(test_me)
109 <<". Ended up with "<< Amg::toString(transClosure) );
110 return StatusCode::FAILURE;
111 }
112 const TgcIdHelper& id_helper{m_idHelperSvc->tgcIdHelper()};
113 for (unsigned gasGap = 1; gasGap <= reElement->nGasGaps(); ++gasGap) {
114 for (bool isStrip : {false, true}) {
115 const IdentifierHash layHash = reElement->constructHash(0, gasGap, isStrip);
116 const unsigned nChan = reElement->numChannels(layHash);
117 for (unsigned chan = 1; chan <= nChan ; ++chan) {
118 bool isValid{false};
119 const Identifier channelId = id_helper.channelID(reElement->identify(),
120 gasGap, isStrip, chan, isValid);
121 if (!isValid) {
122 ATH_MSG_DEBUG("No valid Identifier constructed from the fields "
123 <<m_idHelperSvc->toStringDetEl(reElement->identify())
124 <<"isStrip: "<<(isStrip ? "yay" : "nay")<<" gasGap: "<<gasGap<<
125 " channel: "<<chan);
126 continue;
127 }
128 const IdentifierHash measHash{reElement->measurementHash(channelId)};
129 const Identifier backCnv = reElement->measurementId(measHash);
130 if (backCnv != channelId) {
131 ATH_MSG_FATAL("Forward-backward conversion of the Identifier "<<m_idHelperSvc->toString(channelId)
132 <<"failed. Got instead "<<m_idHelperSvc->toString(backCnv));
133 return StatusCode::FAILURE;
134 }
135 if (reElement->layerHash(channelId) != reElement->layerHash(measHash)) {
136 ATH_MSG_FATAL("The cosntruction of the layer hash from the Identifier "<<m_idHelperSvc->toString(channelId)
137 <<" gave something else than doing it from the measurement hash "<<measHash<<". "<<
138 reElement->layerHash(channelId)<<" vs. "<<reElement->layerHash(measHash));
139 }
140 }
141 }
142 }
143 ATH_CHECK(dumpToTree(ctx, gctx, reElement));
144 }
145 return StatusCode::SUCCESS;
146}
147StatusCode GeoModelTgcTest::dumpToTree(const EventContext& ctx,
148 const ActsTrk::GeometryContext& gctx,
149 const TgcReadoutElement* reElement) {
150
151 m_stIndex = reElement->stationName();
152 m_stEta = reElement->stationEta();
153 m_stPhi = reElement->stationPhi();
154 m_stLayout = reElement->chamberDesign();
155 m_nGasGaps = reElement->nGasGaps();
156 m_readoutTransform = reElement->localToGlobalTrans(gctx);
157
158 m_alignableNode = reElement->alignableTransform()->getDefTransform();
159
160 m_shortWidth = reElement->moduleWidthS();
161 m_longWidth = reElement->moduleWidthL();
162 m_height = reElement->moduleHeight();
163 m_thickness = reElement->moduleThickness();
164
165 for (unsigned gap = 1; gap <= reElement->nGasGaps(); ++gap) {
166 const IdentifierHash layHash = reElement->constructHash(0, gap, true);
168 for (unsigned strip = 1 ; strip <= reElement->numStrips(layHash); ++strip) {
169 const IdentifierHash measHash = reElement->constructHash(strip, gap, true);
170 const RadialStripDesign& layout{reElement->stripLayout(measHash)};
171
172 const Amg::Transform3D localToGlobal{reElement->localToGlobalTrans(gctx ,
173 reElement->layerHash(measHash)) *
174 (Amg::getRotateZ3D(-90.*Gaudi::Units::deg))};
175 if (strip == 1) {
176 m_layTans.push_back(localToGlobal);
177 m_layMeasPhi.push_back(true);
178 m_layNumber.push_back(gap);
179 m_layShortWidth.push_back(2.*layout.shortHalfHeight());
180 m_layLongWidth.push_back(2.*layout.longHalfHeight());
181 m_layHeight.push_back(2.*layout.halfWidth());
182 m_layNumWires.push_back(0);
183 }
184 m_stripGasGap.push_back(gap);
185 m_stripNum.push_back(strip);
186 m_stripCenter.push_back(reElement->channelPosition(gctx, measHash));
187 const auto sensor = reElement->sensorLayout(measHash);
188 const Amg::Vector2D locTop2D{layout.leftEdge(strip).value_or(Amg::Vector2D::Zero())};
189 const Amg::Vector2D locBot2D{layout.rightEdge(strip).value_or(Amg::Vector2D::Zero())};
190 const Amg::Vector3D globTop{localToGlobal * sensor->to3D(layout.leftEdge(strip), true)};
191 const Amg::Vector3D globBot{localToGlobal * sensor->to3D(layout.rightEdge(strip), true)};
192 m_stripBottom.push_back(globBot);
193 m_stripTop.push_back(globTop);
194 m_locStripTop.push_back(locTop2D);
195 m_locStripCenter.push_back(layout.center(strip).value_or(Amg::Vector2D::Zero()));
196 m_locStripBottom.push_back(locBot2D);
197
198 }
200 for (unsigned gang = 1; gang <= reElement->numWireGangs(layHash); ++gang) {
201 const IdentifierHash measHash = reElement->constructHash(gang, gap, false);
202 const WireGroupDesign& layout{reElement->wireGangLayout(measHash)};
203 if (gang == 1) {
204 m_layTans.push_back(reElement->localToGlobalTrans(gctx, reElement->layerHash(measHash)));
205 m_layMeasPhi.push_back(false);
206 m_layNumber.push_back(gap);
207 m_layShortWidth.push_back(2.*layout.shortHalfHeight());
208 m_layLongWidth.push_back(2.*layout.longHalfHeight());
209 m_layHeight.push_back(2.*layout.halfWidth());
210 m_layNumWires.push_back(layout.nAllWires());
211 }
212 m_gangNum.push_back(gang);
213 m_gangGasGap.push_back(gap);
214 m_gangCenter.push_back(reElement->channelPosition(gctx, measHash));
215 m_gangNumWires.push_back(layout.numWiresInGroup(gang));
216 m_locGangPos.push_back(layout.center(gang).value_or(Amg::Vector2D::Zero()));
217 m_gangLength.push_back(layout.stripLength(gang));
218 }
219 }
220 return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
221}
222
223}
224
#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)
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.
std::set< Identifier > m_testStations
Set of stations to be tested.
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.
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.
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
Converts the measurement hash back to the full Identifier.
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
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.