ATLAS Offline Software
Loading...
Searching...
No Matches
MuonDetDescr/MuonGeoModelTest/src/GeoModelRpcTest.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 "GeoModelRpcTest.h"
5
6#include <fstream>
7#include <iostream>
8
13#include "GaudiKernel/SystemOfUnits.h"
14
15
16namespace MuonGM {
17
19 ATH_CHECK(m_tree.write());
20 return StatusCode::SUCCESS;
21}
23 ATH_CHECK(m_detMgrKey.initialize());
24 ATH_CHECK(m_idHelperSvc.retrieve());
25 ATH_CHECK(m_tree.init(this));
26 const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
27 auto translateTokenList = [this, &idHelper](const std::vector<std::string>& chNames){
28
29 std::set<Identifier> transcriptedIds{};
30 for (const std::string& token : chNames) {
31 if (token.size() != 6) {
32 ATH_MSG_WARNING("Wrong format given for "<<token<<". Expecting 6 characters");
33 continue;
34 }
36 const std::string statName = token.substr(0, 3);
37 const unsigned statEta = std::atoi(token.substr(3, 1).c_str()) * (token[4] == 'A' ? 1 : -1);
38 const unsigned statPhi = std::atoi(token.substr(5, 1).c_str());
39 bool isValid{false};
40 const Identifier eleId = idHelper.elementID(statName, statEta, statPhi, 1, isValid);
41 if (!isValid) {
42 ATH_MSG_WARNING("Failed to deduce a station name for " << token);
43 continue;
44 }
45 transcriptedIds.insert(eleId);
46 std::copy_if(idHelper.detectorElement_begin(), idHelper.detectorElement_end(),
47 std::inserter(transcriptedIds, transcriptedIds.end()),
48 [&eleId, &idHelper](const Identifier& copyMe){
49 return idHelper.stationName(copyMe) == idHelper.stationName(eleId) &&
50 idHelper.stationEta(copyMe) == idHelper.stationEta(eleId) &&
51 idHelper.stationPhi(copyMe) == idHelper.stationPhi(eleId);
52 });
53 }
54 return transcriptedIds;
55 };
56
57 std::vector <std::string>& selectedSt = m_selectStat.value();
58 const std::vector <std::string>& excludedSt = m_excludeStat.value();
59 selectedSt.erase(std::remove_if(selectedSt.begin(), selectedSt.end(),
60 [&excludedSt](const std::string& token){
61 return std::ranges::find(excludedSt, token) != excludedSt.end();
62 }), selectedSt.end());
63
64 if (selectedSt.size()) {
65 m_testStations = translateTokenList(selectedSt);
66 std::stringstream sstr{};
67 for (const Identifier& id : m_testStations) {
68 sstr<<" *** "<<m_idHelperSvc->toString(id)<<std::endl;
69 }
70 ATH_MSG_INFO("Test only the following stations "<<std::endl<<sstr.str());
71 } else {
72 const std::set<Identifier> excluded = translateTokenList(excludedSt);
74 for(auto itr = idHelper.detectorElement_begin();
75 itr!= idHelper.detectorElement_end();++itr){
76 if (!excluded.count(*itr)) {
77 m_testStations.insert(*itr);
78 }
79 }
81 if (!excluded.empty()) {
82 std::stringstream excluded_report{};
83 for (const Identifier& id : excluded){
84 excluded_report << " *** " << m_idHelperSvc->toStringDetEl(id) << std::endl;
85 }
86 ATH_MSG_INFO("Test all station except the following excluded ones " << std::endl << excluded_report.str());
87 }
88 }
89 return StatusCode::SUCCESS;
90}
91StatusCode GeoModelRpcTest::execute(const EventContext& ctx) {
93 if (!detMgr.isValid()) {
94 ATH_MSG_FATAL("Failed to retrieve MuonDetectorManager "
95 << m_detMgrKey.fullKey());
96 return StatusCode::FAILURE;
97 }
98 for (const Identifier& test_me : m_testStations) {
99 ATH_MSG_VERBOSE("Test retrieval of Mdt detector element "
100 << m_idHelperSvc->toStringDetEl(test_me));
101 const RpcReadoutElement* reElement = detMgr->getRpcReadoutElement(test_me);
102 if (!reElement) {
103 ATH_MSG_VERBOSE("Detector element is invalid");
104 continue;
105 }
107 if (reElement->identify() != test_me) {
108 ATH_MSG_FATAL("Expected to retrieve "
109 << m_idHelperSvc->toStringDetEl(test_me) << ". But got instead "
110 << m_idHelperSvc->toStringDetEl(reElement->identify()));
111 return StatusCode::FAILURE;
112 }
113 ATH_CHECK(dumpToTree(ctx, reElement));
114 if (m_idHelperSvc->stationNameString(reElement->identify()) == "BIS") continue;
115 const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
116 for (int gasGap = 1 ; gasGap <= reElement->numberOfLayers(); ++gasGap) {
117 for (int doubPhi = reElement->getDoubletPhi(); doubPhi <= reElement->NphiStripPanels(); ++doubPhi) {
118 for (bool measPhi: {false, true}) {
119 for (int strip = 1 ; strip < reElement->Nstrips(measPhi); ++strip) {
120 bool isValid{false};
121 const Identifier stripId = idHelper.channelID(test_me,
122 idHelper.doubletZ(test_me),
123 doubPhi,
124 gasGap, measPhi, strip, isValid);
125 if (!isValid) {
126 ATH_MSG_DEBUG("Could not construct Identifier from "
127 <<m_idHelperSvc->toStringChamber(test_me)
128 <<", gasGap:"<<gasGap<<", doubletPhi: "<<doubPhi
129 <<", measurePhi "<<measPhi<<", strip: "<<strip);
130 continue;
131 }
132 Amg::Vector2D locPos2D{Amg::Vector2D::Zero()};
133 if (!reElement->stripPosition(stripId, locPos2D)) {
134 ATH_MSG_FATAL("Could not retrieve the local strip position for "<<m_idHelperSvc->toString(stripId));
135 return StatusCode::FAILURE;
136 }
137 const Trk::Surface& planeSurf{reElement->surface(stripId)};
138 const Amg::Vector3D globPos3D = planeSurf.localToGlobal(locPos2D);
140 const Amg::Vector3D stripPos = reElement->stripPos(stripId);
141 if ( (stripPos - globPos3D).mag() > std::numeric_limits<float>::epsilon()) {
142 ATH_MSG_FATAL("Retrieving the strip position in two different ways leads to two distinct results "
143 <<Amg::toString(stripPos)<<" as reference. Second path "<<Amg::toString(globPos3D));
144 return StatusCode::FAILURE;
145 }
146 const Trk::Surface& laySurf{reElement->surface(stripId)};
147 const double stripLen = 0.5 *reElement->StripLength(measPhi) - 1. * Gaudi::Units::cm;
148 if (!laySurf.insideBounds(locPos2D)){
149 ATH_MSG_FATAL("The strip center "<<Amg::toString(locPos2D)<<" of "<<m_idHelperSvc->toString(stripId)
150 <<" is outside bounds "<<laySurf.bounds());
151 return StatusCode::FAILURE;
152 }
153 if (!laySurf.insideBounds(locPos2D + stripLen * Amg::Vector2D::UnitY())){
154 ATH_MSG_FATAL("The right strip edge "<<Amg::toString(locPos2D + stripLen * Amg::Vector2D::UnitY())<<
155 " of "<<m_idHelperSvc->toString(stripId)<<" is outside bounds "<<laySurf.bounds());
156 return StatusCode::FAILURE;
157 }if (!laySurf.insideBounds(locPos2D - stripLen * Amg::Vector2D::UnitY())){
158 ATH_MSG_FATAL("The left strip edge "<<Amg::toString(locPos2D - stripLen * Amg::Vector2D::UnitY())
159 <<" of "<<m_idHelperSvc->toString(stripId)<<" is outside bounds "<<laySurf.bounds());
160 return StatusCode::FAILURE;
161 }
162 }
163 }
164 }
165 }
166 }
167 return StatusCode::SUCCESS;
168}
169StatusCode GeoModelRpcTest::dumpToTree(const EventContext& ctx, const RpcReadoutElement* readoutEle) {
170
171 m_stIndex = readoutEle->getStationIndex();
172 m_stEta = readoutEle->getStationEta();
173 m_stPhi = readoutEle->getStationPhi();
174 m_doubletR = readoutEle->getDoubletR();
175 m_doubletZ = readoutEle->getDoubletZ();
176 m_doubletPhi = readoutEle->getDoubletPhi();
177 m_chamberDesign = readoutEle->getTechnologyName();
178
179 m_numStripsEta = readoutEle->Nstrips(false);
180 m_numStripsPhi = readoutEle->Nstrips(true);
181 m_numRpcLayers = readoutEle->numberOfLayers();
182 m_numPhiPanels = readoutEle->NphiStripPanels();
183
184 m_stripEtaPitch = readoutEle->StripPitch(false);
185 m_stripPhiPitch = readoutEle->StripPitch(true);
186 m_stripEtaWidth = readoutEle->StripWidth(false);
187 m_stripPhiWidth = readoutEle->StripWidth(true);
188 m_stripEtaLength = readoutEle->StripLength(false);
189 m_stripPhiLength = readoutEle->StripLength(true);
190
191
192 const RpcIdHelper& idHelper{m_idHelperSvc->rpcIdHelper()};
193
194 const Amg::Transform3D& trans{readoutEle->absTransform()};
195 m_readoutTransform = trans;
196 const MuonGM::MuonStation* station = readoutEle->parentMuonStation();
197 m_alignableNode = station->getGeoTransform()->getDefTransform() *
198 station->getNativeToAmdbLRS().inverse();
199 if (station->hasALines()) {
200 m_ALineTransS = station->getALine_tras();
201 m_ALineTransT = station->getALine_traz();
202 m_ALineTransZ = station->getALine_trat();
203 m_ALineRotS = station->getALine_rots();
204 m_ALineRotT = station->getALine_rotz();
205 m_ALineRotZ = station->getALine_rott();
206 }
207 const int maxDoubPhi = std::max(readoutEle->getDoubletPhi(), readoutEle->NphiStripPanels());
208 for (int doubPhi = readoutEle->getDoubletPhi(); doubPhi <= maxDoubPhi; ++doubPhi) {
209 for (int gap = 1; gap <= readoutEle->numberOfLayers(); ++gap) {
210 for (bool measPhi : {false, true}) {
211 unsigned int numStrip = readoutEle->Nstrips(measPhi);
212 for (unsigned int strip = 1; strip <= numStrip ; ++strip) {
213 bool isValid{false};
214 const Identifier stripID = idHelper.channelID(readoutEle->identify(),
215 readoutEle->getDoubletZ(),
216 doubPhi, gap, measPhi, strip, isValid);
217 if (!isValid) {
218 ATH_MSG_WARNING("Invalid Identifier detected for readout element "
219 <<m_idHelperSvc->toStringDetEl(readoutEle->identify())
220 <<" gap: "<<gap<<" strip: "<<strip<<" meas phi: "<<measPhi);
221 continue;
222 }
223 Amg::Vector2D lStripPos{Amg::Vector2D::Zero()};
224 if (!readoutEle->stripPosition(stripID, lStripPos)){
225 ATH_MSG_FATAL("Failed to obtain strip position for "<<m_idHelperSvc->toString(stripID));
226 return StatusCode::FAILURE;
227 }
228
229 m_stripPos.push_back(readoutEle->stripPos(stripID));
230 m_locPos.push_back(lStripPos);
231 m_stripPosGasGap.push_back(gap);
232 m_stripPosMeasPhi.push_back(measPhi);
233 m_stripPosNum.push_back(strip);
234 m_stripDblPhi.push_back(doubPhi);
235
236 if (strip != 1) continue;
237 const Amg::Transform3D locToGlob = readoutEle->transform(stripID);
238 m_stripRot.push_back(locToGlob);
239 m_stripRotGasGap.push_back(gap);
240 m_stripRotMeasPhi.push_back(measPhi);
241 m_stripRotDblPhi.push_back(doubPhi);
242
243 }
244 }
245 }
246 }
247
248 return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
249}
250
251
252}
Scalar mag() const
mag method
#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)
MuonVal::ScalarBranch< float > & m_stripEtaPitch
Strip dimensions.
std::set< Identifier > m_testStations
Set of stations to be tested.
MuonVal::ThreeVectorBranch m_stripPos
Strip positions.
MuonVal::ScalarBranch< uint8_t > & m_numRpcLayers
Number of eta & phi gas gaps.
MuonVal::ScalarBranch< float > & m_ALineTransS
Alignment parameters.
Gaudi::Property< std::vector< std::string > > m_selectStat
String should be formated like <stationName><stationEta><A/C><stationPhi>.
Gaudi::Property< std::vector< std::string > > m_excludeStat
MuonVal::ScalarBranch< std::string > & m_chamberDesign
MuonVal::ScalarBranch< unsigned short > & m_stIndex
Identifier of the readout element.
MuonVal::ScalarBranch< uint8_t > & m_numStripsEta
Number of strips, strip pitch in eta & phi direction.
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_detMgrKey
MuonDetectorManager from the conditions store.
MuonVal::MuonTesterTree m_tree
Write a TTree for validation purposes.
MuonVal::CoordTransformBranch m_readoutTransform
Transformation of the readout element (Translation, ColX, ColY, ColZ).
StatusCode execute(const EventContext &ctx) override
Execute method.
MuonVal::CoordSystemsBranch m_stripRot
Rotation matrix of the respective layers.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
StatusCode dumpToTree(const EventContext &ctx, const RpcReadoutElement *readoutEle)
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
virtual const Amg::Transform3D & transform() const override
Return local to global transform.
Identifier identify() const override final
Returns the ATLAS Identifier of the MuonReadOutElement.
double getALine_trat() const
const Amg::Transform3D & getNativeToAmdbLRS() const
double getALine_rott() const
double getALine_rots() const
const GeoAlignableTransform * getGeoTransform() const
bool hasALines() const
double getALine_tras() const
double getALine_rotz() const
double getALine_traz() const
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
int getDoubletPhi() const
return DoubletPhi value for the given readout element, be aware that one RE can contain two DoubletPh...
virtual bool stripPosition(const Identifier &id, Amg::Vector2D &pos) const override final
strip position If the strip number is outside the range of valid strips, the function will return fal...
int NphiStripPanels() const
returns the number of phi strip panels (1 or 2)
int getDoubletR() const
return DoubletR value for the given readout element
double StripLength(bool measphi) const
returns the strip length for the phi or eta plane
int getDoubletZ() const
return DoubletZ value for the given readout element
int Nstrips(bool measphi) const
returns the number of strips for the phi or eta plane
virtual int numberOfLayers(bool measphi=true) const override final
number of layers in phi/eta projection, same for eta/phi planes
double StripWidth(bool measphi) const
returns the strip width for the phi or eta plane
double StripPitch(bool measphi) const
returns the strip pitch for the phi or eta plane
const_id_iterator detectorElement_begin() const
Iterators over full set of ids.
const_id_iterator detectorElement_end() const
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
Identifier elementID(int stationName, int stationEta, int stationPhi, int doubletR) const
int doubletZ(const Identifier &id) const
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
virtual bool insideBounds(const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const =0
virtual methods to be overwritten by the inherited surfaces
virtual const SurfaceBounds & bounds() const =0
Surface Bounds method.
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const =0
Specified by each surface type: LocalToGlobal method without dynamic memory allocation.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
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.