ATLAS Offline Software
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 
16 #include "StoreGate/WriteHandle.h"
17 
18 namespace ActsTrk {
19 
20 std::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 
76 std::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 =
84  ActsTrk::makeInterfaceContainer<xAOD::TrackStateContainer>(
85  mmtj.trackStatesAux());
86  RECORD_xAOD(m_statesKey, statesInterface, mmtj.m_trackStatesAux, evtContext);
87 
88  auto parametersInterface =
89  ActsTrk::makeInterfaceContainer<xAOD::TrackParametersContainer>(
90  mmtj.trackParametersAux());
91  RECORD_xAOD(m_parametersKey, parametersInterface, mmtj.m_trackParametersAux, evtContext);
92 
93  auto jacobiansInterface =
94  ActsTrk::makeInterfaceContainer<xAOD::TrackJacobianContainer>(
95  mmtj.trackJacobiansAux());
96  RECORD_xAOD(m_jacobiansKey, jacobiansInterface, mmtj.m_trackJacobiansAux, evtContext);
97 
98  auto measurementsInterface =
99  ActsTrk::makeInterfaceContainer<xAOD::TrackMeasurementContainer>(
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 
125 std::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 =
144  ActsTrk::makeInterfaceContainer<xAOD::TrackSummaryContainer>(
145  tc.container().m_mutableTrackBackendAux.get());
146  RECORD_xAOD(m_xAODTrackSummaryKey, interfaceTrackSummaryContainer, tc.container().m_mutableTrackBackendAux, evtContext);
147 
148  auto trackSurfaces = ActsTrk::makeInterfaceContainer<xAOD::TrackSurfaceContainer>(
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 
200 std::unique_ptr<ActsTrk::MultiTrajectory>
201 ConstTrackContainerHandlesHelper::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 
251 std::unique_ptr<ActsTrk::PersistentTrackContainer>
252 ConstTrackContainerHandlesHelper::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 
294 namespace {
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
ActsTrk::ConstTrackContainerHandlesHelper::m_jacobiansKey
SG::ReadHandleKey< xAOD::TrackJacobianContainer > m_jacobiansKey
Definition: TrackContainerHandlesHelper.h:113
ActsTrk::MutablePersistentTrackContainer
Definition: PersistentTrackContainer.h:49
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
ActsTrk::MutableTrackContainerHandlesHelper::m_trackSummaryKey
SG::WriteHandleKey< ActsTrk::TrackSummaryContainer > m_trackSummaryKey
Definition: TrackContainerHandlesHelper.h:82
fitman.sz
sz
Definition: fitman.py:527
ActsTrk::ConstTrackContainerHandlesHelper::m_trackSummaryKey
SG::WriteHandleKey< ActsTrk::TrackSummaryContainer > m_trackSummaryKey
Definition: TrackContainerHandlesHelper.h:127
ActsTrk::MutableTrackContainerHandlesHelper::m_mtjKey
SG::WriteHandleKey< ActsTrk::MultiTrajectory > m_mtjKey
Definition: TrackContainerHandlesHelper.h:70
index
Definition: index.py:1
SG::ConstAccessor::auxid
SG::auxid_t auxid() const
Return the aux id for this variable.
xAOD::AuxContainerBase::getAuxIDs
virtual const auxid_set_t & getAuxIDs() const override
Get the types(names) of variables handled by this container.
Definition: AuxContainerBase.cxx:277
TrackState.h
ActsTrk::ConstTrackContainerHandlesHelper::restoreUncalibMeasurementPtr
void restoreUncalibMeasurementPtr(xAOD::TrackStateAuxContainer &statesLink) const
Definition: TrackContainerHandlesHelper.cxx:323
xAOD::AuxContainerBase
Common base class for the auxiliary containers.
Definition: AuxContainerBase.h:59
ActsTrk::prefixFromTrackContainerName
std::string prefixFromTrackContainerName(const std::string &tracks)
Parse TrackContainer name to get the prefix for backends The name has to contain XYZTracks,...
Definition: TrackContainerHandlesHelper.cxx:20
SG::ConstAccessor< T >
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
SG::Decorator::auxid
SG::auxid_t auxid() const
Return the aux id for this variable.
ActsTrk::ConstTrackContainerHandlesHelper::m_trackSurfacesKey
SG::ReadHandleKey< xAOD::TrackSurfaceContainer > m_trackSurfacesKey
Definition: TrackContainerHandlesHelper.h:126
ActsTrk::ConstTrackContainerHandlesHelper::initialize
StatusCode initialize(const std::string &prefix)
Sets up the handles.
Definition: TrackContainerHandlesHelper.cxx:173
ActsTrk::MutableTrackContainerHandlesHelper::m_trackSurfacesKey
SG::WriteHandleKey< xAOD::TrackSurfaceContainer > m_trackSurfacesKey
Definition: TrackContainerHandlesHelper.h:81
ActsTrk::MutableTrackContainerHandlesHelper::initialize
StatusCode initialize(const std::string &prefix)
Sets up the handles.
Definition: TrackContainerHandlesHelper.cxx:47
PrepareReferenceFile.regex
regex
Definition: PrepareReferenceFile.py:43
SG::makeHandle
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
Definition: ReadCondHandle.h:274
ActsTrk::MutableMultiTrajectory
Athena implementation of ACTS::MultiTrajectory (ReadWrite version) The data is stored in 4 external b...
Definition: MultiTrajectory.h:78
xAOD::AuxContainerBase::size
virtual size_t size() const override
Get the size of the container.
Definition: AuxContainerBase.cxx:432
TrackStateContainer.h
WriteHandle.h
Handle class for recording to StoreGate.
xAOD::UncalibratedMeasurement_v1
Definition: UncalibratedMeasurement_v1.h:13
SG::Decorator< T >
INIT_CHECK
#define INIT_CHECK(key)
Definition: TrackContainerHandlesHelper.cxx:42
ActsTrk::ConstTrackContainerHandlesHelper::buildMtj
std::unique_ptr< ActsTrk::MultiTrajectory > buildMtj(const Acts::TrackingGeometry *geo, const EventContext &context) const
Definition: TrackContainerHandlesHelper.cxx:201
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ActsTrk::MutableTrackContainerHandlesHelper::m_parametersKey
SG::WriteHandleKey< xAOD::TrackParametersContainer > m_parametersKey
Definition: TrackContainerHandlesHelper.h:66
UncalibratedMeasurementContainer.h
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
xAOD::AuxContainerBase::getDecoration
virtual void * getDecoration(auxid_t auxid, size_t size, size_t capacity) override
Get a pointer to a given array, as a decoration.
Definition: AuxContainerBase.cxx:302
ActsTrk::ConstTrackContainerHandlesHelper::build
std::unique_ptr< ActsTrk::PersistentTrackContainer > build(const Acts::TrackingGeometry *geo, const Acts::GeometryContext &geoContext, const EventContext &context) const
Definition: TrackContainerHandlesHelper.cxx:252
ActsTrk::ConstTrackContainerHandlesHelper::m_mtjKey
SG::WriteHandleKey< ActsTrk::MultiTrajectory > m_mtjKey
Definition: TrackContainerHandlesHelper.h:117
ActsTrk::ConstTrackContainerHandlesHelper::m_xAODTrackSummaryKey
SG::ReadHandleKey< xAOD::TrackSummaryContainer > m_xAODTrackSummaryKey
Definition: TrackContainerHandlesHelper.h:125
ActsTrk::ConstTrackContainerHandlesHelper::m_measurementsKey
SG::ReadHandleKey< xAOD::TrackMeasurementContainer > m_measurementsKey
Definition: TrackContainerHandlesHelper.h:114
ActsTrk::MutableTrackContainerHandlesHelper::m_xAODTrackSummaryKey
SG::WriteHandleKey< xAOD::TrackSummaryContainer > m_xAODTrackSummaryKey
Definition: TrackContainerHandlesHelper.h:80
xAOD::AuxContainerBase::getData
virtual const void * getData(auxid_t auxid) const override
Get a pointer to a given array.
Definition: AuxContainerBase.cxx:232
ActsTrk::MutableTrackContainerHandlesHelper::moveToConst
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
Definition: TrackContainerHandlesHelper.cxx:126
xAOD::JetAttributeAccessor::accessor
const AccessorWrapper< T > * accessor(xAOD::JetAttribute::AttributeID id)
Returns an attribute accessor corresponding to an AttributeID.
Definition: JetAccessorMap.h:26
ActsTrk::MutableTrackContainerHandlesHelper::m_surfacesKey
SG::WriteHandleKey< xAOD::TrackSurfaceContainer > m_surfacesKey
Definition: TrackContainerHandlesHelper.h:69
ActsTrk::MutableTrackContainerHandlesHelper::m_jacobiansKey
SG::WriteHandleKey< xAOD::TrackJacobianContainer > m_jacobiansKey
Definition: TrackContainerHandlesHelper.h:67
DeMoScan.index
string index
Definition: DeMoScan.py:362
LArCellConditions.geo
bool geo
Definition: LArCellConditions.py:46
RECORD_xAOD
#define RECORD_xAOD(key, container, auxContainer, ctx)
Definition: TrackContainerHandlesHelper.cxx:33
ActsTrk::MutableTrackContainerHandlesHelper::m_measurementsKey
SG::WriteHandleKey< xAOD::TrackMeasurementContainer > m_measurementsKey
Definition: TrackContainerHandlesHelper.h:68
ActsTrk::ConstTrackContainerHandlesHelper::m_statesKey
SG::ReadHandleKey< xAOD::TrackStateContainer > m_statesKey
Definition: TrackContainerHandlesHelper.h:111
xAOD::TrackStateAuxContainer_v1
Definition: TrackStateAuxContainer_v1.h:18
ActsTrk
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
Definition: MSTrackingVolumeBuilder.cxx:24
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
TrackContainerHandlesHelper.h
ActsTrk::MutableTrackContainerHandlesHelper::m_statesKey
SG::WriteHandleKey< xAOD::TrackStateContainer > m_statesKey
Definition: TrackContainerHandlesHelper.h:65
ActsTrk::ConstTrackContainerHandlesHelper::m_parametersKey
SG::ReadHandleKey< xAOD::TrackParametersContainer > m_parametersKey
Definition: TrackContainerHandlesHelper.h:112
ActsTrk::ConstTrackContainerHandlesHelper::m_surfacesKey
SG::ReadHandleKey< xAOD::TrackSurfaceContainer > m_surfacesKey
Definition: TrackContainerHandlesHelper.h:115
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
CxxUtils::ConcurrentBitset::test
bool test(bit_t bit) const
Test to see if a bit is set.