trout
Phlex-based reconstruction framework for the SHiP experiment.
Loading...
Searching...
No Matches
SpectrometerMeasurements.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 CERN for the benefit of the SHiP Collaboration
2//
3// SPDX-License-Identifier: LGPL-3.0-or-later
4
5// SpectrometerMeasurements.hpp — builds the per-surface measurement and
6// source-link containers a CombinatorialKalmanFilter needs, from a flat
7// vector of RecHit and a real Acts::TrackingGeometry (see
8// acts_geometry_provider.cpp). Unlike ToyDetector, every hit is kept — not
9// just one per station — since pattern recognition (not this class) is what
10// decides which hits belong to which candidate track.
11
12#pragma once
13
15#include "HitUncertainty.hpp"
16#include "Index.hpp"
17#include "IndexSourceLink.hpp"
18
19#include <Acts/Definitions/Algebra.hpp>
20#include <Acts/Definitions/Units.hpp>
21#include <Acts/EventData/SourceLink.hpp>
22#include <Acts/Geometry/GeometryContext.hpp>
23#include <Acts/Geometry/GeometryIdentifier.hpp>
24#include <Acts/Geometry/TrackingGeometry.hpp>
25#include <Acts/Surfaces/Surface.hpp>
26#include <Acts/Utilities/CalibrationContext.hpp>
27
28#include <SHiP/RecHit.hpp>
29#include <array>
30#include <cmath>
31#include <limits>
32#include <utility>
33#include <vector>
34
35namespace SHiP::trout {
36
38 public:
39 struct Measurement {
40 // Non-owning; points into the TrackingGeometry that SpillContext
41 // keeps alive alongside this container (see SpillContext.hpp).
42 const Acts::Surface* surface = nullptr;
43 Acts::Vector3 global; // kept alongside local for seed construction
44 Acts::Vector2 local;
45 Acts::SquareMatrix2 covariance;
46 double time; // ns, for the time-coincidence cut in seeding
47 };
48
49 // zWindowMm: a hit is assigned to the nearest station surface only if
50 // within this z distance — the same tolerance selectOneHitPerStation used,
51 // now applied per-hit instead of picking a single best hit per station.
52 // The same value is reused as the on-surface tolerance for globalToLocal,
53 // since both express "how far off the station plane a hit may sit".
54 SpectrometerMeasurements(const Acts::TrackingGeometry& geometry,
55 const Acts::GeometryContext& gctx,
56 const std::vector<SHiP::RecHit>& hits, double zWindowMm = 510.0) {
57 double const zWindow = zWindowMm * Acts::UnitConstants::mm;
58 std::vector<std::pair<const Acts::Surface*, double>> stationSurfaces;
59 geometry.visitSurfaces(
60 [&](const Acts::Surface* s) { stationSurfaces.emplace_back(s, s->center(gctx).z()); });
61
62 for (auto const& hit : hits) {
63 Acts::Vector3 const global(hit.position[0] * Acts::UnitConstants::mm,
64 hit.position[1] * Acts::UnitConstants::mm,
65 hit.position[2] * Acts::UnitConstants::mm);
66
67 const Acts::Surface* best = nullptr;
68 double bestDz = std::numeric_limits<double>::max();
69 for (auto const& [s, zSurface] : stationSurfaces) {
70 double const dz = std::abs(global.z() - zSurface);
71 if (dz < zWindow && dz < bestDz) {
72 bestDz = dz;
73 best = s;
74 }
75 }
76 if (!best)
77 continue; // no station within window — drop the hit
78 auto locRes = best->globalToLocal(gctx, global, Acts::Vector3::UnitZ(), zWindow);
79 if (!locRes.ok())
80 continue;
81 double const time = hit.time * Acts::UnitConstants::ns;
82 auto const cov = hitCovariance(HitUncertaintyContext{global, time});
83 auto const idx = static_cast<ActsExamples::Index>(m_measurements.size());
84 m_measurements.push_back(Measurement{best, global, locRes.value(), cov, time});
85 m_sourceLinks.emplace(best->geometryId(), idx);
86 }
87 }
88
89 const std::vector<Measurement>& measurements() const { return m_measurements; }
90
92 return m_sourceLinks;
93 }
94
95 // Delegate: write calibrated measurement (same shape as
96 // ToyDetector::calibrator, looked up by IndexSourceLink instead of
97 // MySourceLink).
98 template <typename trajectory_t>
99 void calibrator(const Acts::GeometryContext&, const Acts::CalibrationContext&,
100 const Acts::SourceLink& sl, typename trajectory_t::TrackStateProxy ts) const {
101 auto const& indexSourceLink = sl.get<IndexSourceLink>();
102 auto const& m = m_measurements[indexSourceLink.index()];
103 ts.allocateCalibrated(m.local, m.covariance);
104 // The projector defaults to measuring loc0 twice; without this the
105 // second coordinate is compared with loc0 and loc1 is never measured.
106 ts.setProjectorSubspaceIndices(std::array{Acts::eBoundLoc0, Acts::eBoundLoc1});
107 // Without this, states this calibrator services never carry an
108 // uncalibrated source link at all — findCandidateHits() (SpectrometerCkf.hpp)
109 // needs it to recover which measurement index a CKF-found state
110 // corresponds to.
111 ts.setUncalibratedSourceLink(Acts::SourceLink{sl});
112 }
113
114 private:
115 std::vector<Measurement> m_measurements;
117};
118
119} // namespace SHiP::trout
SpectrometerMeasurements(const Acts::TrackingGeometry &geometry, const Acts::GeometryContext &gctx, const std::vector< SHiP::RecHit > &hits, double zWindowMm=510.0)
Definition SpectrometerMeasurements.hpp:54
const ActsExamples::GeometryIdMultiset< IndexSourceLink > & sourceLinks() const
Definition SpectrometerMeasurements.hpp:91
void calibrator(const Acts::GeometryContext &, const Acts::CalibrationContext &, const Acts::SourceLink &sl, typename trajectory_t::TrackStateProxy ts) const
Definition SpectrometerMeasurements.hpp:99
const std::vector< Measurement > & measurements() const
Definition SpectrometerMeasurements.hpp:89
boost::container::flat_multiset< T, detail::CompareGeometryId > GeometryIdMultiset
Store elements that know their detector geometry id, e.g.
Definition GeometryContainers.hpp:116
std::uint32_t Index
Index type to reference elements in a container.
Definition Index.hpp:22
Definition fit_seed.cpp:16
Acts::SquareMatrix2 hitCovariance(HitUncertaintyContext const &)
Definition HitUncertainty.cpp:11
Definition HitUncertainty.hpp:24
Definition SpectrometerMeasurements.hpp:39
double time
Definition SpectrometerMeasurements.hpp:46
const Acts::Surface * surface
Definition SpectrometerMeasurements.hpp:42
Acts::Vector2 local
Definition SpectrometerMeasurements.hpp:44
Acts::SquareMatrix2 covariance
Definition SpectrometerMeasurements.hpp:45
Acts::Vector3 global
Definition SpectrometerMeasurements.hpp:43