ATLAS Offline Software
Loading...
Searching...
No Matches
xAODToTracccMeasurementConverterAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
5
9
12
13#include <algorithm>
14#include <limits>
15#include <memory>
16#include <numeric>
17
18namespace ActsTrk {
19
21{
22 ATH_MSG_DEBUG("Initializing.");
23
26
27 ATH_CHECK(m_outputMeasKey.initialize());
30
31 ATH_CHECK(m_MRs.retrieve());
32 ATH_CHECK(m_copiesTool.retrieve());
33
34 ATH_CHECK(detStore()->retrieve(m_pixelID, "PixelID"));
35 ATH_CHECK(detStore()->retrieve(m_stripID, "SCT_ID"));
38 ATH_CHECK(m_hostCondKey.initialize());
39
40 ATH_MSG_DEBUG("Successfully initialized");
41 return StatusCode::SUCCESS;
42}
43
45 const Identifier& moduleId, unsigned int& condIndex) const
46{
47 const auto detrayIdOpt = m_geoIdMapping->athenaToDetray(moduleId);
48 if (!detrayIdOpt.has_value()) {
49 ATH_MSG_ERROR("No detray id found for Athena identifier " << moduleId);
50 return StatusCode::FAILURE;
51 }
52 const auto condIndexOpt = m_geoIdMapping->detrayToDetDescIndex(*detrayIdOpt);
53 if (!condIndexOpt.has_value()) {
54 ATH_MSG_ERROR("No detray conditions entry found for detray id " << *detrayIdOpt);
55 return StatusCode::FAILURE;
56 }
57 condIndex = static_cast<unsigned int>(*condIndexOpt);
58 return StatusCode::SUCCESS;
59}
60
61StatusCode xAODToTracccMeasurementConverterAlg::execute(const EventContext& ctx) const
62{
63 using size_type = traccc::edm::measurement_collection::buffer::size_type;
64 constexpr unsigned int invalidIndex = std::numeric_limits<unsigned int>::max();
65
66 auto pixelClusters = SG::makeHandle(m_inputPixelClustersKey, ctx);
67 ATH_CHECK(pixelClusters.isValid());
68 auto stripClusters = SG::makeHandle(m_inputStripClustersKey, ctx);
69 ATH_CHECK(stripClusters.isValid());
70
72 ATH_CHECK(hostCondHandle.isValid());
73 const traccc::detector_conditions_description::host& hostCond = **hostCondHandle;
74
75 const unsigned int nPixel = pixelClusters->size();
76 const unsigned int nStrip = stripClusters->size();
77 const size_type nMeas = nPixel + nStrip;
78 ATH_MSG_DEBUG("Found " << nPixel << " pixel clusters and " << nStrip
79 << " strip clusters, total " << nMeas << " clusters");
80
81 std::vector<MeasurementRecord> records;
82 records.reserve(nMeas);
83
84 for (const xAOD::PixelCluster* cl : *pixelClusters) {
86 rec.isPixel = true;
87 rec.hostIndex = cl->index();
88 const Identifier moduleId = m_pixelID->wafer_id(IdentifierHash{cl->identifierHash()});
89 ATH_CHECK(condIndexFor(moduleId, rec.condIndex));
90 rec.geometryId = hostCond.geometry_id()[rec.condIndex].value();
91 const auto locPos = cl->localPosition<2>();
92 const auto locCov = cl->localCovariance<2>();
93 rec.localPosition = {locPos(0, 0), locPos(1, 0)};
94 rec.localVariance = {locCov(0, 0), locCov(1, 1)};
95 rec.diameter = cl->widthInEta();
96 records.push_back(rec);
97 }
98
99 for (const xAOD::StripCluster* cl : *stripClusters) {
101 rec.isPixel = false;
102 rec.hostIndex = cl->index();
103 const Identifier moduleId = m_stripID->wafer_id(IdentifierHash{cl->identifierHash()});
104 ATH_CHECK(condIndexFor(moduleId, rec.condIndex));
105 rec.geometryId = hostCond.geometry_id()[rec.condIndex].value();
106
107 // The measured coordinate is given by the module subspace, the other
108 // coordinate is set to the centre of the module design
109 const unsigned int designIdx = hostCond.module_to_design_id()[rec.condIndex];
110 const unsigned int measuredAxis = static_cast<unsigned int>(m_hostDesign->subspace()[designIdx][0]);
111 const unsigned int otherAxis = (measuredAxis == 0u) ? 1u : 0u;
112 const auto& otherEdges = (otherAxis == 0u) ? m_hostDesign->bin_edges_x()[designIdx]
113 : m_hostDesign->bin_edges_y()[designIdx];
114 float otherCentre = 0.f;
115 float otherVariance = 0.f;
116 if (!otherEdges.empty()) {
117 const float width = otherEdges.back() - otherEdges.front();
118 otherCentre = 0.5f * (otherEdges.front() + otherEdges.back());
119 otherVariance = width * width / 12.f;
120 }
121
122 const auto locPos = cl->localPosition<1>();
123 const auto locCov = cl->localCovariance<1>();
124 rec.localPosition[measuredAxis] = locPos(0, 0);
125 rec.localVariance[measuredAxis] = locCov(0, 0);
126 rec.localPosition[otherAxis] = otherCentre;
127 rec.localVariance[otherAxis] = otherVariance;
128 records.push_back(rec);
129 }
130
131 // The traccc track finding requires the measurements to be sorted by surface
132 std::vector<unsigned int> order(records.size());
133 std::iota(order.begin(), order.end(), 0u);
134 std::sort(order.begin(), order.end(), [&records](unsigned int lhs, unsigned int rhs) {
135 const MeasurementRecord& a = records[lhs];
136 const MeasurementRecord& b = records[rhs];
137 if (a.geometryId != b.geometryId) return a.geometryId < b.geometryId;
138 if (a.localPosition[0] != b.localPosition[0]) return a.localPosition[0] < b.localPosition[0];
139 return a.localPosition[1] < b.localPosition[1];
140 });
141
142 std::pmr::memory_resource* hostMR = m_MRs->hostMR();
143 auto hostCopy = m_copiesTool->hostCopy(ctx);
144 auto measHostBuffer = std::make_unique<traccc::edm::measurement_collection::buffer>(
145 nMeas, hostMR ? *hostMR : m_MRs->mainMR());
146 hostCopy->setup(*measHostBuffer)->wait();
147
148 // Create a "device" collection around the buffer to work on it
149 traccc::edm::measurement_collection::device measurements{*measHostBuffer};
150
151 auto measToPixel = std::make_unique<std::vector<unsigned int>>(nMeas, invalidIndex);
152 auto measToStrip = std::make_unique<std::vector<unsigned int>>(nMeas, invalidIndex);
153
154 // The traccc buffers are not default initialized: all members must be set.
155 for (size_type i = 0; i < nMeas; ++i) {
156 const MeasurementRecord& rec = records[order[i]];
157 const unsigned int designIdx = hostCond.module_to_design_id()[rec.condIndex];
158
159 auto meas = measurements.at(i);
160 meas.local_position() = rec.localPosition;
161 meas.local_variance() = rec.localVariance;
162 meas.dimensions() = static_cast<unsigned int>(m_hostDesign->dimensions()[designIdx]);
163 meas.time() = 0.f;
164 meas.diameter() = rec.diameter;
165 meas.identifier() = i;
166 meas.surface_link() = hostCond.geometry_id()[rec.condIndex];
167 meas.set_subspace(m_hostDesign->subspace()[designIdx]);
168 meas.cluster_index() = rec.hostIndex;
169
170 if (rec.isPixel) {
171 (*measToPixel)[i] = rec.hostIndex;
172 } else {
173 (*measToStrip)[i] = rec.hostIndex;
174 }
175 }
176
177 auto measHandle = SG::makeHandle(m_outputMeasKey, ctx);
178 if (hostMR) {
179 auto deviceCopy = m_copiesTool->deviceCopy(ctx);
180 auto measDeviceBuffer = std::make_unique<traccc::edm::measurement_collection::buffer>(
181 measHostBuffer->capacity(), m_MRs->mainMR());
182
183 // We ignore() the setup and wait() on the copy to allow parallelism.
184 deviceCopy->setup(*measDeviceBuffer)->ignore();
185 (*deviceCopy)(*measHostBuffer, *measDeviceBuffer)->wait();
186 ATH_CHECK(measHandle.record(std::move(measDeviceBuffer)));
187 } else {
188 ATH_CHECK(measHandle.record(std::move(measHostBuffer)));
189 }
190
191 auto measToPixelHandle = SG::makeHandle(m_outputMeasToPixelKey, ctx);
192 ATH_CHECK(measToPixelHandle.record(std::move(measToPixel)));
193 auto measToStripHandle = SG::makeHandle(m_outputMeasToStripKey, ctx);
194 ATH_CHECK(measToStripHandle.record(std::move(measToStrip)));
195
196 m_nPixel += nPixel;
197 m_nStrip += nStrip;
198
199 ATH_MSG_DEBUG("Wrote " << nMeas << " measurements to '"
200 << m_outputMeasKey.key() << "'");
201 return StatusCode::SUCCESS;
202}
203
205{
206 ATH_MSG_DEBUG("Finalizing.");
207
208 ATH_MSG_INFO("Converted total number of pixel clusters = " << m_nPixel
209 << " and total number of strip clusters = " << m_nStrip);
210
211 return StatusCode::SUCCESS;
212}
213
214} // namespace ActsTrk
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
const double width
SG::ReadCondHandleKey< traccc::detector_conditions_description::host > m_hostCondKey
StatusCode condIndexFor(const Identifier &moduleId, unsigned int &condIndex) const
Look up the traccc conditions index for an Athena module identifier.
ToolHandle< AthDevice::IMemoryResourcesTool > m_MRs
virtual StatusCode finalize() override
Function finalizing the algorithm.
SG::ReadHandleKey< xAOD::StripClusterContainer > m_inputStripClustersKey
virtual StatusCode initialize() override
Function initializing the algorithm.
SG::WriteHandleKey< std::vector< unsigned int > > m_outputMeasToPixelKey
SG::ReadHandleKey< xAOD::PixelClusterContainer > m_inputPixelClustersKey
SG::WriteHandleKey< traccc::edm::measurement_collection::buffer > m_outputMeasKey
const traccc::detector_design_description::host * m_hostDesign
SG::WriteHandleKey< std::vector< unsigned int > > m_outputMeasToStripKey
virtual StatusCode execute(const EventContext &ctx) const override
Function executing the algorithm.
std::atomic< unsigned long > m_nPixel
The object counters for debug prints in finalize method {.
const ServiceHandle< StoreGateSvc > & detStore() const
This is a "hash" representation of an Identifier.
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
StripCluster_v1 StripCluster
Define the version of the strip cluster class.
PixelCluster_v1 PixelCluster
Define the version of the pixel cluster class.
Host side description of a measurement before it is written to the traccc collection.