ATLAS Offline Software
Loading...
Searching...
No Matches
MuonDetDescr/MuonGeoModelTest/src/GeoModelsTgcTest.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4#include "GeoModelsTgcTest.h"
5
6#include <fstream>
7#include <iostream>
8
12#include "GeoModelKernel/GeoDefinitions.h"
14#include "GaudiKernel/SystemOfUnits.h"
15
16namespace MuonGM {
17
18
20 ATH_CHECK(m_tree.write());
21 return StatusCode::SUCCESS;
22}
24 ATH_CHECK(m_detMgrKey.initialize());
25 ATH_CHECK(m_idHelperSvc.retrieve());
26 ATH_CHECK(m_tree.init(this));
27 const sTgcIdHelper& idHelper{m_idHelperSvc->stgcIdHelper()};
28 auto translateTokenList = [this, &idHelper](const std::vector<std::string>& chNames){
29
30 std::set<Identifier> transcriptedIds{};
31 for (const std::string& token : chNames) {
32 if (token.size() != 6) {
33 ATH_MSG_WARNING("Wrong format given for "<<token<<". Expecting 6 characters");
34 continue;
35 }
37 const std::string statName = token.substr(0, 3);
38 const unsigned statEta = std::atoi(token.substr(3, 1).c_str()) * (token[4] == 'A' ? 1 : -1);
39 const unsigned statPhi = std::atoi(token.substr(5, 1).c_str());
40 bool isValid{false};
41 const Identifier eleId = idHelper.elementID(statName, statEta, statPhi, isValid);
42 if (!isValid) {
43 ATH_MSG_WARNING("Failed to deduce a station name for " << token);
44 continue;
45 }
46 transcriptedIds.insert(eleId);
47 const Identifier secMlId = idHelper.multilayerID(eleId, 2, isValid);
48 if (isValid){
49 transcriptedIds.insert(secMlId);
50 }
51 }
52 return transcriptedIds;
53 };
54
55 std::vector <std::string>& selectedSt = m_selectStat.value();
56 const std::vector <std::string>& excludedSt = m_excludeStat.value();
57 selectedSt.erase(std::remove_if(selectedSt.begin(), selectedSt.end(),
58 [&excludedSt](const std::string& token){
59 return std::ranges::find(excludedSt, token) != excludedSt.end();
60 }), selectedSt.end());
61
62 if (selectedSt.size()) {
63 m_testStations = translateTokenList(selectedSt);
64 std::stringstream sstr{};
65 for (const Identifier& id : m_testStations) {
66 sstr<<" *** "<<m_idHelperSvc->toString(id)<<std::endl;
67 }
68 ATH_MSG_INFO("Test only the following stations "<<std::endl<<sstr.str());
69 } else {
70 const std::set<Identifier> excluded = translateTokenList(excludedSt);
72 for(auto itr = idHelper.detectorElement_begin();
73 itr!= idHelper.detectorElement_end();++itr){
74 if (!excluded.count(*itr)) {
75 m_testStations.insert(*itr);
76 }
77 }
79 if (!excluded.empty()) {
80 std::stringstream excluded_report{};
81 for (const Identifier& id : excluded){
82 excluded_report << " *** " << m_idHelperSvc->toStringDetEl(id) << std::endl;
83 }
84 ATH_MSG_INFO("Test all station except the following excluded ones " << std::endl << excluded_report.str());
85 }
86 }
87 return StatusCode::SUCCESS;
88}
90 const EventContext& ctx{Gaudi::Hive::currentContext()};
92 if (!detMgr.isValid()) {
93 ATH_MSG_FATAL("Failed to retrieve MuonDetectorManager "
94 << m_detMgrKey.fullKey());
95 return StatusCode::FAILURE;
96 }
97 for (const Identifier& test_me : m_testStations) {
98 ATH_MSG_VERBOSE("Test retrieval of sTgc detector element "
99 << m_idHelperSvc->toStringDetEl(test_me));
100 const sTgcReadoutElement* reElement = detMgr->getsTgcReadoutElement(test_me);
101 if (!reElement) {
102 ATH_MSG_VERBOSE("Detector element is invalid");
103 continue;
104 }
106 if (m_idHelperSvc->toStringDetEl(reElement->identify()) != m_idHelperSvc->toStringDetEl(test_me)) {
107 ATH_MSG_FATAL("Expected to retrieve "
108 << m_idHelperSvc->toStringDetEl(test_me) << ". But got instead "
109 << m_idHelperSvc->toStringDetEl(reElement->identify()));
110 return StatusCode::FAILURE;
111 }
112 ATH_CHECK(dumpToTree(ctx, reElement));
113 }
114 return StatusCode::SUCCESS;
115}
116StatusCode GeoModelsTgcTest::dumpToTree(const EventContext& ctx, const sTgcReadoutElement* roEl) {
117 const sTgcIdHelper& id_helper{m_idHelperSvc->stgcIdHelper()};
118
119 const Amg::Transform3D permute{GeoTrf::GeoRotation{90.*Gaudi::Units::deg,90.*Gaudi::Units::deg, 0.}};
120 m_alignableNode = roEl->AmdbLRSToGlobalTransform() * roEl->getDelta().inverse()*permute;
122 int stIndex = roEl->getStationIndex();
123 int stEta = roEl->getStationEta();
124 int stPhi = roEl->getStationPhi();
125 int stML = id_helper.multilayer(roEl->identify());
126 std::string chamberDesign = roEl->getStationType();
127
128 m_stIndex = stIndex;
129 m_stEta = stEta;
130 m_stPhi = stPhi;
131 m_stML = stML;
132 m_chamberDesign = chamberDesign;
133
134 const Identifier genStripID =id_helper.channelID(stIndex, stEta, stPhi,
136 const Identifier genPadID =id_helper.channelID(stIndex, stEta, stPhi,
138
140 int numLayers = roEl->numberOfLayers(true);
141 double yCutout = roEl->getDesign(genStripID)->yCutout();
142 double gasTck = roEl->getDesign(genStripID)->thickness;
143
144 m_numLayers = numLayers;
145 m_yCutout = yCutout;
146 m_gasTck = gasTck;
148 double sGapLength = roEl->getDesign(genStripID)->minYSize();
149 double lGapLength = roEl->getDesign(genStripID)->maxYSize();
150 double gapHeight = roEl->getDesign(genStripID)->xSize();
151
152 double sPadLength = roEl->getPadDesign(genPadID)->sPadWidth;
153 double lPadLength = roEl->getPadDesign(genPadID)->lPadWidth;
154
155 m_sGapLength = sGapLength;
156 m_lGapLength = lGapLength;
157 m_gapHeight = gapHeight;
158
159 m_sPadLength = sPadLength;
160 m_lPadLength = lPadLength;
162 double sChamberLength = roEl->getPadDesign(genPadID)->sWidth;
163 double lChamberLength = roEl->getPadDesign(genPadID)->lWidth;
164 double chamberHeight = roEl->getPadDesign(genPadID)->Length;
165
166 m_sChamberLength = sChamberLength;
167 m_lChamberLength = lChamberLength;
168 m_chamberHeight = chamberHeight;
169
171 const Amg::Transform3D& trans{roEl->transform()};
172 m_readoutTransform = trans;
173
175 for (int lay = 1; lay <= numLayers; ++lay) {
176 const Identifier layWireID =id_helper.channelID(stIndex, stEta, stPhi,
178 const Identifier layStripID =id_helper.channelID(stIndex, stEta, stPhi,
180 const Identifier layPadID =id_helper.padID(stIndex, stEta, stPhi,
181 stML, lay, sTgcIdHelper::sTgcChannelTypes::Pad, 1, 1);
182
184 unsigned int numWires = roEl->numberOfWires(layWireID);
185 unsigned int firstWireGroupWidth = roEl->getDesign(layWireID)->firstPitch;
186 int numWireGroups = roEl->getDesign(layWireID)->nGroups;
187 double wireCutout = roEl->getDesign(layWireID)->wireCutout;
188 double wirePitch = roEl->wirePitch();
189 double wireWidth = roEl->getDesign(layWireID)->inputWidth;
190 double wireGroupWidth = roEl->getDesign(layWireID)->groupWidth;
191
192 m_numWires.push_back(numWires);
193 m_firstWireGroupWidth.push_back(firstWireGroupWidth);
194 m_numWireGroups.push_back(numWireGroups);
195 m_wireCutout.push_back(wireCutout);
196 m_wirePitch = wirePitch;
197 m_wireWidth = wireWidth;
198 m_wireGroupWidth = wireGroupWidth;
199
201 for (int wireGroupIndex = 1; wireGroupIndex <= numWireGroups; ++wireGroupIndex) {
202 bool isValid = false;
203 const Identifier wireGroupID =id_helper.channelID(stIndex, stEta, stPhi, stML, lay,
205 if(!isValid) {
206 ATH_MSG_WARNING("The following wire group ID is not valid: " << wireGroupID);
207 }
208 Amg::Vector3D wireGroupPos(Amg::Vector3D::Zero());
209 Amg::Vector2D localWireGroupPos(Amg::Vector2D::Zero());
210 roEl->stripPosition(wireGroupID, localWireGroupPos);
211 m_localWireGroupPos.push_back(localWireGroupPos);
212 roEl->stripGlobalPosition(wireGroupID, wireGroupPos);
213 m_globalWireGroupPos.push_back(wireGroupPos);
214 m_wireGroupNum.push_back(wireGroupIndex);
215 m_wireGroupGasGap.push_back(lay);
216
217 if (wireGroupIndex != 1) continue;
218 const Amg::Transform3D locToGlob = roEl->transform(wireGroupID);
219 m_wireGroupRot.push_back(locToGlob);
220 m_wireGroupRotGasGap.push_back(lay);
221 }
222
224 int numStrips = roEl->getDesign(layStripID)->nch;
225 double stripPitch = roEl->channelPitch(layStripID);
226 double stripWidth = roEl->getDesign(layStripID)->inputWidth;
227 double firstStripPitch = roEl->getDesign(layStripID)->firstPitch;
228
229 m_numStrips = numStrips;
230 m_stripPitch = stripPitch;
231 m_stripWidth = stripWidth;
232 m_firstStripPitch.push_back(firstStripPitch);
233
235 for (int stripIndex = 1; stripIndex <= numStrips; ++stripIndex) {
236 bool isValid = false;
237 const Identifier stripID =id_helper.channelID(stIndex, stEta, stPhi, stML, lay,
239 if(!isValid) {
240 ATH_MSG_WARNING("The following strip ID is not valid: " << stripID);
241 }
242 double stripLength = roEl->getDesign(stripID)->channelLength(stripIndex);
243 Amg::Vector3D globalStripPos(Amg::Vector3D::Zero());
244 Amg::Vector2D localStripPos(Amg::Vector2D::Zero());
245 roEl->stripPosition(stripID, localStripPos);
246 m_localStripPos.push_back(localStripPos);
247 roEl->stripGlobalPosition(stripID, globalStripPos);
248 m_globalStripPos.push_back(globalStripPos);
249 m_stripNum.push_back(stripIndex);
250 m_stripGasGap.push_back(lay);
251 m_stripLengths.push_back(stripLength);
252
253 if (stripIndex != 1) continue;
254 const Amg::Transform3D locToGlob = roEl->transform(stripID);
255 m_stripRot.push_back(locToGlob);
256 m_stripRotGasGap.push_back(lay);
257 }
258
260 unsigned int numPads = roEl->numberOfPads(layPadID);
261 int numPadEta = roEl->getPadDesign(layPadID)->nPadH;
262 int numPadPhi = roEl->getPadDesign(layPadID)->nPadColumns;
263 double firstPadHeight = roEl->getPadDesign(layPadID)->firstRowPos;
264 double padHeight = roEl->getPadDesign(layPadID)->inputRowPitch;
265 double padPhiShift = roEl->getPadDesign(layPadID)->PadPhiShift;
266 double firstPadPhiDiv = roEl->getPadDesign(layPadID)->firstPhiPos;
267 double anglePadPhi = roEl->getPadDesign(layPadID)->inputPhiPitch;
268 double beamlineRadius = roEl->getPadDesign(layPadID)->radialDistance;
269
270 m_numPads.push_back(numPads);
271 m_numPadEta.push_back(numPadEta);
272 m_numPadPhi.push_back(numPadPhi);
273 m_firstPadHeight.push_back(firstPadHeight);
274 m_padHeight.push_back(padHeight);
275 m_padPhiShift.push_back(padPhiShift);
276 m_firstPadPhiDiv.push_back(firstPadPhiDiv);
277 m_anglePadPhi = anglePadPhi;
278 m_beamlineRadius = beamlineRadius;
279
281 for (int phiIndex = 1; phiIndex <= numPadPhi; ++phiIndex) {
282 for(int etaIndex = 1; etaIndex <= numPadEta; ++etaIndex) {
283 bool isValid = false;
284 const Identifier padID =id_helper.padID(stIndex, stEta, stPhi, stML, lay,
285 sTgcIdHelper::sTgcChannelTypes::Pad, etaIndex, phiIndex, isValid);
286 if(!isValid) {
287 ATH_MSG_WARNING("The following pad ID is not valid: " << padID);
288 }
289 Amg::Vector2D localPadPos(Amg::Vector2D::Zero());
290 Amg::Vector3D globalPadPos(Amg::Vector3D::Zero());
291 std::array<Amg::Vector2D,4> localPadCorners{make_array<Amg::Vector2D, 4>(Amg::Vector2D::Zero())};
292 std::array<Amg::Vector3D,4> globalPadCorners{make_array<Amg::Vector3D, 4>(Amg::Vector3D::Zero())};
293
294 roEl->padPosition(padID, localPadPos);
295 roEl->padGlobalPosition(padID, globalPadPos);
296 roEl->padCorners(padID, localPadCorners);
297 roEl->padGlobalCorners(padID, globalPadCorners);
298
299 m_localPadPos.push_back(localPadPos);
300 m_localPadCornerBL.push_back(localPadCorners[0]);
301 m_localPadCornerBR.push_back(localPadCorners[1]);
302 m_localPadCornerTL.push_back(localPadCorners[2]);
303 m_localPadCornerTR.push_back(localPadCorners[3]);
304
305 Amg::Vector2D hitCorrection{-.1, -.1};
306 Amg::Vector2D hitPos = localPadCorners[3] + hitCorrection;
307 m_hitPosition.push_back(hitPos);
308 m_padNumber.push_back(roEl->padNumber(hitPos, padID));
309
310 m_globalPadPos.push_back(globalPadPos);
311 m_globalPadCornerBR.push_back(globalPadCorners[0]);
312 m_globalPadCornerBL.push_back(globalPadCorners[1]);
313 m_globalPadCornerTR.push_back(globalPadCorners[2]);
314 m_globalPadCornerTL.push_back(globalPadCorners[3]);
315
316 m_padEta.push_back(etaIndex);
317 m_padPhi.push_back(phiIndex);
318 m_padGasGap.push_back(lay);
319
320 if (etaIndex != 1 || phiIndex != 1) continue;
321 const Amg::Transform3D locToGlob = roEl->transform(padID);
322 m_padRot.push_back(locToGlob);
323 m_padRotGasGap.push_back(lay);
324 }
325 }
326 }
327
328 return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
329}
330
331}
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_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(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
MuonVal::ScalarBranch< short > & m_stIndex
Identifier of the readout element.
MuonVal::VectorBranch< uint > & m_numPads
Pad dimensions.
MuonVal::ScalarBranch< std::string > & m_chamberDesign
MuonVal::ScalarBranch< float > & m_sChamberLength
Chamber Length for debug.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
MuonVal::CoordSystemsBranch m_stripRot
Rotation matrix of the respective strip layers.
MuonVal::CoordSystemsBranch m_padRot
Rotation matrix of the respective pad layers.
std::set< Identifier > m_testStations
Set of stations to be tested.
MuonVal::ScalarBranch< float > & m_sGapLength
GasGap Lengths for debug.
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_detMgrKey
MuonDetectorManager from the conditions store.
StatusCode dumpToTree(const EventContext &ctx, const sTgcReadoutElement *readoutEle)
Gaudi::Property< std::vector< std::string > > m_selectStat
String should be formated like <stationName><stationEta><A/C><stationPhi>
MuonVal::ScalarBranch< uint > & m_numStrips
Strip dimensions.
Gaudi::Property< std::vector< std::string > > m_excludeStat
MuonVal::CoordSystemsBranch m_wireGroupRot
Rotation matrix of the respective wireGroup layers.
MuonVal::CoordTransformBranch m_readoutTransform
Transformation of the readout element (Translation, ColX, ColY, ColZ)
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
An sTgcReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station c...
bool padPosition(const Identifier &id, Amg::Vector2D &pos) const
pad position
const MuonPadDesign * getPadDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
virtual bool stripPosition(const Identifier &id, Amg::Vector2D &pos) const override final
strip position - should be renamed to channel position If the strip number is outside the range of va...
bool padCorners(const Identifier &id, std::array< Amg::Vector2D, 4 > &corners) const
pad corners
const MuonChannelDesign * getDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
int numberOfWires(const Identifier &id) const
Get the total number of wires (single wires) of a chamber.
double channelPitch(const Identifier &id) const
Channel pitch.
const Amg::Transform3D & getDelta() const
read A-line parameters and include the chamber rotation/translation in the local-to-global (ATLAS) re...
bool padGlobalPosition(const Identifier &id, Amg::Vector3D &gpos) const
pad global position
bool stripGlobalPosition(const Identifier &id, Amg::Vector3D &gpos) const
virtual int numberOfLayers(bool) const override final
number of layers in phi/eta projection
int numberOfPads(const Identifier &layerId) const
Get the number of pad per layer.
bool padGlobalCorners(const Identifier &id, std::array< Amg::Vector3D, 4 > &gcorners) const
pad global corners
int padNumber(const Amg::Vector2D &pos, const Identifier &id) const
pad number corresponding to local position
const_id_iterator detectorElement_begin() const
Iterators over full set of ids.
const_id_iterator detectorElement_end() const
int multilayer(const Identifier &id) const
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Identifier padID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int padEta, int padPhi) const
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int channel) const
Identifier multilayerID(const Identifier &channeldID) const
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the Athena extensions are properly loaded.
Definition GeoMuonHits.h:27
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.
double channelLength(int channel) const
STRIPS ONLY: calculate channel length for a given strip number.
double radialDistance
DT-2015-11-29 distance from the beamline to the center of the module.