Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PodioTrackContainer.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file PodioTrackContainer.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2023 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #pragma once
10 
16 #include "ActsPodioEdm/Track.h"
17 #include "ActsPodioEdm/TrackCollection.h"
18 #include "ActsPodioEdm/TrackInfo.h"
19 
20 #include <mutex>
21 #include <stdexcept>
22 #include <type_traits>
23 
24 #include <podio/Frame.h>
25 
26 namespace Acts {
27 
28 class MutablePodioTrackContainer;
29 class ConstPodioTrackContainer;
30 
31 template <>
33 };
34 
35 template <>
37 
39  public:
41  static constexpr auto kInvalid = MultiTrajectoryTraits::kInvalid;
42  static constexpr auto MeasurementSizeMax =
44 
45  using Parameters =
47  using Covariance =
49 
50  using ConstParameters =
52  using ConstCovariance =
54 
55  protected:
57  : m_helper{helper} {}
58 
59  template <bool EnsureConst, typename T>
60  static std::any component_impl(T& instance, HashedString key,
61  IndexType itrack) {
62  using namespace Acts::HashedStringLiteral;
63  if constexpr (EnsureConst) {
64  static_assert(std::is_const_v<std::remove_reference_t<T>>,
65  "Is not const");
66  }
67 
68  using namespace Acts::HashedStringLiteral;
69  auto track = instance.m_collection->at(itrack);
70  std::conditional_t<EnsureConst, const ActsPodioEdm::TrackInfo*,
71  ActsPodioEdm::TrackInfo*>
72  dataPtr;
73  if constexpr (EnsureConst) {
74  dataPtr = &track.getData();
75  } else {
76  dataPtr = &track.data();
77  }
78  auto& data = *dataPtr;
79  switch (key) {
80  case "tipIndex"_hash:
81  return &data.tipIndex;
82  case "params"_hash:
83  return data.parameters.data();
84  case "cov"_hash:
85  return data.covariance.data();
86  case "nMeasurements"_hash:
87  return &data.nMeasurements;
88  case "nHoles"_hash:
89  return &data.nHoles;
90  case "chi2"_hash:
91  return &data.chi2;
92  case "ndf"_hash:
93  return &data.ndf;
94  case "nOutliers"_hash:
95  return &data.nOutliers;
96  case "nSharedHits"_hash:
97  return &data.nSharedHits;
98  default:
99  auto it = instance.m_dynamic.find(key);
100  if (it == instance.m_dynamic.end()) {
101  throw std::runtime_error("Unable to handle this component");
102  }
103 
104  std::conditional_t<EnsureConst,
105  const podio_detail::ConstDynamicColumnBase*,
106  podio_detail::DynamicColumnBase*>
107  col = it->second.get();
108  assert(col && "Dynamic column is null");
109  return col->get(itrack);
110  }
111  }
112 
113  static void populateSurfaceBuffer(
114  const PodioUtil::ConversionHelper& helper,
115  const ActsPodioEdm::TrackCollection& collection,
116  std::vector<std::shared_ptr<const Surface>>& surfaces) noexcept {
117  surfaces.reserve(collection.size());
118  for (ActsPodioEdm::Track track : collection) {
119  surfaces.push_back(PodioUtil::convertSurfaceFromPodio(
120  helper, track.getReferenceSurface()));
121  }
122  }
123 
124  std::reference_wrapper<const PodioUtil::ConversionHelper> m_helper;
125  std::vector<std::shared_ptr<const Surface>> m_surfaces;
126 };
127 
129  public:
131  : PodioTrackContainerBase{helper},
132  m_collection{std::make_unique<ActsPodioEdm::TrackCollection>()} {
133  populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);
134  }
135 
138 
140 
141  // BEGIN INTERFACE HELPER
142 
143  private:
144  std::shared_ptr<const Surface> getOrCreateSurface(IndexType itrack) {
145  std::shared_ptr<const Surface>& ptr = m_surfaces.at(itrack);
146  if (!ptr) {
147  ActsPodioEdm::Track track = m_collection->at(itrack);
148  ptr = PodioUtil::convertSurfaceFromPodio(m_helper,
149  track.getReferenceSurface());
150  }
151  return ptr;
152  }
153 
154  public:
155  std::any component_impl(HashedString key, IndexType itrack) {
156  return PodioTrackContainerBase::component_impl<false>(*this, key, itrack);
157  }
158 
159  std::any component_impl(HashedString key, IndexType itrack) const {
160  return PodioTrackContainerBase::component_impl<true>(*this, key, itrack);
161  }
162 
163  bool hasColumn_impl(HashedString key) const {
164  return m_dynamic.find(key) != m_dynamic.end();
165  }
166 
167  std::size_t size_impl() const { return m_collection->size(); }
168  // END INTERFACE HELPER
169 
170  const Surface* referenceSurface_impl(IndexType itrack) const {
171  return m_surfaces.at(itrack).get();
172  }
173 
174  void setReferenceSurface_impl(IndexType itrack,
175  std::shared_ptr<const Surface> surface) {
176  auto track = m_collection->at(itrack);
177  track.setReferenceSurface(
178  PodioUtil::convertSurfaceToPodio(m_helper, *surface));
179  m_surfaces.at(itrack) = std::move(surface);
180  }
181 
182  public:
183  // BEGIN INTERFACE
184 
186  auto track = m_collection->create();
187  track.referenceSurface().surfaceType = PodioUtil::kNoSurface;
188  m_surfaces.emplace_back();
189  for (const auto& [key, vec] : m_dynamic) {
190  vec->add();
191  }
192  return m_collection->size() - 1;
193  };
194 
195  void removeTrack_impl(IndexType itrack);
196 
197  template <typename T>
198  constexpr void addColumn_impl(const std::string& key) {
199  m_dynamic.insert({hashString(key),
200  std::make_unique<podio_detail::DynamicColumn<T>>(key)});
201  }
202 
204  return Parameters{m_collection->at(itrack).data().parameters.data()};
205  }
206 
208  return ConstParameters{
209  m_collection->at(itrack).getData().parameters.data()};
210  }
211 
213  return Covariance{m_collection->at(itrack).data().covariance.data()};
214  }
215 
217  return ConstCovariance{
218  m_collection->at(itrack).getData().covariance.data()};
219  }
220 
221  // @TODO What's the equivalent of this?
222  void copyDynamicFrom_impl(IndexType dstIdx,
223  const MutablePodioTrackContainer& src,
224  IndexType srcIdx);
225 
226  void ensureDynamicColumns_impl(const MutablePodioTrackContainer& other);
227 
228  void reserve(IndexType /*size*/) {}
229 
230  ActsPodioEdm::TrackCollection& trackCollection() { return *m_collection; }
231 
232  void releaseInto(podio::Frame& frame, const std::string& suffix = "") {
233  std::string s = suffix;
234  if (!s.empty()) {
235  s = "_" + s;
236  }
237  frame.put(std::move(m_collection), "tracks" + s);
238  m_surfaces.clear();
239 
240  for (const auto& [key, col] : m_dynamic) {
241  col->releaseInto(frame, "tracks" + s + "_extra__");
242  }
243  }
244 
245  // END INTERFACE
246 
247  private:
249 
250  std::unique_ptr<ActsPodioEdm::TrackCollection> m_collection;
251  std::unordered_map<HashedString,
252  std::unique_ptr<podio_detail::DynamicColumnBase>>
254 };
255 
257 
259  public:
261  const ActsPodioEdm::TrackCollection& collection)
262  : PodioTrackContainerBase{helper}, m_collection{&collection} {
263  populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);
264  }
265 
266  ConstPodioTrackContainer(const PodioUtil::ConversionHelper& helper,
267  const podio::Frame& frame,
268  const std::string& suffix = "")
269  : PodioTrackContainerBase{helper} {
270  std::string s = suffix.empty() ? suffix : "_" + suffix;
271  std::string tracksKey = "tracks" + s;
272 
273  std::vector<std::string> available = frame.getAvailableCollections();
274  if (std::find(available.begin(), available.end(), tracksKey) ==
275  available.end()) {
276  throw std::runtime_error{"Track collection '" + tracksKey +
277  "'not found in frame"};
278  }
279 
280  const auto* collection = frame.get(tracksKey);
281 
282  if (const auto* d =
283  dynamic_cast<const ActsPodioEdm::TrackCollection*>(collection);
284  d != nullptr) {
285  m_collection = d;
286  } else {
287  throw std::runtime_error{"Unable to get collection " + tracksKey};
288  }
289 
290  populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);
291 
292  // let's find dynamic columns
293  using types =
294  std::tuple<int32_t, int64_t, uint32_t, uint64_t, float, double>;
295 
296  for (const auto& col : available) {
297  std::string prefix = tracksKey + "_extra__";
298  std::size_t p = col.find(prefix);
299  if (p == std::string::npos) {
300  continue;
301  }
302  std::string dynName = col.substr(prefix.size());
303  const podio::CollectionBase* coll = frame.get(col);
304 
305  std::unique_ptr<podio_detail::ConstDynamicColumnBase> up;
306 
307  std::apply(
308  [&](auto... args) {
309  auto inner = [&](auto arg) {
310  if (up) {
311  return;
312  }
313  using T = decltype(arg);
314  const auto* dyn =
315  dynamic_cast<const podio::UserDataCollection<T>*>(coll);
316  if (dyn == nullptr) {
317  return;
318  }
319  up = std::make_unique<podio_detail::ConstDynamicColumn<T>>(
320  dynName, *dyn);
321  };
322 
323  ((inner(args)), ...);
324  },
325  types{});
326 
327  if (!up) {
328  throw std::runtime_error{"Dynamic column '" + dynName +
329  "' is not of allowed type"};
330  }
331 
332  m_dynamic.insert({hashString(dynName), std::move(up)});
333  }
334  }
335 
336  std::any component_impl(HashedString key, IndexType itrack) const {
337  return PodioTrackContainerBase::component_impl<true>(*this, key, itrack);
338  }
339 
340  bool hasColumn_impl(HashedString key) const {
341  return m_dynamic.find(key) != m_dynamic.end();
342  }
343 
344  std::size_t size_impl() const { return m_collection->size(); }
345 
346  const Surface* referenceSurface_impl(IndexType itrack) const {
347  return m_surfaces.at(itrack).get();
348  }
349 
350  ConstParameters parameters(IndexType itrack) const {
351  return ConstParameters{
352  m_collection->at(itrack).getData().parameters.data()};
353  }
354 
355  ConstCovariance covariance(IndexType itrack) const {
356  return ConstCovariance{
357  m_collection->at(itrack).getData().covariance.data()};
358  }
359 
360  const ActsPodioEdm::TrackCollection& trackCollection() {
361  return *m_collection;
362  }
363 
364  private:
366 
367  const ActsPodioEdm::TrackCollection* m_collection;
368  std::unordered_map<HashedString,
369  std::unique_ptr<podio_detail::ConstDynamicColumnBase>>
371 };
372 
373 ACTS_STATIC_CHECK_CONCEPT(ConstTrackContainerBackend, ConstPodioTrackContainer);
374 
375 } // namespace Acts