ATLAS Offline Software
Loading...
Searching...
No Matches
xAODSpacePointMaker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
12
14
15#include "Identifier/Identifier.h"
19
21 ATH_MSG_INFO("Initialising xAODSpacePointMaker tool");
22
23 ATH_CHECK(m_pixelClusterKey.initialize());
24 ATH_CHECK(m_stripClusterKey.initialize());
25
26 ATH_CHECK(m_pixelSpacePointsKey.initialize());
27 ATH_CHECK(m_stripSpacePointsKey.initialize());
28
29 return StatusCode::SUCCESS;
30}
31
34 const EFTrackingTransient::Metadata* metadata,
35 const EventContext& ctx) const {
36
37 if (msgLvl(MSG::DEBUG)) {
38 ATH_MSG_DEBUG("Making xAOD::SpacePointContainer from SpacePointAuxInput");
39
40 // debugging information about vector sizes
41 ATH_MSG_DEBUG("Metadata numOfPixelSpacePoints: " << metadata->numOfPixelSpacePoints);
42 ATH_MSG_DEBUG("spAux.elementIdList size: " << spAux.elementIdList.size());
43 ATH_MSG_DEBUG("spAux.globalPosition size: " << spAux.globalPosition.size());
44 ATH_MSG_DEBUG("spAux.measurementIndexes size: " << spAux.measurementIndexes.size());
45 ATH_MSG_DEBUG("spAux.varianceR size: " << spAux.varianceR.size());
46 ATH_MSG_DEBUG("spAux.varianceZ size: " << spAux.varianceZ.size());
47 }
48
49 // Check for inconsistent metadata and throw an error if it is
50 if (metadata->numOfPixelSpacePoints > 0 &&
51 (spAux.elementIdList.empty() ||
52 spAux.globalPosition.empty() ||
53 spAux.measurementIndexes.empty() ||
54 spAux.varianceR.empty() ||
55 spAux.varianceZ.empty())) {
56 ATH_MSG_WARNING("Inconsistent metadata: numOfPixelSpacePoints = "
57 << metadata->numOfPixelSpacePoints
58 << " but one or more required vectors are empty");
59 return StatusCode::SUCCESS;
60 }
61
62 if (metadata->numOfPixelSpacePoints > 0 && spAux.elementIdList.empty()) {
63 ATH_MSG_WARNING("Inconsistent metadata!");
64 }
65
66 // Create the containers
68 ATH_CHECK(pixelSpacePointsHandle.record(
69 std::make_unique<xAOD::SpacePointContainer>(),
70 std::make_unique<xAOD::SpacePointAuxContainer>()));
71
72 ATH_CHECK(pixelSpacePointsHandle.isValid());
73 ATH_MSG_DEBUG("Container '" << m_pixelSpacePointsKey << "' initialised");
74
75 // Get pixel cluster container for linking
77 if (!pixelClusters.isValid()) {
78 ATH_MSG_ERROR("Could not retrieve pixel cluster container");
79 return StatusCode::FAILURE;
80 }
81
82 // Create spacepoints
83 for (unsigned int i = 0; i < metadata->numOfPixelSpacePoints; i++) {
84 // Add bounds checking for all vector accesses
85 if (i >= spAux.elementIdList.size()) {
86 ATH_MSG_ERROR("Index out of bounds: i=" << i
87 << " >= elementIdList.size()=" << spAux.elementIdList.size());
88 return StatusCode::FAILURE;
89 }
90
91 if (i >= spAux.varianceR.size()) {
92 ATH_MSG_ERROR("Index out of bounds: i=" << i
93 << " >= varianceR.size()=" << spAux.varianceR.size());
94 return StatusCode::FAILURE;
95 }
96
97 if (i >= spAux.varianceZ.size()) {
98 ATH_MSG_ERROR("Index out of bounds: i=" << i
99 << " >= varianceZ.size()=" << spAux.varianceZ.size());
100 return StatusCode::FAILURE;
101 }
102
103 if (i >= spAux.measurementIndexes.size()) {
104 ATH_MSG_ERROR("Index out of bounds: i=" << i
105 << " >= measurementIndexes.size()=" << spAux.measurementIndexes.size());
106 return StatusCode::FAILURE;
107 }
108
109 if (i*3+2 >= spAux.globalPosition.size()) {
110 ATH_MSG_ERROR("Index out of bounds: i*3+2=" << (i*3+2)
111 << " >= globalPosition.size()=" << spAux.globalPosition.size());
112 return StatusCode::FAILURE;
113 }
114
115 // use unique_ptr to avoid memory leak
116 auto sp = pixelSpacePointsHandle->push_back(std::make_unique<xAOD::SpacePoint>());
117
118 // Create position vector
119 Eigen::Matrix<float, 3, 1> globalPosition(
120 spAux.globalPosition.at(i * 3),
121 spAux.globalPosition.at(i * 3 + 1),
122 spAux.globalPosition.at(i * 3 + 2));
123
124 // Get the measurement index
125 const int measIdx = spAux.measurementIndexes.at(i);
126
127 // Create the spacepoint with empty measurements vector
128 sp->setSpacePoint(
129 spAux.elementIdList[i],
130 globalPosition,
131 spAux.varianceR[i],
132 spAux.varianceZ[i],
133 std::vector<const xAOD::UncalibratedMeasurement*>()); // Empty vector
134
135 // Create ElementLink to the pixel cluster
136 if (measIdx >= 0 && static_cast<size_t>(measIdx) < pixelClusters->size()) {
137 ElementLink<xAOD::PixelClusterContainer> link(*pixelClusters, measIdx);
138 static const SG::Decorator<ElementLink<xAOD::PixelClusterContainer>> dec("fpgaPixelClusterLink");
139 dec(*sp) = link;
140 }
141 }
142
143 // After creating all spacepoints print the number of spacepoints created in debug stream
144 ATH_MSG_DEBUG("Created " << pixelSpacePointsHandle->size() << " pixel spacepoints");
145
146 return StatusCode::SUCCESS;
147}
148
151 const EFTrackingTransient::Metadata* metadata,
152 const EventContext& ctx) const {
153 ATH_MSG_DEBUG("Making xAOD::SpacePointContainer from SpacePointAuxInput");
154
155 // debug stream for information about vector sizes
156 ATH_MSG_DEBUG("Metadata numOfStripSpacePoints: " << metadata->numOfStripSpacePoints);
157 ATH_MSG_DEBUG("sspAux.elementIdList size: " << sspAux.elementIdList.size());
158 ATH_MSG_DEBUG("sspAux.globalPosition size: " << sspAux.globalPosition.size());
159 ATH_MSG_DEBUG("sspAux.measurementIndexes size: " << sspAux.measurementIndexes.size());
160 ATH_MSG_DEBUG("sspAux.varianceR size: " << sspAux.varianceR.size());
161 ATH_MSG_DEBUG("sspAux.varianceZ size: " << sspAux.varianceZ.size());
162
163 // Check for inconsistent metadata and throw an error if it is
164 if (metadata->numOfStripSpacePoints > 0 &&
165 (sspAux.elementIdList.empty() ||
166 sspAux.globalPosition.empty() ||
167 sspAux.measurementIndexes.empty() ||
168 sspAux.varianceR.empty() ||
169 sspAux.varianceZ.empty())) {
170 ATH_MSG_ERROR("Inconsistent metadata: numOfStripSpacePoints = "
171 << metadata->numOfStripSpacePoints
172 << " but one or more required vectors are empty");
173 return StatusCode::FAILURE;
174 }
175
176 if (metadata->numOfStripSpacePoints > 0 && sspAux.elementIdList.empty()) {
177 ATH_MSG_WARNING("Inconsistent metadata!");
178 }
179
180 // create the containers
182 ATH_CHECK(stripSpacePointsHandle.record(
183 std::make_unique<xAOD::SpacePointContainer>(),
184 std::make_unique<xAOD::SpacePointAuxContainer>()));
185
186 ATH_CHECK(stripSpacePointsHandle.isValid());
187 ATH_MSG_DEBUG("Container '" << m_stripSpacePointsKey << "' initialised");
188
189 // get the strip cluster container for linking
191 if (!stripClusters.isValid()) {
192 ATH_MSG_ERROR("Could not retrieve strip cluster container");
193 return StatusCode::FAILURE;
194 }
195
196 // create the spacepoints
197 for (unsigned int i = 0; i < metadata->numOfStripSpacePoints; i++) {
198 // add bounds checking for all vector accesses
199 if (i >= sspAux.elementIdList.size()) {
200 ATH_MSG_ERROR("Index out of bounds: i=" << i
201 << " >= elementIdList.size()=" << sspAux.elementIdList.size());
202 return StatusCode::FAILURE;
203 }
204
205 if (i >= sspAux.varianceR.size()) {
206 ATH_MSG_ERROR("Index out of bounds: i=" << i
207 << " >= varianceR.size()=" << sspAux.varianceR.size());
208 return StatusCode::FAILURE;
209 }
210
211 if (i >= sspAux.varianceZ.size()) {
212 ATH_MSG_ERROR("Index out of bounds: i=" << i
213 << " >= varianceZ.size()=" << sspAux.varianceZ.size());
214 return StatusCode::FAILURE;
215 }
216
217 if (i*2+1 >= sspAux.measurementIndexes.size()) {
218 ATH_MSG_ERROR("Index out of bounds: i*2+1=" << (i*2+1)
219 << " >= measurementIndexes.size()=" << sspAux.measurementIndexes.size());
220 return StatusCode::FAILURE;
221 }
222
223 if (i*3+2 >= sspAux.globalPosition.size()) {
224 ATH_MSG_ERROR("Index out of bounds: i*3+2=" << (i*3+2)
225 << " >= globalPosition.size()=" << sspAux.globalPosition.size());
226 return StatusCode::FAILURE;
227 }
228
229 // use unique_ptr here to avoid any memory leaks
230 auto ssp = stripSpacePointsHandle->push_back(std::make_unique<xAOD::SpacePoint>());
231
232 // Create position vector
233 Eigen::Matrix<float, 3, 1> globalPosition(
234 sspAux.globalPosition.at(i * 3),
235 sspAux.globalPosition.at(i * 3 + 1),
236 sspAux.globalPosition.at(i * 3 + 2));
237
238 // Get the measurement index
239 const int meas_idx1 = sspAux.measurementIndexes.at(i * 2);
240 const int meas_idx2 = sspAux.measurementIndexes.at(i * 2 + 1);
241
242 // For strip spacepoints, we need to use the version with two element IDs!
243 std::vector<xAOD::DetectorIDHashType> elementIds;
244 elementIds.push_back(sspAux.elementIdList.at(i * 2));
245 elementIds.push_back(sspAux.elementIdList.at(i * 2 + 1));
246
247
248 // Get strip-specific properties
249 float topHalfStripLength = 0.0f;
250 float bottomHalfStripLength = 0.0f;
251
252 if (i < sspAux.topHalfStripLength.size()) {
253 topHalfStripLength = sspAux.topHalfStripLength.at(i);
254 }
255
256 if (i < sspAux.bottomHalfStripLength.size()) {
257 bottomHalfStripLength = sspAux.bottomHalfStripLength.at(i);
258 }
259
260 // Create direction vectors
261 Eigen::Matrix<float, 3, 1> topStripDirection = Eigen::Matrix<float, 3, 1>::Zero();
262 if (i * 3 + 2 < sspAux.topStripDirection.size()) {
263 topStripDirection = Eigen::Matrix<float, 3, 1>(
264 sspAux.topStripDirection.at(i * 3),
265 sspAux.topStripDirection.at(i * 3 + 1),
266 sspAux.topStripDirection.at(i * 3 + 2));
267 }
268
269 Eigen::Matrix<float, 3, 1> bottomStripDirection = Eigen::Matrix<float, 3, 1>::Zero();
270 if (i * 3 + 2 < sspAux.bottomStripDirection.size()) {
271 bottomStripDirection = Eigen::Matrix<float, 3, 1>(
272 sspAux.bottomStripDirection.at(i * 3),
273 sspAux.bottomStripDirection.at(i * 3 + 1),
274 sspAux.bottomStripDirection.at(i * 3 + 2));
275 }
276
277 Eigen::Matrix<float, 3, 1> stripCenterDistance = Eigen::Matrix<float, 3, 1>::Zero();
278 if (i * 3 + 2 < sspAux.stripCenterDistance.size()) {
279 stripCenterDistance = Eigen::Matrix<float, 3, 1>(
280 sspAux.stripCenterDistance.at(i * 3),
281 sspAux.stripCenterDistance.at(i * 3 + 1),
282 sspAux.stripCenterDistance.at(i * 3 + 2));
283 }
284
285 Eigen::Matrix<float, 3, 1> topStripCenter = Eigen::Matrix<float, 3, 1>::Zero();
286 if (i * 3 + 2 < sspAux.topStripCenter.size()) {
287 topStripCenter = Eigen::Matrix<float, 3, 1>(
288 sspAux.topStripCenter.at(i * 3),
289 sspAux.topStripCenter.at(i * 3 + 1),
290 sspAux.topStripCenter.at(i * 3 + 2));
291 }
292
293 // Create the spacepoint with all required parameters
294 ssp->setSpacePoint(
295 std::move(elementIds),
296 globalPosition,
297 sspAux.varianceR.at(i),
298 sspAux.varianceZ.at(i),
299 std::vector<const xAOD::UncalibratedMeasurement*>(), // Empty vector of strip measurements
300 topHalfStripLength,
301 bottomHalfStripLength,
302 topStripDirection,
303 bottomStripDirection,
304 stripCenterDistance,
305 topStripCenter);
306
307 // Instead of storing measurements directly, store ElementLinks
308 if (meas_idx1 >= 0 && static_cast<size_t>(meas_idx1) < stripClusters->size() &&
309 meas_idx2 >= 0 && static_cast<size_t>(meas_idx2) < stripClusters->size()) {
310
311 // Create ElementLinks to the strip clusters
312 ElementLink<xAOD::StripClusterContainer> link1(*stripClusters, meas_idx1);
313 ElementLink<xAOD::StripClusterContainer> link2(*stripClusters, meas_idx2);
314
315 // Store the links as auxiliary data
316 static const SG::Decorator<ElementLink<xAOD::StripClusterContainer>> dec1("fpgaStripClusterLink1");
317 static const SG::Decorator<ElementLink<xAOD::StripClusterContainer>> dec2("fpgaStripClusterLink2");
318 dec1(*ssp) = link1;
319 dec2(*ssp) = link2;
320 }
321
322 // set the global position of the space point
323 ssp->globalPosition() = globalPosition;
324
325 // validate the position of the space point
326 ATH_MSG_DEBUG("Strip Spacepoint " << i << " position: ("
327 << globalPosition(0) << ", "
328 << globalPosition(1) << ", "
329 << globalPosition(2) << ")");
330 }
331
332 ATH_MSG_DEBUG("Created " << stripSpacePointsHandle->size() << " strip spacepoints");
333
334 return StatusCode::SUCCESS;
335}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sp
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
Helper class to provide type-safe access to aux data.
Definition Decorator.h:59
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode makeStripSpacePointContainer(const EFTrackingTransient::SpacePointAuxInput &sspAux, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
Make the strip space point container.
SG::ReadHandleKey< xAOD::PixelClusterContainer > m_pixelClusterKey
Key for the pixel cluster container to read from.
SG::WriteHandleKey< xAOD::SpacePointContainer > m_pixelSpacePointsKey
Key for the pixel space points container to be created.
StatusCode initialize() override
Initialise the space point maker tool.
SG::WriteHandleKey< xAOD::SpacePointContainer > m_stripSpacePointsKey
Key for the strip space points container to be created.
SG::ReadHandleKey< xAOD::StripClusterContainer > m_stripClusterKey
Key for the strip cluster container to read from.
StatusCode makePixelSpacePointContainer(const EFTrackingTransient::SpacePointAuxInput &spAux, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
Make the pixel space point container.
The structure of the Metadata containing data after clusterization.
The SpacePointAuxInput struct is used to simplify the creaction of the xAOD::SpacePointContainer.