ATLAS Offline Software
Loading...
Searching...
No Matches
MuonDetectorFactoryLite.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include "GaudiKernel/MsgStream.h"
8#include "GaudiKernel/SystemOfUnits.h"
10#include "GeoModelKernel/GeoFullPhysVol.h"
11#include "GeoModelKernel/GeoPerfUtils.h"
12#include "GeoModelKernel/GeoPhysVol.h"
13#include "MuonGeoModel/MYSQL.h"
17
22
23namespace MuonGM {
24
25 // Helper function to retrieve ID Helpers:
26 template <class T>
27 const T *getIdHelper (StoreGateSvc *pDetStore, const std::string & helperName) {
28 const T *helper;
29 StatusCode sc = pDetStore->retrieve(helper, helperName);
30 if (sc.isFailure()) {
31 return nullptr;
32 }
33 else {
34 return helper;
35 }
36 };
37
38
39
40
41 MuonDetectorFactoryLite::MuonDetectorFactoryLite(StoreGateSvc *pDetStore, GeoModelIO::ReadGeoModel *sqliteReader):
42 m_pDetStore{pDetStore},
43 m_sqliteReader(sqliteReader) {
44 }
45
47
50
52
53 std::map<std::string, GeoAlignableTransform*> mapAXF = m_sqliteReader->getPublishedNodes<std::string, GeoAlignableTransform*>("MuonSys");
54 std::map<std::string, GeoFullPhysVol*> mapFPV = m_sqliteReader->getPublishedNodes<std::string, GeoFullPhysVol*>("MuonSys");
55
56 MsgStream log(Athena::getMessageSvc(), "MuGM:MuonFactory");
57
59
60
61
62
63
64 // Iterate using iterator in for loop
65 for (const auto& [key, pV] : mapFPV) {
66 if (key.starts_with ("sMD") || key.starts_with ("sTG")) {
67 int /*index1=key[3]-'0',*/ eta=key[5]-'0', ml=key[7]-'0', phi=key[12]-'0';
68
69 char AC=key[13];
70 int ec = AC=='C' ? -1 : 1;
71 std::string vName = pV->getLogVol()->getName();
72 if (key.starts_with("sMD")) {
73 std::string sName = vName.substr(4,4);
74 std::unique_ptr<MuonGM::MMReadoutElement> re = std::make_unique<MuonGM::MMReadoutElement>(pV, sName, ec*eta,phi,ml,m_manager);
75 re->initDesign();
76 m_manager->addMMReadoutElement(std::move(re));
77 }
78 else if (key.starts_with("sTG")) {
79 std::string sName = vName.substr(7,4);
80 std::unique_ptr<sTgcReadoutElement> re = std::make_unique<sTgcReadoutElement>(pV, sName, ec*eta, phi, ml, m_manager);
81 re->initDesign(2.6);
82 m_manager->addsTgcReadoutElement(std::move(re));
83 }
84 }
85 }
86
87
88
89 // here create the MYSQL singleton
91 mysql->set_amdb_from_RDB(true);
92
93 std::unique_ptr<RDBReaderAtlas> dbr;
94 {
95 // We never alter these in the "Lite" workflow
96 std::string oracleTag="";
97 std::string oracleNode="";
98 std::map<std::string, std::string> ascii{};
99 dbr = std::make_unique<RDBReaderAtlas>(m_pDetStore, m_pRDBAccess, oracleTag, oracleNode, ascii);
100
101
102 }
103
104
105
106 // set here the flag deciding whether to include cutouts:
107 // m_includeCutouts = 1 => include cutouts
108 // m_includeCutouts = 0 => no cutouts
109 m_manager->setCutoutsFlag(true);
110 m_manager->setCutoutsBogFlag(true);
111
112
113 StatusCode sc = StatusCode::SUCCESS;
114
115 dbr->setManager(getDetectorManager());
116 sc = dbr->ProcessDB(*mysql);
117 if (sc != StatusCode::SUCCESS) {
118 log << MSG::ERROR << " FAILURE in DB access; Muon node will not be built" << endmsg;
119 return;
120 }
121
122 GeoFullPhysVol *p4 = mapFPV["MuonTreeTop"];
123 m_manager->addTreeTop(p4); // This is the top!
124 log << MSG::INFO << " TreeTop added to the Manager" << endmsg;
125
126 // Look through the map explicitly for Stations
127 std::set<std::string> mappedStations;
128 for (const auto& i: mapFPV) {
129 size_t pos=i.first.find("_Station");
130 if (pos!=std::string::npos) mappedStations.insert(i.first.substr(0,pos));
131 }
132
133 // Boudreau Jan 2024 Keep track of instantiated readout geometries. This is
134 // needed because the muon geometry is rebuild multiple times in current
135 // implementation.
136 std::set<std::string> keyset;
137
138 for (const auto& i: mappedStations) {
139 auto it= mysql->stationMap().find(i);
140 if (it==mysql->stationMap().end()) {
141 throw std::runtime_error("Raw/readout geometry mismatch");
142 }
143
144 Station *station = (*it).second.get();
145 std::string stname(station->GetName(), 0, 3);
146
147 bool isAssembly = false;
148 if (station->GetNrOfCutouts() > 0 && stname.substr(0, 1) != "T")
149 isAssembly = true;
150
151 // BIR have multilayers of diff. length and overall station volume clashes with toroids
152 if (stname == "BIR")
153 isAssembly = true;
154
155 MuonChamberLite l(*mysql, station,&mapFPV,&mapAXF); // here is where we start to create a MuonChamber with all readoutelements
156 l.setKeyset(&keyset);
157
159 AlignPos ap;
160 for ( auto const& [key, position] : *station) {
161 int zi = position.zindex;
162 int fi = position.phiindex;
163
164 // here build the physical volume (tree) associated to the chamber
165 if (stname == "CSL") isAssembly = true;
166
167 // CSL because coffin shape of the station mother volume
168 l.addReadoutLayers(*mysql, getDetectorManager(), zi, fi, position.isMirrored, isAssembly);
169
170 // here define the GeoAlignableTransform associated to the chamber
171 // nominal transform first
172 GeoAlignableTransform *xf = mapAXF[station->GetName()+"_Station_"+std::to_string(zi)+"_"+std::to_string(fi)];
173 // alignment issues and readout geometry for station
174 MuonStation *mst = m_manager->getMuonStation(station->GetName(), zi, fi + 1);
175 if (!mst) {
176 log << MSG::WARNING << "For Station with nameTag=<" << station->GetName() << "> at zi/fi = " << zi << "/" << fi
177 << " no MuonStation found => no possibility to align" << endmsg;
178 continue;
179 }
180 mst->setTransform(xf);
181 GeoTrf::Transform3D tsz_to_szt = GeoTrf::RotateZ3D(-90 * Gaudi::Units::degree) * GeoTrf::RotateY3D(-90 * Gaudi::Units::degree);
182 GeoTrf::Transform3D nativeToAmdbLRS=tsz_to_szt * station->native_to_tsz_frame(*mysql, position);
183 mst->setNativeToAmdbLRS(nativeToAmdbLRS);
184 mst->setNominalAmdbLRSToGlobal(station->tsz_to_global_frame(*mysql, position) * tsz_to_szt.inverse());
185
186 int nAlines = station->CountAlignPos(zi, fi);
187 if (nAlines == 0) {
188 ap.tras = ap.traz = ap.trat = ap.rots = ap.rotz = ap.rott = 0.;
189 ap.jobindex = 0;
190 mst->setDelta_fromAline(ap.tras, ap.traz, ap.trat, ap.rots, ap.rotz, ap.rott);
191 } else if (nAlines > 0) {
192 AlignPosIterator alast;
193 AlignPosIterator afirst = station->getFirstAlignPosInRange(zi, fi, alast);
194
195 for (AlignPosIterator acurrent = afirst; acurrent != alast; ++acurrent) {
196 ap = acurrent->second;
197 if (ap.phiindex != fi || ap.zindex != zi) {
198 log << MSG::ERROR << "Inconsistent AlignedPosition found in the static Geometry DB: aligPos.fi, zi = " << ap.phiindex << ", " << ap.zindex
199 << " for station " << station->GetName() << " at fi/zi = " << fi << "/" << zi << " AlignPos indices fi/zi " << fi << "/" << zi << endmsg;
200 }
201 GeoTrf::Transform3D tsz_to_szt = GeoTrf::RotateZ3D(-90 * Gaudi::Units::degree) * GeoTrf::RotateY3D(-90 * Gaudi::Units::degree);
202 // Keep, for later developments. GeoTrf::Transform3D nominalTransform=station->getNominalTransform(*mysql, position);
203 // Keep, for later developments. GeoTrf::Transform3D native_to_amdbl=tsz_to_szt * station->native_to_tsz_frame(*mysql, position);
204 mst->setTransform(xf);
205 mst->setNativeToAmdbLRS(tsz_to_szt * station->native_to_tsz_frame(*mysql, position));
206 mst->setNominalAmdbLRSToGlobal(station->tsz_to_global_frame(*mysql, position) * tsz_to_szt.inverse());
207 mst->setDeltaAmdbLRS(GeoTrf::Transform3D::Identity());
208 }
209 }
210 } // end loop on positions
211 } // for ( it = sel.begin(); it != sel.end(); it++ ) {
212 delete mysql.get();
213 } // MuonDetectorFactoryLite::create
214
215} // namespace MuonGM
const boost::regex re(r_e)
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
static Double_t sc
void set_amdb_from_RDB(bool)
Definition MYSQL.cxx:268
const StationMap & stationMap() const
Definition MYSQL.cxx:227
static LockedMYSQL GetPointer()
Definition MYSQL.cxx:42
CxxUtils::LockedPointer< MYSQL > LockedMYSQL
Definition MYSQL.h:47
virtual void create(GeoPhysVol *world) override
MuonDetectorFactoryLite(StoreGateSvc *pDetStore, GeoModelIO::ReadGeoModel *sqliteReader)
GeoModelIO::ReadGeoModel * m_sqliteReader
virtual const MuonDetectorManager * getDetectorManager() const override
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
void setDeltaAmdbLRS(Amg::Transform3D xf)
set the delta transform in the amdb frame and update the geoModel Delta
void setNominalAmdbLRSToGlobal(Amg::Transform3D xf)
void setDelta_fromAline(double, double, double, double, double, double)
set the delta transform in the amdb frame and update the geoModel Delta
void setTransform(GeoAlignableTransform *xf)
void setNativeToAmdbLRS(Amg::Transform3D xf)
GeoTrf::Transform3D native_to_tsz_frame(const MYSQL &mysql, const Position &p) const
Definition Station.cxx:371
int CountAlignPos(int iz, int iphi) const
Definition Station.cxx:69
const std::string & GetName() const
Definition Station.cxx:110
int GetNrOfCutouts() const
Definition Station.cxx:324
AlignPosIterator getFirstAlignPosInRange(int iz, int iphi, AlignPosIterator &lastAlignPosInRange) const
Definition Station.cxx:55
GeoTrf::Transform3D tsz_to_global_frame(const MYSQL &mysql, const Position &p) const
Definition Station.cxx:430
The Athena Transient Store API.
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
singleton-like access to IMessageSvc via open function and helper
IMessageSvc * getMessageSvc(bool quiet=false)
Ensure that the Athena extensions are properly loaded.
Definition GeoMuonHits.h:27
std::multimap< int, AlignPos, std::less< int > >::const_iterator AlignPosIterator
Definition Station.h:38
std::map< int, Position, std::less< int > >::const_iterator PositionIterator
Definition Station.h:37
const T * getIdHelper(StoreGateSvc *pDetStore, const std::string &helperName)