ATLAS Offline Software
Loading...
Searching...
No Matches
MuonDetDescr/MuonGeoModelTest/src/GeoModelMdtTest.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 "GeoModelMdtTest.h"
5
6#include <fstream>
7#include <iostream>
8
12namespace MuonGM {
13
14std::ostream& operator<<(std::ostream& ostr, const Amg::Transform3D& trans){
15 ostr<<Amg::toString(trans, 3);
16 return ostr;
17}
19 ATH_CHECK(m_detMgrKey.initialize());
20 ATH_CHECK(m_cablingKey.initialize(!m_cablingKey.empty()));
21 ATH_CHECK(m_idHelperSvc.retrieve());
22 ATH_CHECK(m_tree.init(this));
23
24 const MdtIdHelper& idHelper{m_idHelperSvc->mdtIdHelper()};
25 auto translateTokenList = [this, &idHelper](const std::vector<std::string>& chNames){
26
27 std::set<Identifier> transcriptedIds{};
28 for (const std::string& token : chNames) {
29 if (token.size() != 6) {
30 ATH_MSG_WARNING("Wrong format given for "<<token<<". Expecting 6 characters");
31 continue;
32 }
34 const std::string statName = token.substr(0, 3);
35 const unsigned statEta = std::atoi(token.substr(3, 1).c_str()) * (token[4] == 'A' ? 1 : -1);
36 const unsigned statPhi = std::atoi(token.substr(5, 1).c_str());
37 bool isValid{false};
38 const Identifier eleId = idHelper.elementID(statName, statEta, statPhi, isValid);
39 if (!isValid) {
40 ATH_MSG_WARNING("Failed to deduce a station name for " << token);
41 continue;
42 }
43 transcriptedIds.insert(eleId);
44 const Identifier secMlId = idHelper.multilayerID(eleId, 2, isValid);
45 if (isValid){
46 transcriptedIds.insert(secMlId);
47 }
48 }
49 return transcriptedIds;
50 };
51
52 std::vector <std::string>& selectedSt = m_selectStat.value();
53 const std::vector <std::string>& excludedSt = m_excludeStat.value();
54 selectedSt.erase(std::remove_if(selectedSt.begin(), selectedSt.end(),
55 [&excludedSt](const std::string& token){
56 return std::ranges::find(excludedSt, token) != excludedSt.end();
57 }), selectedSt.end());
58
59 if (selectedSt.size()) {
60 m_testStations = translateTokenList(selectedSt);
61 std::stringstream sstr{};
62 for (const Identifier& id : m_testStations) {
63 sstr<<" *** "<<m_idHelperSvc->toString(id)<<std::endl;
64 }
65 ATH_MSG_INFO("Test only the following stations "<<std::endl<<sstr.str());
66 } else {
67 const std::set<Identifier> excluded = translateTokenList(excludedSt);
69 for(auto itr = idHelper.detectorElement_begin();
70 itr!= idHelper.detectorElement_end();++itr){
71 if (!excluded.count(*itr)) {
72 m_testStations.insert(*itr);
73 }
74 }
76 if (!excluded.empty()) {
77 std::stringstream excluded_report{};
78 for (const Identifier& id : excluded){
79 excluded_report << " *** " << m_idHelperSvc->toStringDetEl(id) << std::endl;
80 }
81 ATH_MSG_INFO("Test all station except the following excluded ones " << std::endl << excluded_report.str());
82 }
83 }
84 return StatusCode::SUCCESS;
85}
87 const EventContext& ctx{Gaudi::Hive::currentContext()};
89 if (!detMgr.isValid()) {
90 ATH_MSG_FATAL("Failed to retrieve MuonDetectorManager "
91 << m_detMgrKey.fullKey());
92 return StatusCode::FAILURE;
93 }
94
95 for (const Identifier& test_me : m_testStations) {
96 const std::string detStr = m_idHelperSvc->toStringDetEl(test_me);
97 ATH_MSG_VERBOSE("Test retrieval of Mdt detector element " << detStr);
98 const MdtReadoutElement* reElement = detMgr->getMdtReadoutElement(test_me);
99 if (!reElement) {
100 ATH_MSG_VERBOSE("Detector element is invalid");
101 continue;
102 }
104 if (reElement->identify() != test_me) {
105 ATH_MSG_FATAL("Expected to retrieve "
106 << detStr << ". But got instead "
107 << m_idHelperSvc->toStringDetEl(reElement->identify()));
108 return StatusCode::FAILURE;
109 }
110 ATH_CHECK(dumpToTree(ctx, reElement));
111 }
112 return StatusCode::SUCCESS;
113}
115 ATH_CHECK(m_tree.write());
116 return StatusCode::SUCCESS;
117}
118StatusCode GeoModelMdtTest::dumpToTree(const EventContext& ctx, const MdtReadoutElement* readoutEle) {
119 m_stIndex = readoutEle->getStationIndex();
120 m_stEta = readoutEle->getStationEta();
121 m_stPhi = readoutEle->getStationPhi();
122 m_stML = readoutEle->getMultilayer();
123 m_chamberDesign = readoutEle->getTechnologyName();
124
125 m_numTubes = readoutEle->getNtubesperlayer();
126 m_numLayers = readoutEle->getNLayers();
127
128 m_tubeRad = readoutEle->innerTubeRadius();
129 m_tubePitch = readoutEle->tubePitch();
130
131 const MuonGM::MuonStation* station = readoutEle->parentMuonStation();
132 m_alignableNode = station->getGeoTransform()->getDefTransform() *
133 station->getNativeToAmdbLRS().inverse();
134 if (station->hasALines()){
135 m_ALineTransS = station->getALine_tras();
136 m_ALineTransT = station->getALine_traz();
137 m_ALineTransZ = station->getALine_trat();
138 m_ALineRotS = station->getALine_rots();
139 m_ALineRotT = station->getALine_rotz();
140 m_ALineRotZ = station->getALine_rott();
141 }
142 const BLinePar* bline = readoutEle->getBLinePar();
143 if (bline) {
144 using Parameter = BLinePar::Parameter;
145 m_BLineBz = bline->getParameter(Parameter::bz);
146 m_BLineBp = bline->getParameter(Parameter::bp);
147 m_BLineBn = bline->getParameter(Parameter::bn);
148 m_BLineSp = bline->getParameter(Parameter::sp);
149 m_BLineSn = bline->getParameter(Parameter::sn);
150 m_BLineTw = bline->getParameter(Parameter::tw);
151 m_BLinePg = bline->getParameter(Parameter::pg);
152 m_BLineTr = bline->getParameter(Parameter::tr);
153 m_BLineEg = bline->getParameter(Parameter::eg);
154 m_BLineEp = bline->getParameter(Parameter::ep);
155 m_BLineEn = bline->getParameter(Parameter::en);
156 }
157
158 if (station->hasMdtAsBuiltParams()) {
159 const MdtAsBuiltPar* asBuilt = station->getMdtAsBuiltParams();
160 using multilayer_t = MdtAsBuiltPar::multilayer_t;
161 using tubeSide_t = MdtAsBuiltPar::tubeSide_t;
162 const multilayer_t asBuiltMl = readoutEle->getMultilayer() == 1 ? multilayer_t::ML1 : multilayer_t::ML2;
163 m_asBuiltPosY0 = asBuilt->y0(asBuiltMl, tubeSide_t::POS);
164 m_asBuiltPosZ0 = asBuilt->z0(asBuiltMl, tubeSide_t::POS);
165 m_asBuiltPosAlpha = asBuilt->alpha (asBuiltMl, tubeSide_t::POS);
166 m_asBuiltPosPitchY = asBuilt->ypitch(asBuiltMl, tubeSide_t::POS);
167 m_asBuiltPosPitchZ = asBuilt->zpitch(asBuiltMl, tubeSide_t::POS);
168 m_asBuiltPosStagg = asBuilt->stagg (asBuiltMl, tubeSide_t::POS);
169
170 m_asBuiltNegY0 = asBuilt->y0(asBuiltMl, tubeSide_t::NEG);
171 m_asBuiltNegZ0 = asBuilt->z0(asBuiltMl, tubeSide_t::NEG);
172 m_asBuiltNegAlpha = asBuilt->alpha (asBuiltMl, tubeSide_t::NEG);
173 m_asBuiltNegPitchY = asBuilt->ypitch(asBuiltMl, tubeSide_t::NEG);
174 m_asBuiltNegPitchZ = asBuilt->zpitch(asBuiltMl, tubeSide_t::NEG);
175 m_asBuiltNegStagg = asBuilt->stagg (asBuiltMl, tubeSide_t::NEG);
176 }
177
178 const MuonMDT_CablingMap* cabling{nullptr};
179 ATH_CHECK(SG::get(cabling, m_cablingKey, ctx));
180 m_readoutTransform = readoutEle->getMaterialGeom()->getAbsoluteTransform();
181
182 const MdtIdHelper& id_helper{m_idHelperSvc->mdtIdHelper()};
183
184 for (int lay = 1; lay <= readoutEle->getNLayers(); ++lay) {
185 for (int tube = 1; tube <= readoutEle->getNtubesperlayer(); ++tube) {
186 bool is_valid{false};
187 const Identifier tube_id =id_helper.channelID(readoutEle->identify(),
188 readoutEle->getMultilayer(),
189 lay, tube, is_valid);
190 if (!is_valid) continue;
191 if (m_idHelperSvc->stationNameString(tube_id) == "BMG") {
192 try{
193 readoutEle->transform(tube_id);
194 } catch (const std::runtime_error& err ){
195 ATH_MSG_VERBOSE("Tube does not exist "<<err.what());
196 continue;
197 }
198 }
199 const Amg::Transform3D layTransf{readoutEle->transform(tube_id)};
200 m_tubeLay.push_back(lay);
201 m_tubeNum.push_back(tube);
202
203 m_tubeTransform.push_back(layTransf);
204
205 const Amg::Vector3D roPos = readoutEle->ROPos(tube_id);
206 m_roPos.push_back(roPos);
207 m_activeTubeLength.push_back(readoutEle->getActiveTubeLength(lay,tube));
208 m_tubeLength.push_back(readoutEle->tubeLength(tube_id));
209 m_wireLength.push_back(readoutEle->getWireLength(lay, tube));
210 if (cabling) {
211 MdtCablingData translation{};
212 if (!cabling->convert(tube_id, translation) ||
213 !cabling->getOnlineId(translation, msgStream())){
214 ATH_MSG_FATAL("Cabling translation failed");
215 return StatusCode::FAILURE;
216 }
217 m_cablingCSM.push_back(translation.csm);
218 m_cablingMROD.push_back(translation.mrod);
219 m_cablingTdcId.push_back(translation.tdcId);
220 m_cablingTdcCh.push_back(translation.channelId);
221 }
222 }
223 }
224 return m_tree.fill(ctx) ? StatusCode::SUCCESS : StatusCode::FAILURE;
225}
226} // namespace MuonGM
#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
float getParameter(const Parameter p) const
Returns a given parameter.
Definition BLinePar.h:40
Container classifier the MDT as-built parameters See parameter description in http://atlas-muon-align...
int stagg(multilayer_t iML, tubeSide_t iTubeSide) const
double zpitch(multilayer_t iML, tubeSide_t iTubeSide) const
double ypitch(multilayer_t iML, tubeSide_t iTubeSide) const
double alpha(multilayer_t iML, tubeSide_t iTubeSide) const
multilayer_t
MDT multi-layer index.
tubeSide_t
MDT tube side.
double z0(multilayer_t iML, tubeSide_t iTubeSide) const
double y0(multilayer_t iML, tubeSide_t iTubeSide) const
Identifier multilayerID(const Identifier &channeldID) const
Identifier elementID(int stationName, int stationEta, int stationPhi) const
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int tubeLayer, int tube) const
MuonVal::VectorBranch< unsigned short > & m_tubeLay
Readout each tube specifically.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
MuonVal::ScalarBranch< unsigned short > & m_numLayers
Number of tubes per layer.
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_detMgrKey
std::set< Identifier > m_testStations
Set of stations to be tested.
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 underlying GeoModel element (Translation, ColX, ColY, ColZ)
SG::ReadCondHandleKey< MuonMDT_CablingMap > m_cablingKey
MuonVal::ThreeVectorBranch m_roPos
Position of the readout.
MuonVal::CoordSystemsBranch m_tubeTransform
Ideal transformations to the tube rest frame.
MuonVal::ScalarBranch< std::string > & m_chamberDesign
MuonVal::ScalarBranch< float > & m_ALineTransS
Alignment parameters.
MuonVal::MuonTesterTree m_tree
Write a TTree for validation purposes.
StatusCode dumpToTree(const EventContext &ctx, const MdtReadoutElement *readoutEle)
MuonVal::VectorBranch< uint8_t > & m_cablingCSM
Cabling information.
MuonVal::ScalarBranch< unsigned short > & m_stIndex
Identifier of the readout element.
MuonVal::ScalarBranch< unsigned short > & m_numTubes
Number of tubes per layer.
MuonVal::ScalarBranch< float > & m_BLineBz
B Line chamber defomrations.
MuonVal::VectorBranch< unsigned short > & m_tubeNum
MuonVal::ScalarBranch< float > & m_asBuiltPosY0
AS-built parameters.
Gaudi::Property< std::vector< std::string > > m_excludeStat
double getActiveTubeLength(const int tubeLayer, const int tube) const
Amg::Vector3D ROPos(const int tubelayer, const int tube) const
int getNLayers() const
Returns the number of tube layers inside the multilayer.
int getMultilayer() const
Returns the multilayer represented by the readout element.
virtual const Amg::Transform3D & transform(const Identifier &id) const override final
Return local to global transform associated with this identifier.
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
double tubePitch() const
Returns the distance between 2 tubes in a tube layer.
double innerTubeRadius() const
Returns the inner tube radius excluding the aluminium walls.
double tubeLength(const int tubeLayer, const int tube) const
double getWireLength(const int tubeLayer, const int tube) const
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
const MdtAsBuiltPar * getMdtAsBuiltParams() const
bool hasALines() const
double getALine_tras() const
double getALine_rotz() const
bool hasMdtAsBuiltParams() const
double getALine_traz() const
const_id_iterator detectorElement_begin() const
Iterators over full set of ids.
const_id_iterator detectorElement_end() const
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the Athena extensions are properly loaded.
Definition GeoMuonHits.h:27
std::ostream & operator<<(std::ostream &os, const AlignPos &p)
Definition AlignPos.cxx:8
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.
uint8_t tdcId
Mezzanine type.
uint8_t channelId
Identifier of the corresponding tdc.
uint8_t & csm
MROD number.