ATLAS Offline Software
Loading...
Searching...
No Matches
RegionSelectorCondAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
5
6
10
11#include "Acts/Surfaces/PlanarBounds.hpp"
13
16
17namespace MuonR4{
19 ATH_CHECK(detStore()->retrieve(m_detMgr));
20 ATH_CHECK(m_tableKey.initialize());
21 ATH_CHECK(m_alignKey.initialize());
24 return StatusCode::SUCCESS;
25 }
26 template <typename Key_t,
27 typename... OtherKey_t>
28 StatusCode RegionSelectorCondAlg::addDependency(const EventContext& ctx,
31 OtherKey_t... others) const {
32 if (!key.empty()) {
33 SG::ReadCondHandle readHandle{key, ctx};
34 if (!readHandle.isValid()){
35 ATH_MSG_FATAL("Failed to retrieve "<<key.fullKey()<<".");
36 return StatusCode::FAILURE;
37 }
38 writeHandle.addDependency(readHandle);
39 }
40 if constexpr(sizeof...(others) > 0) {
41 ATH_CHECK(addDependency(ctx, writeHandle, others...));
42 }
43 return StatusCode::SUCCESS;
44 }
45
47 switch (type) {
48 using enum ActsTrk::DetectorType;
49 case Mdt:
50 return m_idHelperSvc->mdtIdHelper();
51 case Rpc:
52 return m_idHelperSvc->rpcIdHelper();
53 case Tgc:
54 return m_idHelperSvc->tgcIdHelper();
55 case Mm:
56 return m_idHelperSvc->mmIdHelper();
57 case sTgc:
58 return m_idHelperSvc->stgcIdHelper();
59 default:
60 THROW_EXCEPTION("Unknown detector type "<<ActsTrk::to_string(type));
61 }
62 }
63
64 std::set<std::uint32_t> RegionSelectorCondAlg::getRobIDs(const EventContext& ctx,
65 const Identifier& moduleID) const {
66
67 switch(m_idHelperSvc->technologyIndex(moduleID)) {
69 case MDT: {
70 const MuonMDT_CablingMap* cabling{};
71 if (!SG::get(cabling, m_cablingMdtKey, ctx).isSuccess()) {
72 THROW_EXCEPTION("Failed to load Mdt cabling "<<m_cablingMdtKey.fullKey());
73 }
74 return {cabling->getROBId(m_idHelperSvc->moduleHash(moduleID), msgStream())};
75 } case RPC: {
76 const Muon::RpcCablingMap* cabling{};
77 if (!SG::get(cabling, m_cablingRpcKey, ctx).isSuccess()) {
78 THROW_EXCEPTION("Failed to load Rpc cabling "<<m_cablingRpcKey.fullKey());
79 }
80 return {cabling->getROBId(m_idHelperSvc->moduleHash(moduleID), msgStream())};
81 } case TGC: {
82 SmartIF<MuonTGC_CablingSvc> cabling{Gaudi::svcLocator()->service("MuonTGC_CablingSvc")};
83 if (!cabling.isValid()) {
84 THROW_EXCEPTION("Failed to load Tgc cabling");
85 }
86 int subDetectorId{}, rodId{};
87 cabling->getReadoutIDfromElementID(moduleID, subDetectorId, rodId);
88 return {static_cast<std::uint32_t>(((0x0ff) & subDetectorId)<<16 | rodId)};
89 } case MM:
90 case STGC:{
92 m_idHelperSvc->stationNameString(moduleID),
93 static_cast<int8_t>(m_idHelperSvc->stationEta(moduleID)),
94 static_cast<uint8_t>(m_idHelperSvc->stationPhi(moduleID))};
95 return std::set<std::uint32_t>(robIdHelper.get_ids().begin(), robIdHelper.get_ids().end());
96 } default: {
97 THROW_EXCEPTION("Invalid identifier "<<m_idHelperSvc->toStringChamber(moduleID));
98 }
99 }
100 return {};
101 }
102
103 StatusCode RegionSelectorCondAlg::execute(const EventContext& ctx) const {
104 SG::WriteCondHandle writeHandle{m_tableKey, ctx};
105 if (writeHandle.isValid()) {
106 ATH_MSG_DEBUG("Region selector "<<m_tableKey<<" is still valid");
107 return StatusCode::SUCCESS;
108 }
111
112 auto writeCdo = std::make_unique<RegSelSiLUT>();
113 const ActsTrk::DetectorAlignStore* alignDeltas{nullptr};
114 ATH_CHECK(SG::get(alignDeltas, m_alignKey, ctx));
115
117 if (m_splitTrfCache) {
118 gctx.setStore(MuonGMR4::copyDeltas(*alignDeltas));
119 } else {
120 gctx.setStore(std::make_unique<ActsTrk::DetectorAlignStore>(*alignDeltas));
121 }
122 const MuonIdHelper& idHelper{getIdHelper(alignDeltas->detType)};
123
126 struct TempSelTable {
127 std::optional<double> centralPhi{};
128 double zMin{std::numeric_limits<double>::max()};
129 double zMax{-std::numeric_limits<double>::max()};
130 double rMin{std::numeric_limits<double>::max()};
131 double rMax{-std::numeric_limits<double>::max()};
132 double dPhiMin{std::numeric_limits<double>::max()};
133 double dPhiMax{-std::numeric_limits<double>::max()};
134
135 void update(const Amg::Vector3D& v) {
136 const double dPhi = xAOD::P4Helpers::deltaPhi(v.phi(), centralPhi.value_or(0.));
137 rMin = std::min(rMin, v.perp()); rMax = std::max(rMax, v.perp());
138 zMin = std::min(zMin, v.z()); zMax = std::max(zMax, v.z());
139 dPhiMin = std::min(dPhiMin, dPhi); dPhiMax = std::max(dPhiMax, dPhi);
140 }
141
142 };
143 std::vector<TempSelTable> luts(idHelper.module_hash_max());
144 IdentifierHash modHash{};
146 for (const MuonGMR4::MuonReadoutElement* reEle: m_detMgr->getAllReadoutElements(alignDeltas->detType)) {
147
148 const Acts::Surface& surface{reEle->surface()};
149
150 const double halfTck = 0.5*reEle->thickness();
151
152 std::vector<Amg::Vector3D> localVertices{};
153 localVertices.reserve(8);
154 ATH_MSG_VERBOSE(__LINE__<<" - Fetch edge points from surface: "<<m_idHelperSvc->toStringDetEl(reEle->identify()));
155 std::ranges::for_each(static_cast<const Acts::PlanarBounds&>(surface.bounds()).vertices(),
156 [&](const Amg::Vector2D& v){
157 ATH_MSG_VERBOSE(__LINE__<<" - Local vertex: "<<Amg::toString(v)<<", half thickness: "<<halfTck);
158 localVertices.emplace_back(v.x(), v.y(), halfTck);
159 localVertices.emplace_back(v.x(), v.y(), -halfTck);
160 });
161 ATH_MSG_VERBOSE(__LINE__<<" - Fetched "<<localVertices.size()<<" vertices.");
162 const Amg::Transform3D& loc2Glob{surface.transform(gctx.context())};
163 idHelper.get_module_hash(reEle->identify(), modHash);
164 auto& lut = luts.at(modHash);
165 if (!lut.centralPhi) {
166 lut.centralPhi = loc2Glob.translation().phi();
167 }
168 for (const Amg::Vector3D& locVtx : localVertices) {
169 const Amg::Vector3D globVtx = loc2Glob * locVtx;
170 ATH_MSG_VERBOSE(__LINE__<<" - Expand LUT with vertex "
171 <<std::format("{:.2f}/{:.2f}/{:.2f}", globVtx.perp(), globVtx.z(), globVtx.phi()));
172 lut.update(globVtx);
173 }
174 }
175 const auto modCtx = idHelper.module_context();
177 for (auto module_itr = idHelper.module_begin();
178 module_itr != idHelper.module_end(); ++module_itr) {
179 idHelper.get_module_hash(*module_itr, modHash);
180 const auto& lut = luts.at(modHash);
181
182 if(!lut.centralPhi) {
183 continue;
184 }
185
186 ExpandedIdentifier exp_id{};
187 if (idHelper.get_expanded_id(*module_itr, exp_id, &modCtx)) {
188 ATH_MSG_DEBUG(__LINE__<<" - Failed retrieving ExpandedIdentifier for PRD Identifier = "
189 << m_idHelperSvc->toString(*module_itr) << ". Skipping to the next PRD.");
190 continue;
191 }
192 const int detid = ( exp_id[2]<0 ? -1 : 1 );
193 const int layerid = exp_id[1]+1;
194
195 const double phiMin = lut.centralPhi.value_or(0) + lut.dPhiMin;
196 const double phiMax = lut.centralPhi.value_or(0) + lut.dPhiMax;
197
198
199 for (const std::uint32_t robID : getRobIDs(ctx, *module_itr)) {
200 RegSelModule m{lut.zMin, lut.zMax, lut.rMin, lut.rMax,
201 phiMin, phiMax, layerid, detid, robID, modHash};
202 ATH_MSG_VERBOSE(__LINE__<<" - Insert new entry "<<m_idHelperSvc->chamberNameString(*module_itr)
203 <<", "<<m);
204 writeCdo->addModule(m);
205 }
206 }
207
208 if (m_printTable) {
209 if (const auto *lut = dynamic_cast<const RegSelSiLUT*>(writeCdo.get())) {
210 lut->write(std::format("{:}.map", name()));
211 }
212 }
213
214 ATH_CHECK(writeHandle.record(std::make_unique<IRegSelLUTCondData>(std::move(writeCdo))));
215 return StatusCode::SUCCESS;
216 }
217}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
DetectorType detType
The aligned detector element type.
Acts::GeometryContext context() const
void setStore(AlignmentStorePtr store)
Adds the store to the Geometry context.
const ServiceHandle< StoreGateSvc > & detStore() const
static EventIDRange infiniteRunLB()
Produces an EventIDRange that is infinite in RunLumi and invalid in Time.
This is a "hash" representation of an Identifier.
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
const_id_iterator module_end() const
int get_expanded_id(const Identifier &id, ExpandedIdentifier &exp_id, const IdContext *context) const
Create expanded id from compact id (return == 0 for OK)
const_id_iterator module_begin() const
Iterators over full set of ids.
virtual int get_module_hash(const Identifier &id, IdentifierHash &hash_id) const
size_type module_hash_max() const
the maximum hash value
IdContext module_context() const
id for module
virtual StatusCode initialize() override final
Gaudi::Property< bool > m_printTable
const MuonGMR4::MuonDetectorManager * m_detMgr
Detector manager.
SG::ReadCondHandleKey< Muon::RpcCablingMap > m_cablingRpcKey
Dependency on the phase II Rpc cabling map.
Gaudi::Property< bool > m_splitTrfCache
Instantiate a new transform cache to ensure lazy transform population in the event processing.
const MuonIdHelper & getIdHelper(const ActsTrk::DetectorType type) const
Retrieve the idHelper for the given detector technology.
virtual StatusCode execute(const EventContext &ctx) const override final
SG::ReadCondHandleKey< ActsTrk::DetectorAlignStore > m_alignKey
Dependency on the alignment constants.
StatusCode addDependency(const EventContext &ctx, SG::WriteCondHandle< IRegSelLUTCondData > &writeHandle, const SG::ReadCondHandleKey< Key_t > &key, OtherKey_t... others) const
Declare the dependency of the region selector table on the other keys set.
SG::WriteCondHandleKey< IRegSelLUTCondData > m_tableKey
Region selector table written by the algorithm.
std::set< std::uint32_t > getRobIDs(const EventContext &ctx, const Identifier &moduleID) const
Returns the list of ROB ids associated with the module.
SG::ReadCondHandleKey< MuonMDT_CablingMap > m_cablingMdtKey
Dependency on the Mdt cabling map.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
const std::vector< uint32_t > & get_ids() const
void addDependency(const EventIDRange &range)
StatusCode record(const EventIDRange &range, T *t)
record handle, with explicit range DEPRECATED
std::string to_string(const DetectorType &type)
DetectorType
Simple enum to Identify the Type of the ACTS sub detector.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
std::unique_ptr< ActsTrk::DetectorAlignStore > copyDeltas(const ActsTrk::DetectorAlignStore &inStore)
Copy the alignment deltas from the inStore to a new alignment store.
This header ties the generic definitions in this package.
TechnologyIndex
enum to classify the different layers in the muon spectrometer
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition TgcBase.h:6
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10