ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MultiTrajectory.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MultiTrajectory.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 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 
11 #include <bitset>
12 #include <cstdint>
13 #include <type_traits>
14 #include <vector>
15 
16 #include <Eigen/Core>
17 
22 
23 namespace Acts {
24 
25 // forward declarations
26 template <typename source_link_t>
28 class Surface;
29 
30 namespace detail_lt {
32 template <typename T, bool select>
33 using ConstIf = std::conditional_t<select, const T, T>;
37 template <typename Storage, size_t kSizeIncrement>
44  auto addCol(size_t n = 1) {
45  size_t index = m_size + (n - 1);
46  while (capacity() <= index) {
47  data.conservativeResize(Eigen::NoChange, data.cols() + kSizeIncrement);
48  }
49  m_size = index + 1;
50 
51  // @TODO: do this or not? If we assume this happens only when something is
52  // written, the expectation is that everything is zero
53  data.col(index).setZero();
54 
55  return data.col(index);
56  }
57 
59  auto col(size_t index) { return data.col(index); }
60 
62  auto col(size_t index) const { return data.col(index); }
63 
65  size_t capacity() const { return static_cast<size_t>(data.cols()); }
66 
67  size_t size() const { return m_size; }
68 
69  private:
70  Storage data;
71  size_t m_size{0};
72 };
73 
75 template <size_t Size, bool ReadOnlyMaps = true>
76 struct Types {
77  enum {
78  Flags = Eigen::ColMajor | Eigen::AutoAlign,
80  };
81  using Scalar = double;
82  // single items
83  using Coefficients = Eigen::Matrix<Scalar, Size, 1, Flags>;
84  using Covariance = Eigen::Matrix<Scalar, Size, Size, Flags>;
85  using CoefficientsMap = Eigen::Map<ConstIf<Coefficients, ReadOnlyMaps>>;
86  using CovarianceMap = Eigen::Map<ConstIf<Covariance, ReadOnlyMaps>>;
87  // storage of multiple items in flat arrays
88  using StorageCoefficients =
91  using StorageCovariance =
94 };
95 
96 struct IndexData {
97  using IndexType = uint16_t;
98 
99  static constexpr IndexType kInvalid = UINT16_MAX;
100 
108 
109  double chi2;
110  double pathLength;
112 
117 };
118 
125 template <typename source_link_t, size_t N, size_t M, bool ReadOnly = true>
127  public:
128  using SourceLink = source_link_t;
133 
134  // as opposed to the types above, this is an actual Matrix (rather than a
135  // map)
136  // @TODO: Does not copy flags, because this fails: can't have col major row
137  // vector, but that's required for 1xN projection matrices below.
138  constexpr static auto ProjectorFlags = Eigen::RowMajor | Eigen::AutoAlign;
139  using Projector =
140  Eigen::Matrix<typename Covariance::Scalar, M, N, ProjectorFlags>;
141  using EffectiveProjector =
142  Eigen::Matrix<typename Projector::Scalar, Eigen::Dynamic, Eigen::Dynamic,
144 
147  size_t index() const { return m_istate; }
148 
151  size_t previous() const { return data().iprevious; }
152 
156  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
158  return m_traj->m_index[m_istate];
159  }
160 
163  const IndexData& data() const { return m_traj->m_index[m_istate]; }
164 
167  const Surface& referenceSurface() const {
168  assert(data().irefsurface != IndexData::kInvalid);
169  return *m_traj->m_referenceSurfaces[data().irefsurface];
170  }
171 
175  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
176  void setReferenceSurface(std::shared_ptr<const Surface> srf) {
177  m_traj->m_referenceSurfaces[data().irefsurface] = std::move(srf);
178  }
179 
184  Parameters parameters() const;
185 
191  Covariance covariance() const;
192 
195  Parameters predicted() const;
196 
200 
204 
207  bool hasPredicted() const { return data().ipredicted != IndexData::kInvalid; }
208 
211  Parameters filtered() const;
212 
216 
220 
223  bool hasFiltered() const { return data().ifiltered != IndexData::kInvalid; }
224 
227  Parameters smoothed() const;
228 
232 
236 
239  bool hasSmoothed() const { return data().ismoothed != IndexData::kInvalid; }
240 
243  Covariance jacobian() const;
244 
247  bool hasJacobian() const { return data().ijacobian != IndexData::kInvalid; }
248 
256  Projector projector() const;
257 
260  bool hasProjector() const { return data().iprojector != IndexData::kInvalid; }
261 
269  return projector().topLeftCorner(data().measdim, M);
270  }
271 
277  template <typename Derived, bool RO = ReadOnly,
278  typename = std::enable_if_t<!RO>>
279  void setProjector(const Eigen::MatrixBase<Derived>& projector) {
280  constexpr int rows = Eigen::MatrixBase<Derived>::RowsAtCompileTime;
281  constexpr int cols = Eigen::MatrixBase<Derived>::ColsAtCompileTime;
282 
283  static_assert(rows != -1 && cols != -1,
284  "Assignment of dynamic matrices is currently not supported.");
285 
286  IndexData& dataref = data();
287  assert(dataref.iprojector != IndexData::kInvalid);
288 
289  constexpr int max_measdim = MultiTrajectory<SourceLink>::MeasurementSizeMax;
290 
291  static_assert(rows <= max_measdim, "Given projector has too many rows");
292  static_assert(cols <= max_measdim, "Given projector has too many columns");
293 
294  // set up full size projector with only zeros
295  typename TrackStateProxy::Projector fullProjector =
296  decltype(fullProjector)::Zero();
297 
298  // assign (potentially) smaller actual projector to matrix, preserving
299  // zeroes outside of smaller matrix block.
300  fullProjector.template topLeftCorner<rows, max_measdim>() = projector;
301 
302  // convert to bitset before storing
303  m_traj->m_projectors[dataref.iprojector] = matrixToBitset(fullProjector);
304  }
305 
308  bool hasUncalibrated() const {
310  }
311 
314  const SourceLink& uncalibrated() const;
315 
319  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
321  assert(data().iuncalibrated != IndexData::kInvalid);
322  return m_traj->m_sourceLinks[data().iuncalibrated];
323  }
324 
327  bool hasCalibrated() const {
329  }
330 
334  const SourceLink& calibratedSourceLink() const;
335 
340  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
342  assert(data().icalibratedsourcelink != IndexData::kInvalid);
343  return m_traj->m_sourceLinks[data().icalibratedsourcelink];
344  }
345 
349  Measurement calibrated() const;
350 
355 
358  auto effectiveCalibrated() const { return calibrated().head(data().measdim); }
359 
363  return calibratedCovariance().topLeftCorner(data().measdim, data().measdim);
364  }
365 
370  size_t calibratedSize() const { return data().measdim; }
371 
379  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>,
380  ParID_t... params>
382  IndexData& dataref = data();
383  constexpr size_t measdim = Acts::Measurement<SourceLink, params...>::size();
384 
385  dataref.measdim = measdim;
386 
387  assert(hasCalibrated());
388  calibrated().setZero();
389  calibrated().template head<measdim>() = meas.parameters();
390 
391  calibratedCovariance().setZero();
392  calibratedCovariance().template topLeftCorner<measdim, measdim>() =
393  meas.covariance();
394 
395  setProjector(meas.projector());
396 
397  // this shouldn't change
398  assert(data().irefsurface != IndexData::kInvalid);
399  std::shared_ptr<const Surface>& refSrf =
400  m_traj->m_referenceSurfaces[dataref.irefsurface];
401  // either unset, or the same, otherwise this is inconsistent assignment
402  assert(!refSrf || refSrf.get() == &meas.referenceSurface());
403  if (!refSrf) {
404  // ref surface is not set, set it now
405  refSrf = meas.referenceSurface().getSharedPtr();
406  }
407 
408  assert(dataref.icalibratedsourcelink != IndexData::kInvalid);
409  calibratedSourceLink() = meas.sourceLink();
410  }
411 
418  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>,
419  ParID_t... params>
421  IndexData& dataref = data();
422  auto& traj = *m_traj;
423  // force reallocate, whether currently invalid or shared index
424  traj.m_meas.addCol();
425  traj.m_measCov.addCol();
426  // shared index between meas par
427  // and cov
428  dataref.icalibrated = traj.m_meas.size() - 1;
429 
430  traj.m_sourceLinks.emplace_back();
431  dataref.icalibratedsourcelink = traj.m_sourceLinks.size() - 1;
432 
433  traj.m_projectors.emplace_back();
434  dataref.iprojector = traj.m_projectors.size() - 1;
435 
436  // now actually assign to the allocated entries
437  setCalibrated(meas);
438  }
439 
445  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
446  double& chi2() {
447  return data().chi2;
448  }
449 
454  double chi2() const { return data().chi2; }
455 
460  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
461  double& pathLength() {
462  return data().pathLength;
463  }
464 
467  double pathLength() const { return data().pathLength; }
468 
473  template <bool RO = ReadOnly, typename = std::enable_if_t<!RO>>
475  return data().typeFlags;
476  }
477 
480  TrackStateType typeFlags() const { return data().typeFlags; }
481 
482  private:
483  // Private since it can only be created by the trajectory.
484  TrackStateProxy(ConstIf<MultiTrajectory<SourceLink>, ReadOnly>& trajectory,
485  size_t istate);
486 
488  size_t m_istate;
489 
491 };
492 
493 // implement track state visitor concept
494 template <typename T, typename TS>
495 using call_operator_t = decltype(std::declval<T>()(std::declval<TS>()));
496 
497 template <typename T, typename TS>
499  concept ::either<concept ::identical_to<bool, call_operator_t, T, TS>,
500  concept ::identical_to<void, call_operator_t, T, TS>>>;
501 
502 } // namespace detail_lt
503 
510 namespace TrackStatePropMask {
512 using Type = std::bitset<8>;
513 
514 constexpr Type Predicted{1 << 0};
515 constexpr Type Filtered{1 << 1};
516 constexpr Type Smoothed{1 << 2};
517 constexpr Type Jacobian{1 << 3};
518 
519 constexpr Type Uncalibrated{1 << 4};
520 constexpr Type Calibrated{1 << 5};
521 
522 // Initialize to all 1s. This only works as long as number of bits <= 64
523 constexpr Type All{static_cast<unsigned long long>(-1)};
524 constexpr Type None{0};
525 } // namespace TrackStatePropMask
526 
536 template <typename source_link_t>
538  public:
539  enum {
540  ParametersSize = eBoundParametersSize,
541  MeasurementSizeMax = eBoundParametersSize,
542  };
543  using SourceLink = source_link_t;
544  using ConstTrackStateProxy =
545  detail_lt::TrackStateProxy<SourceLink, ParametersSize, MeasurementSizeMax,
546  true>;
547  using TrackStateProxy = detail_lt::TrackStateProxy<SourceLink, ParametersSize,
548  MeasurementSizeMax, false>;
549 
550  using ProjectorBitset = std::bitset<ParametersSize * MeasurementSizeMax>;
551 
553  MultiTrajectory() = default;
554 
563  template <typename parameters_t>
564  size_t addTrackState(const TrackState<SourceLink, parameters_t>& ts,
565  size_t iprevious = SIZE_MAX);
566 
573  size_t addTrackState(
575  size_t iprevious = SIZE_MAX);
576 
580  ConstTrackStateProxy getTrackState(size_t istate) const {
581  return {*this, istate};
582  }
583 
587  TrackStateProxy getTrackState(size_t istate) { return {*this, istate}; }
588 
593  template <typename F>
594  void visitBackwards(size_t iendpoint, F&& callable) const;
595 
603  template <typename F>
604  void applyBackwards(size_t iendpoint, F&& callable);
605 
606  private:
608  std::vector<detail_lt::IndexData> m_index;
614  std::vector<SourceLink> m_sourceLinks;
615  std::vector<ProjectorBitset> m_projectors;
616 
617  // owning vector of shared pointers to surfaces
618  // @TODO: This might be problematic when appending a large number of surfaces
619  // trackstates, because vector has to reallocated and thus copy. This might
620  // be handled in a smart way by moving but not sure.
621  std::vector<std::shared_ptr<const Surface>> m_referenceSurfaces;
622 
623  friend class detail_lt::TrackStateProxy<SourceLink, ParametersSize,
624  MeasurementSizeMax, true>;
625  friend class detail_lt::TrackStateProxy<SourceLink, ParametersSize,
626  MeasurementSizeMax, false>;
627 };
628 
629 } // namespace Acts
630