ATLAS Offline Software
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 
14 
15 #include "Identifier/Identifier.h"
16 #include "StoreGate/ReadHandle.h"
17 #include "StoreGate/WriteHandle.h"
19 
21  ATH_MSG_INFO("Initialising xAODSpacePointMaker tool");
22 
25 
26  ATH_CHECK(m_pixelSpacePointsKey.initialize());
27  ATH_CHECK(m_stripSpacePointsKey.initialize());
28 
29  return StatusCode::SUCCESS;
30 }
31 
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  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 
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  SG::Decorator<ElementLink<xAOD::StripClusterContainer>> dec1("fpgaStripClusterLink1");
317  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 }
xAODSpacePointMaker::m_pixelSpacePointsKey
SG::WriteHandleKey< xAOD::SpacePointContainer > m_pixelSpacePointsKey
Key for the pixel space points container to be created.
Definition: xAODSpacePointMaker.h:78
EFTrackingTransient::SpacePointAuxInput::bottomHalfStripLength
std::vector< float > bottomHalfStripLength
Definition: EFTrackingTransient.h:261
xAODSpacePointMaker::m_pixelClusterKey
SG::ReadHandleKey< xAOD::PixelClusterContainer > m_pixelClusterKey
Key for the pixel cluster container to read from.
Definition: xAODSpacePointMaker.h:68
EFTrackingTransient::SpacePointAuxInput::topStripDirection
std::vector< float > topStripDirection
Definition: EFTrackingTransient.h:262
xAODSpacePointMaker::m_stripSpacePointsKey
SG::WriteHandleKey< xAOD::SpacePointContainer > m_stripSpacePointsKey
Key for the strip space points container to be created.
Definition: xAODSpacePointMaker.h:83
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
EFTrackingTransient::SpacePointAuxInput
The SpacePointAuxInput struct is used to simplify the creaction of the xAOD::SpacePointContainer.
Definition: EFTrackingTransient.h:254
xAODSpacePointMaker.h
EFTrackingTransient::SpacePointAuxInput::bottomStripDirection
std::vector< float > bottomStripDirection
Definition: EFTrackingTransient.h:263
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
EFTrackingTransient::Metadata
The structure of the Metadata containing data after clusterization.
Definition: EFTrackingTransient.h:124
EFTrackingTransient::SpacePointAuxInput::stripCenterDistance
std::vector< float > stripCenterDistance
Definition: EFTrackingTransient.h:264
xAODSpacePointMaker::m_stripClusterKey
SG::ReadHandleKey< xAOD::StripClusterContainer > m_stripClusterKey
Key for the strip cluster container to read from.
Definition: xAODSpacePointMaker.h:73
xAODSpacePointMaker::initialize
StatusCode initialize() override
Initialise the space point maker tool.
Definition: xAODSpacePointMaker.cxx:20
python.checkMetadata.metadata
metadata
Definition: checkMetadata.py:175
WriteHandle.h
Handle class for recording to StoreGate.
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
EFTrackingTransient::SpacePointAuxInput::topHalfStripLength
std::vector< float > topHalfStripLength
Definition: EFTrackingTransient.h:260
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:59
lumiFormat.i
int i
Definition: lumiFormat.py:85
EFTrackingTransient::SpacePointAuxInput::varianceR
std::vector< float > varianceR
Definition: EFTrackingTransient.h:258
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
EFTrackingTransient::SpacePointAuxInput::globalPosition
std::vector< float > globalPosition
Definition: EFTrackingTransient.h:256
EFTrackingTransient::SpacePointAuxInput::varianceZ
std::vector< float > varianceZ
Definition: EFTrackingTransient.h:259
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
EFTrackingTransient::SpacePointAuxInput::measurementIndexes
std::vector< int > measurementIndexes
Definition: EFTrackingTransient.h:266
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
SpacePointAuxContainer.h
EFTrackingTransient::SpacePointAuxInput::elementIdList
std::vector< unsigned int > elementIdList
Definition: EFTrackingTransient.h:255
SG::WriteHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
xAODSpacePointMaker::makeStripSpacePointContainer
StatusCode makeStripSpacePointContainer(const EFTrackingTransient::SpacePointAuxInput &sspAux, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
Make the strip space point container.
Definition: xAODSpacePointMaker.cxx:149
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
SG::WriteHandle::record
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
DEBUG
#define DEBUG
Definition: page_access.h:11
EFTrackingTransient::SpacePointAuxInput::topStripCenter
std::vector< float > topStripCenter
Definition: EFTrackingTransient.h:265
xAODSpacePointMaker::makePixelSpacePointContainer
StatusCode makePixelSpacePointContainer(const EFTrackingTransient::SpacePointAuxInput &spAux, const EFTrackingTransient::Metadata *metadata, const EventContext &ctx) const
Make the pixel space point container.
Definition: xAODSpacePointMaker.cxx:32
ReadHandle.h
Handle class for reading from StoreGate.
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32