ATLAS Offline Software
Loading...
Searching...
No Matches
TrackContainerHandlesHelper.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
8
9#include "GeoModelKernel/throwExcept.h"
10
11#include <string>
12#include <sstream>
13#include <regex>
14#include <span>
15
17
18namespace ActsTrk {
19
20std::string prefixFromTrackContainerName(const std::string& tracks) {
21 std::regex word_regex("(.*)Tracks$");
22 std::smatch match_regex;
23
24 if ( not std::regex_search(tracks, match_regex, word_regex) or match_regex.size() < 2) {
25 throw std::runtime_error(
26 std::string("prefixFromTrackContainerName: key does not contain "
27 "Tracks in the name ") + tracks);
28 }
29
30 return match_regex[1].str();
31}
32
33#define RECORD_xAOD(key, container, auxContainer, ctx) \
34 { \
35 SG::WriteHandle handle{key, ctx}; \
36 if (!handle.record(std::move(container), \
37 std::move(auxContainer)).isSuccess()){ \
38 THROW_EXCEPTION("Cannot record "<<key.fullKey()<<" backend"); \
39 } \
40 }
41
42#define INIT_CHECK(key) \
43 if (!key.initialize().isSuccess()) { \
44 THROW_EXCEPTION("Failed to initialize key "<<key.fullKey()); \
45 }
46
48 const std::string& prefix) {
49 m_statesKey = prefix + "TrackStates";
50 m_parametersKey = prefix + "TrackParameters";
51 m_jacobiansKey = prefix + "TrackJacobians";
52 m_measurementsKey = prefix + "TrackMeasurements";
53 m_surfacesKey = prefix + "TrackStateSurfaces";
54 m_mtjKey =
55 prefix + "MultiTrajectory"; // identical names, underlying types are distinct
62
63 // Track Container backends
64 m_xAODTrackSummaryKey = prefix + "TrackSummary";
65 m_trackSurfacesKey = prefix + "TrackSurfaces";
67 prefix +
68 "TrackSummary"; // identical names, underlying types are distinct
69
73 return StatusCode::SUCCESS;
74}
75
76std::unique_ptr<ActsTrk::MultiTrajectory>
78 ActsTrk::MutableMultiTrajectory&& mmtj, const EventContext& evtContext) const {
79
80 mmtj.trim();
81
82 auto statesBackendHandle = SG::makeHandle(m_statesKey, evtContext);
83 auto statesInterface =
85 mmtj.trackStatesAux());
86 RECORD_xAOD(m_statesKey, statesInterface, mmtj.m_trackStatesAux, evtContext);
87
88 auto parametersInterface =
90 mmtj.trackParametersAux());
91 RECORD_xAOD(m_parametersKey, parametersInterface, mmtj.m_trackParametersAux, evtContext);
92
93 auto jacobiansInterface =
95 mmtj.trackJacobiansAux());
96 RECORD_xAOD(m_jacobiansKey, jacobiansInterface, mmtj.m_trackJacobiansAux, evtContext);
97
98 auto measurementsInterface =
100 mmtj.trackMeasurementsAux());
101 RECORD_xAOD(m_measurementsKey, measurementsInterface, mmtj.m_trackMeasurementsAux, evtContext);
102
103 auto surfacesBackendHandle = SG::makeHandle(m_surfacesKey, evtContext);
104 RECORD_xAOD(m_surfacesKey, mmtj.m_surfacesBackend, mmtj.m_surfacesBackendAux, evtContext);
105
106 // construct const MTJ version
107 auto cmtj = std::make_unique<ActsTrk::MultiTrajectory>(
109 evtContext),
111 m_parametersKey.key() + "Aux.", evtContext),
113 m_jacobiansKey.key() + "Aux.", evtContext),
115 m_measurementsKey.key() + "Aux.", evtContext),
117 m_surfacesKey.key() + "Aux.", evtContext)
118 );
119 cmtj->moveSurfaces(&mmtj);
120 cmtj->moveLinks(&mmtj);
121
122 return cmtj;
123}
124
125std::unique_ptr<ActsTrk::PersistentTrackContainer>
127 ActsTrk::MutablePersistentTrackContainer&& tc, const Acts::GeometryContext& geoContext, const EventContext& evtContext) const {
128
129
130 std::unique_ptr<ActsTrk::MultiTrajectory> constMtj =
131 moveToConst(std::move(tc.trackStateContainer()), evtContext);
132
133 auto constMtjHandle = SG::makeHandle(m_mtjKey, evtContext);
134 if (constMtjHandle.record(std::move(constMtj)).isFailure()) {
135 throw std::runtime_error(
136 "MutableTrackContainerHandlesHelper::moveToConst, can't record "
137 "ConstMultiTrajectory");
138 }
139
140 auto trackSurfacesAux = std::make_unique<xAOD::TrackSurfaceAuxContainer>();
141 tc.container().encodeSurfaces(trackSurfacesAux.get(), geoContext);
142
143 auto interfaceTrackSummaryContainer =
145 tc.container().m_mutableTrackBackendAux.get());
146 RECORD_xAOD(m_xAODTrackSummaryKey, interfaceTrackSummaryContainer, tc.container().m_mutableTrackBackendAux, evtContext);
147
149 trackSurfacesAux.get());
150 RECORD_xAOD(m_trackSurfacesKey, trackSurfaces, trackSurfacesAux, evtContext);
151
152 auto constTrackSummary = std::make_unique<ActsTrk::TrackSummaryContainer>(
154 evtContext));
155 constTrackSummary->restoreDecorations();
156 constTrackSummary->fillFrom(tc.container());
157
158 auto constTrackSummaryHandle = SG::makeHandle(m_trackSummaryKey, evtContext);
159 if (constTrackSummaryHandle.record(std::move(constTrackSummary))
160 .isFailure()) {
161 throw std::runtime_error(
162 "MutableTrackContainerHandlesHelper::moveToConst, can't record "
163 "TrackSummary");
164 }
165 auto constTrack = std::make_unique<ActsTrk::PersistentTrackContainer>(
167 evtContext),
169 return constTrack;
170}
171
172// const version
174 const std::string& prefix) {
175 m_statesKey = prefix + "TrackStates";
176 m_parametersKey = prefix + "TrackParameters";
177 m_jacobiansKey = prefix + "TrackJacobians";
178 m_measurementsKey = prefix + "TrackMeasurements";
179 m_surfacesKey = prefix + "TrackSurfaces";
180 m_mtjKey = prefix + "MultiTrajectory";
181
188
189 m_xAODTrackSummaryKey = prefix + "TrackSummary";
190 m_trackSurfacesKey = prefix + "TrackSurfaces";
191 m_trackSummaryKey = prefix + "TrackSummary";
192
196
197 return StatusCode::SUCCESS;
198}
199
200std::unique_ptr<ActsTrk::MultiTrajectory>
201ConstTrackContainerHandlesHelper::buildMtj(const Acts::TrackingGeometry* geo,
202 const EventContext& evtContext) const {
203 // we need to build it from backends
204 DataLink<xAOD::TrackStateAuxContainer> statesLink(m_statesKey.key() + "Aux.",
205 evtContext);
206 if (not statesLink.isValid()) {
207 throw std::runtime_error(
208 "ConstMultiTrajectoryHandle::build, StatesLink is invalid");
209 }
210 // The restoration of the pointers to uncalibrated measurements should only
211 // be done once, if it is done in parallel by multiple callers all callers should
212 // write exactly the same value to exactly the same memory location
213 xAOD::TrackStateAuxContainer *nonConstStatesLink ATLAS_THREAD_SAFE = const_cast<xAOD::TrackStateAuxContainer *>(statesLink.getDataPtr());
214 restoreUncalibMeasurementPtr(*nonConstStatesLink);
215
217 m_parametersKey.key() + "Aux.", evtContext);
218 if (not parametersLink.isValid()) {
219 throw std::runtime_error(
220 "ConstMultiTrajectoryHandle::build, ParametersLink is invalid");
221 }
222
224 m_jacobiansKey.key() + "Aux.", evtContext);
225 if (not jacobiansLink.isValid()) {
226 throw std::runtime_error(
227 "ConstMultiTrajectoryHandle::build, JacobiansLink is invalid");
228 }
229
231 m_measurementsKey.key() + "Aux.", evtContext);
232 if (not measurementsLink.isValid()) {
233 throw std::runtime_error(
234 "ConstMultiTrajectoryHandle::build, MeasurementsLink is invalid");
235 }
236
238 m_surfacesKey.key() + "Aux.", evtContext);
239 if (not surfacesLink.isValid()) {
240 throw std::runtime_error(
241 "ConstMultiTrajectoryHandle::build, SurfacesLink is invalid");
242 }
243
244
245 auto cmtj = std::make_unique<ActsTrk::MultiTrajectory>(
246 statesLink, parametersLink, jacobiansLink, measurementsLink, surfacesLink);
247 cmtj->fillSurfaces(geo);
248 return cmtj;
249}
250
251std::unique_ptr<ActsTrk::PersistentTrackContainer>
252ConstTrackContainerHandlesHelper::build(const Acts::TrackingGeometry* geo,
253 const Acts::GeometryContext& /*geoContext*/,
254 const EventContext& evtContext) const {
255
256 std::unique_ptr<ActsTrk::MultiTrajectory> mtj = buildMtj(geo,evtContext);
257 auto mtjHandle = SG::makeHandle(m_mtjKey, evtContext);
258 if (mtjHandle.record(std::move(mtj)).isFailure()) {
259 throw std::runtime_error(
260 "ConstTrackContainerHandle<C>::build failed recording MTJ");
261 }
263 evtContext);
264 if (not summaryLink.isValid()) {
265 throw std::runtime_error(
266 "ConstTrackContainerHandle::build, SummaryLink is invalid");
267 }
268
269 auto surfacesHandle = SG::makeHandle(m_trackSurfacesKey, evtContext);
270 if (not surfacesHandle.isValid()) {
271 throw std::runtime_error(
272 "ConstTrackContainerHandle::build, SurfaceHandle is invalid");
273 }
274
275 auto constTrackSummary = std::make_unique<ActsTrk::TrackSummaryContainer>(summaryLink);
276 constTrackSummary->decodeSurfaces( surfacesHandle.cptr());
277
278 auto summaryHandle = SG::makeHandle(m_trackSummaryKey, evtContext);
279 if (summaryHandle.record(std::move(constTrackSummary)).isFailure()) {
280 throw std::runtime_error(
281 "MutableTrackContainerHandle::build, can't record "
282 "TrackSummary");
283 }
284
285 auto constTrack = std::make_unique<ActsTrk::PersistentTrackContainer>(
287 evtContext),
289
290 return constTrack;
291
292}
293
294namespace {
295 template <typename T>
296 using const_span = std::span<T const>;
297
298 // get an aux variable for elements (read only)
299 template <typename T>
300 const_span<T> getElementVector( const xAOD::AuxContainerBase &aux_container, const SG::ConstAccessor<T> &accessor) {
301 const T *data = static_cast<const T *>(aux_container.getData (accessor.auxid()));
302 const_span<T> ret( data, aux_container.size() );
303 return ret;
304 }
305
306 // create a new decoration for all elements using the default value
307 template <typename T>
308 std::span<T> createDecoration(xAOD::AuxContainerBase &aux_container, const SG::Decorator<T> &decor) {
309 std::size_t sz=aux_container.size();
310 T *data = static_cast<T *>(aux_container.getDecoration(decor.auxid(), sz, sz));
311 return std::span<T>( data, sz );
312 }
313
314 void throwConflictingUncalibratedMeasurementPointerValue(const xAOD::UncalibratedMeasurement *is,
315 const xAOD::UncalibratedMeasurement *should) {
316 std::stringstream msg;
317 msg << "Conflicting values for TrackState.uncalibratedMeasurement. Already set " << static_cast<const void *>(is)
318 << " would set " << static_cast<const void *>(should);
319 throw std::runtime_error(msg.str());
320 }
321}
322
325 static const SG::ConstAccessor< link_t > link_accessor("uncalibratedMeasurementLink");
326
327 if (statesLink.getAuxIDs().test(link_accessor.auxid())){
328 const_span<link_t> elementLinks = getElementVector(statesLink, link_accessor);
329
331 decor("uncalibratedMeasurement");
332
333 std::span<const xAOD::UncalibratedMeasurement *> uncalibratedMeasurements
334 = createDecoration( statesLink, decor);
335
336 for (unsigned int index = 0; index < elementLinks.size(); ++index) {
337 const link_t &el = elementLinks[index];
338 const xAOD::UncalibratedMeasurement *a_measurement = (el.isValid() ? *el : nullptr);
339 // @TODO is this check necessary ?
340 if (uncalibratedMeasurements[index] != nullptr && a_measurement != uncalibratedMeasurements[index]) {
341 throwConflictingUncalibratedMeasurementPointerValue(uncalibratedMeasurements[index], a_measurement);
342 }
343 uncalibratedMeasurements[index]=a_measurement;
344 }
345 }
346 else {
347 std::cerr << "WARNING no uncalibratedMeasurementLink aux data " << std::endl;
348 }
349}
350} // namespace ActsTrk
351
352#undef INIT_CHECK
353#undef RECORD_xAOD
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sz
static Double_t tc
Handle class for recording to StoreGate.
#define INIT_CHECK(key)
#define RECORD_xAOD(key, container, auxContainer, ctx)
#define ATLAS_THREAD_SAFE
SG::ReadHandleKey< xAOD::TrackMeasurementContainer > m_measurementsKey
std::unique_ptr< ActsTrk::PersistentTrackContainer > build(const Acts::TrackingGeometry *geo, const Acts::GeometryContext &geoContext, const EventContext &context) const
SG::ReadHandleKey< xAOD::TrackSurfaceContainer > m_surfacesKey
SG::WriteHandleKey< ActsTrk::MultiTrajectory > m_mtjKey
SG::ReadHandleKey< xAOD::TrackStateContainer > m_statesKey
void restoreUncalibMeasurementPtr(xAOD::TrackStateAuxContainer &statesLink) const
SG::ReadHandleKey< xAOD::TrackJacobianContainer > m_jacobiansKey
SG::WriteHandleKey< ActsTrk::TrackSummaryContainer > m_trackSummaryKey
SG::ReadHandleKey< xAOD::TrackParametersContainer > m_parametersKey
StatusCode initialize(const std::string &prefix)
Sets up the handles.
SG::ReadHandleKey< xAOD::TrackSurfaceContainer > m_trackSurfacesKey
SG::ReadHandleKey< xAOD::TrackSummaryContainer > m_xAODTrackSummaryKey
std::unique_ptr< ActsTrk::MultiTrajectory > buildMtj(const Acts::TrackingGeometry *geo, const EventContext &context) const
Athena implementation of ACTS::MultiTrajectory (ReadWrite version) The data is stored in 4 external b...
SG::WriteHandleKey< xAOD::TrackParametersContainer > m_parametersKey
std::unique_ptr< ActsTrk::PersistentTrackContainer > moveToConst(ActsTrk::MutablePersistentTrackContainer &&tc, const Acts::GeometryContext &geoContext, const EventContext &evtContext) const
produces ActsTrk::ConstTrackContainer with all backends stored in SG
SG::WriteHandleKey< xAOD::TrackMeasurementContainer > m_measurementsKey
SG::WriteHandleKey< xAOD::TrackSurfaceContainer > m_trackSurfacesKey
SG::WriteHandleKey< xAOD::TrackJacobianContainer > m_jacobiansKey
SG::WriteHandleKey< ActsTrk::MultiTrajectory > m_mtjKey
SG::WriteHandleKey< xAOD::TrackSummaryContainer > m_xAODTrackSummaryKey
StatusCode initialize(const std::string &prefix)
Sets up the handles.
SG::WriteHandleKey< ActsTrk::TrackSummaryContainer > m_trackSummaryKey
SG::WriteHandleKey< xAOD::TrackStateContainer > m_statesKey
SG::WriteHandleKey< xAOD::TrackSurfaceContainer > m_surfacesKey
bool test(bit_t bit) const
Test to see if a bit is set.
SG::Decorator< T, ALLOC > Decorator
Definition AuxElement.h:575
Helper class to provide constant type-safe access to aux data.
SG::auxid_t auxid() const
Return the aux id for this variable.
Helper class to provide type-safe access to aux data.
Definition Decorator.h:59
SG::auxid_t auxid() const
Return the aux id for this variable.
Common base class for the auxiliary containers.
virtual const void * getData(auxid_t auxid) const override
Get a pointer to a given array.
virtual const auxid_set_t & getAuxIDs() const override
Get the types(names) of variables handled by this container.
virtual size_t size() const override
Get the size of the container.
virtual void * getDecoration(auxid_t auxid, size_t size, size_t capacity) override
Get a pointer to a given array, as a decoration.
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
std::string prefixFromTrackContainerName(const std::string &tracks)
Parse TrackContainer name to get the prefix for backends The name has to contain XYZTracks,...
std::unique_ptr< IFACE > makeInterfaceContainer(const AUX *aux)
helper to construct interface container for already filled Aux container TODO maybe should be moved t...
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition index.py:1
TrackStateAuxContainer_v1 TrackStateAuxContainer
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
MsgStream & msg
Definition testRead.cxx:32