Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
// STL
#include <cmath>
#include <vector>
#include <cstdint>
// boost
#include <boost/container/static_vector.hpp>
// acts tools
#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Definitions/Common.hpp"
#include "Acts/EventData/SourceLink.hpp"
#include "Acts/Seeding/Seed.hpp"
#include "Acts/Geometry/GeometryIdentifier.hpp"
#include "Acts/Geometry/TrackingGeometry.hpp"
// edm4hep
#include "edm4hep/TrackerHit.h"
#include "edm4hep/SimTrackerHit.h"
// local
#include "GeometryContainers.hpp"
using Index = std::uint32_t;
template <typename value_t>
using IndexMultimap = boost::container::flat_multimap<Index, value_t>;
template <typename value_t>
inline boost::container::flat_multimap<value_t, Index> invertIndexMultimap(
const IndexMultimap<value_t>& multimap) {
using InverseMultimap = boost::container::flat_multimap<value_t, Index>;
// switch key-value without enforcing the new ordering (linear copy)
typename InverseMultimap::sequence_type unordered;
unordered.reserve(multimap.size());
for (auto&& [index, value] : multimap) {
// value is now the key and the index is now the value
unordered.emplace_back(value, index);
}
// adopting the unordered sequence will reestablish the correct order
InverseMultimap inverse;
#if BOOST_VERSION < 107800
for (const auto& i : unordered) {
inverse.insert(i);
}
#else
inverse.insert(unordered.begin(), unordered.end());
#endif
return inverse;
}
/// Space point representation of a measurement suitable for track seeding.
class SimSpacePoint {
using Scalar = Acts::ActsScalar;
public:
/// Construct the space point from edm4hep::TrackerHit
///
/// @param trackerhit tracker hit to construct the space point from
SimSpacePoint(const edm4hep::TrackerHit trackerhit,
float x, float y, float z, float t,
// const edm4hep::SimTrackerHit simtrackerhit,
// Acts::GeometryIdentifier geometryId,
boost::container::static_vector<Acts::SourceLink, 2> sourceLinks)
: m_x(x), m_y(y), m_z(z), m_t(t),
m_sourceLinks(std::move(sourceLinks))
// , m_geometryId(geometryId)
{
// m_trackerHit = trackerhit;
// m_simtrackerHit = simtrackerhit;
// m_x = simtrackerhit.getPosition()[0];
// m_y = simtrackerhit.getPosition()[1];
// m_z = simtrackerhit.getPosition()[2];
// m_t = simtrackerhit.getTime();
// m_cellid = simtrackerhit.getCellID();
m_rho = std::sqrt(m_x * m_x + m_y * m_y + m_z * m_z);
m_varianceRho = trackerhit.getCovMatrix()[0];
m_varianceZ = trackerhit.getCovMatrix()[5];
}
// edm4hep::TrackerHit getTrackerHit() { return m_trackerHit; }
// edm4hep::SimTrackerHit getSimTrackerHit() { return m_simtrackerHit; }
constexpr Scalar x() const { return m_x; }
constexpr Scalar y() const { return m_y; }
constexpr Scalar z() const { return m_z; }
constexpr std::optional<Scalar> t() const { return m_t; }
constexpr Scalar r() const { return m_rho; }
constexpr Scalar varianceR() const { return m_varianceRho; }
constexpr Scalar varianceZ() const { return m_varianceZ; }
constexpr std::optional<Scalar> varianceT() const { return m_varianceT; }
// constexpr std::uint64_t cellid() const { return m_cellid; }
// constexpr Acts::GeometryIdentifier geometryId() const { return m_geometryId; }
const boost::container::static_vector<Acts::SourceLink, 2>&
sourceLinks() const { return m_sourceLinks; }
constexpr float topHalfStripLength() const { return m_topHalfStripLength; }
constexpr float bottomHalfStripLength() const { return m_bottomHalfStripLength; }
Acts::Vector3 topStripDirection() const { return m_topStripDirection; }
Acts::Vector3 bottomStripDirection() const { return m_bottomStripDirection; }
Acts::Vector3 stripCenterDistance() const { return m_stripCenterDistance; }
Acts::Vector3 topStripCenterPosition() const { return m_topStripCenterPosition; }
constexpr bool validDoubleMeasurementDetails() const {
return m_validDoubleMeasurementDetails;
}
private:
// edm4hep::TrackerHit m_trackerHit;
// edm4hep::SimTrackerHit m_simtrackerHit;
// std::uint64_t m_cellid;
// Acts::GeometryIdentifier m_geometryId;
// Global position
Scalar m_x;
Scalar m_y;
Scalar m_z;
std::optional<Scalar> m_t;
Scalar m_rho;
// Variance in rho/z of the global coordinates
Scalar m_varianceRho;
Scalar m_varianceZ;
std::optional<Scalar> m_varianceT;
// SourceLinks of the corresponding measurements. A Pixel (strip) SP has one
// (two) sourceLink(s).
boost::container::static_vector<Acts::SourceLink, 2> m_sourceLinks;
// half of the length of the top strip
float m_topHalfStripLength = 0;
// half of the length of the bottom strip
float m_bottomHalfStripLength = 0;
// direction of the top strip
Acts::Vector3 m_topStripDirection = {0, 0, 0};
// direction of the bottom strip
Acts::Vector3 m_bottomStripDirection = {0, 0, 0};
// distance between the center of the two strips
Acts::Vector3 m_stripCenterDistance = {0, 0, 0};
// position of the center of the bottom strip
Acts::Vector3 m_topStripCenterPosition = {0, 0, 0};
bool m_validDoubleMeasurementDetails = false;
}; // SimSpacePoint
inline bool operator==(const SimSpacePoint& lhs, const SimSpacePoint& rhs) {
// (TODO) use sourceLinks for comparison
return ((lhs.x() == rhs.x()) && (lhs.y() == rhs.y()) &&
(lhs.z() == rhs.z()) && (lhs.t() == rhs.t()));
}
/// Container of space points.
using SimSpacePointContainer = std::vector<SimSpacePoint>;
using SimSeed = Acts::Seed<SimSpacePoint>;
using SimSeedContainer = std::vector<Acts::Seed<SimSpacePoint>>;
// --------------------------
// IndexSourceLink
// --------------------------
/// A source link that stores just an index.
///
/// This is intentionally kept as barebones as possible. The source link
/// is just a reference and will be copied, moved around, etc. often.
/// Keeping it small and separate from the actual, potentially large,
/// measurement data should result in better overall performance.
/// Using an index instead of e.g. a pointer, means source link and
/// measurement are decoupled and the measurement representation can be
/// easily changed without having to also change the source link.
class IndexSourceLink final
{
public:
/// Construct from geometry identifier and index.
IndexSourceLink(Acts::GeometryIdentifier gid, Index idx, edm4hep::TrackerHit trackhit)
: m_geometryId(gid), m_index(idx), m_trackhit(trackhit) {}
// Construct an invalid source link.
// Must be default constructible to satisfy SourceLinkConcept.
IndexSourceLink() = default;
IndexSourceLink(const IndexSourceLink&) = default;
IndexSourceLink(IndexSourceLink&&) = default;
IndexSourceLink& operator=(const IndexSourceLink&) = default;
IndexSourceLink& operator=(IndexSourceLink&&) = default;
/// Access the index.
Index index() const { return m_index; }
Acts::GeometryIdentifier geometryId() const { return m_geometryId; }
edm4hep::TrackerHit getTrackerHit() const { return m_trackhit; }
struct SurfaceAccessor
{
const Acts::TrackingGeometry& trackingGeometry;
const Acts::Surface* operator()(const Acts::SourceLink& sourceLink) const
{
const auto& indexSourceLink = sourceLink.get<IndexSourceLink>();
return trackingGeometry.findSurface(indexSourceLink.geometryId());
}
};
private:
Acts::GeometryIdentifier m_geometryId;
Index m_index = 0;
edm4hep::TrackerHit m_trackhit;
friend bool operator==(const IndexSourceLink& lhs, const IndexSourceLink& rhs)
{
return (lhs.geometryId() == rhs.geometryId()) && (lhs.m_index == rhs.m_index);
}
friend bool operator!=(const IndexSourceLink& lhs, const IndexSourceLink& rhs)
{
return !(lhs == rhs);
}
}; // IndexSourceLink
/// Container of index source links.
///
/// Since the source links provide a `.geometryId()` accessor,
/// they can be stored in an ordered geometry container.
using IndexSourceLinkContainer = GeometryIdMultiset<IndexSourceLink>;
/// Accessor for the above source link container
///
/// It wraps up a few lookup methods to be used in the Combinatorial Kalman
/// Filter
struct IndexSourceLinkAccessor : GeometryIdMultisetAccessor<IndexSourceLink>
{
using BaseIterator = GeometryIdMultisetAccessor<IndexSourceLink>::Iterator;
using Iterator = Acts::SourceLinkAdapterIterator<BaseIterator>;
// get the range of elements with requested geoId
std::pair<Iterator, Iterator> range(const Acts::Surface& surface) const
{
assert(container != nullptr);
auto [begin, end] = container->equal_range(surface.geometryId());
return {Iterator{begin}, Iterator{end}};
}
};