ATLAS Offline Software
Loading...
Searching...
No Matches
AtlasMeasurementSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
6
9
10#include "Acts/Definitions/Common.hpp"
11#include "Acts/Definitions/Algebra.hpp"
12#include "Acts/Utilities/VectorHelpers.hpp"
13#include "Acts/Utilities/Delegate.hpp"
14#include "Acts/Utilities/Result.hpp"
15#include "Acts/Geometry/GeometryContext.hpp"
16#include "Acts/Utilities/CalibrationContext.hpp"
17#include "Acts/EventData/BoundTrackParameters.hpp"
18#include "Acts/Surfaces/Surface.hpp"
19#include "Acts/Utilities/Logger.hpp"
20#include "Acts/TrackFinding/CombinatorialKalmanFilter.hpp"
21#include "Acts/TrackFinding/TrackStateCreator.hpp"
22#include "Acts/Surfaces/BoundaryTolerance.hpp"
23
29
34
35#include <tuple>
36#include <type_traits>
37#include <span>
38#include <ranges>
39
41
42template <std::size_t NMeasMax, typename traj_t, typename measurement_container_variant_t>
44
45static constexpr bool s_fullPreCalibration=true;
46
47// need an "Eigen Map" which is default constructable and assignable
48// and where an assignment changes the data pointer not the contents of
49// the data it was pointing to.
50template <std::size_t DIM>
52 ConstVectorMapWithInvalidDef() : xAOD::ConstVectorMap<DIM>{nullptr} {}
54 this->m_data = a.m_data;
55 return *this;
56 }
58 this->m_data = a.m_data;
59 return *this;
60 }
62 this->m_data = a.data();
63 return *this;
64 }
65 using xAOD::ConstVectorMap<DIM>::ConstVectorMap;
66};
67
68// see above
69template <std::size_t DIM>
71 ConstMatrixMapWithInvalidDef() : xAOD::ConstMatrixMap<DIM>{nullptr} {}
73 this->m_data = a.m_data;
74 return *this;
75 }
77 this->m_data = a.m_data;
78 return *this;
79 }
81 this->m_data = a.data();
82 return *this;
83 }
84 using xAOD::ConstMatrixMap<DIM>::ConstMatrixMap;
85};
86
91template <std::size_t NMeasMax, typename traj_t, typename measurement_container_variant_t>
92struct MeasurementSelectorTraits< AtlasMeasurementSelector<NMeasMax, traj_t, measurement_container_variant_t> >
93{
94 // the measurement type after the selection e.g. a Matrix<N,1>
95 template <std::size_t N>
97
98 // the measurement covariance type after the selection e.g. a Matrix<N,N>
99 template <std::size_t N>
101
102 // the measurement type before the selection e.g. an Eigen::Map< Matrix<N,1> > if
103 // the calibration is performed after the selection
104 template <std::size_t N>
108
109 // the measurement covariance type before the selection e.g. an Eigen::Map<Matrix<N,N> > if
110 // the calibration is performed after the selection
111 template <std::size_t N>
115 // e.g. the same as CalibratedMeasurement
116 template <std::size_t N>
118
119 // e.g. the same as CalibratedMeasurementCovariance
120 template <std::size_t N>
122
123 // e.g. helper template to get the value_type from the measurement range iterator type
124 template <typename T_MeasurementRangeIterator>
126 using value_type = typename T_MeasurementRangeIterator::value_type;
127 };
128
129 using abstract_measurement_range_t = std::ranges::iota_view<unsigned int, unsigned int>;
130
131 // the trajectory type to which states for selected measurements are to be added
132 using trajectory_t = traj_t;
133 // the track state type for new track states
134 using TrackStateProxy = typename traj_t::TrackStateProxy;
135
136 // the value type usd for matrices
137 using MatrixFloatType = double;
138 using BoundTrackParameters = Acts::BoundTrackParameters;
139 using BoundMatrix = Acts::BoundMatrix;
140
141 using BoundState = std::tuple<BoundTrackParameters, BoundMatrix, double>;
142
143 // maximum dimension of measurements determined from the measurement "container" variant
145
146 // must be the same as what is used for the CKF
147 static constexpr std::size_t s_maxBranchesPerSurface = 10;
148};
149
151template <std::size_t NMeasMax, typename traj_t, typename measurement_container_variant_t>
153 : public MeasurementSelectorBaseImpl<NMeasMax,
154 AtlasMeasurementSelector<NMeasMax, traj_t, measurement_container_variant_t> ,
155 measurement_container_variant_t >
156{
157 // @TODO can these redundent definitions been avoided ?
160 measurement_container_variant_t >;
161 // BASE::trats are MeasurementSelectorTraits< ... decltype(*this) >
162 using traits = typename BASE::traits;
163
164 template <std::size_t DIM>
165 using Measurement = typename traits::template CalibratedMeasurement<DIM>;
166
168
169 // helper to determine the calibrator type from the measurement container tyoe
170 // and to define the types used for the calibrated measurement and covariance
172 // the types used for the calibrated measurement and covariance
173 template <std::size_t DIM>
174 using Measurement = typename traits::template CalibratedMeasurement<DIM>;
175 template <std::size_t DIM>
176 using MeasurementCovariance = typename traits::template CalibratedMeasurementCovariance<DIM>;
177
178 // helper to determine the measurement value type from the container type
179 template <typename T_Container>
180 using MeassurementContainerValueType = typename traits::template MeasurementContainerTraits<T_Container>::value_type;
181 };
182
183 // the delegate used for the final calibration
184 template <std::size_t DIM, typename measurement_t>
186 measurement_container_variant_t,
187 typename traits::BoundTrackParameters>::template Calibrator<DIM,measurement_t>;
188
189 template <std::size_t DIM, typename measurement_t>
191 measurement_container_variant_t,
192 typename traits::TrackStateProxy>::template Calibrator<DIM,measurement_t>;
193
194
197
199 m_measurementRangesForced = measurementRangesForced;
200 }
201
202 // Helper to provide the mapping between bound parameters and coordinates
203 // @TODO is the default projector always good enough or is there some dependency
204 // on the geoemtry ?
207 struct Empty {};
208 std::conditional<s_fullPreCalibration,
211
212
214 const ActsTrk::detail::MeasurementRangeList &measurementRanges)
215 : BASE{std::move(config)},
216 m_measurementRanges(&measurementRanges)
217 {}
218
219 // register a calibrator for the given measurement type and the measurement dimension i.e. number of coordinates
220 template <std::size_t DIM, typename T_ValueType>
223 }
224
225 template <std::size_t DIM>
226 static constexpr bool s_CanPreCalibrate = std::is_same< typename traits::template PreSelectionMeasurement<DIM>,
227 typename traits::template CalibratedMeasurement<DIM> >::value
228 && std::is_same< typename traits::template PreSelectionMeasurementCovariance<DIM>,
229 typename traits::template CalibratedMeasurementCovariance<DIM> >::value;
230
231 template < std::size_t DIM, typename T_ValueType >
232 void setPreCalibrator(typename std::enable_if<s_CanPreCalibrate<DIM>, const PreCalibrator<DIM, T_ValueType> &>::type calibrator) {
234 }
235
236
237 // helper to provide a map from bound parameters to coordinates
238 template <std::size_t DIM>
240 parameterMap(const Acts::GeometryContext& geometryContext,
241 const Acts::CalibrationContext& calibrationContext,
242 const Acts::Surface& surface) const {
243 return m_projector.parameterMap<DIM>(geometryContext,calibrationContext,surface);
244 }
245
246 // helper which returns a delegate to perform the post calibration for the given measurement type and dimension
247 template <std::size_t DIM, typename measurement_t>
250 return m_calibrators.template calibrator<DIM,measurement_t>();
251 }
252
253 // helper which returns a delegate or lambda to get the measurement and covariance used during the selection
254 template <std::size_t DIM, typename measurement_t>
255 auto
257 if constexpr(s_fullPreCalibration) {
258 // full calibration during selection
259 return m_preCalibrators.template calibrator<DIM,measurement_t>();
260 }
261 else {
262 // no calibration is performed before the measurement selection, so just Eigen maps to the stored location
263 // and covariance are returned.
264 // @TODO unfortunately the Eigen Maps cannot be used directly because they are incompatible with the
265 // temporary measurement storage used in the measurement selector, so need to convert to the
266 // above ConstVectorMapWithInvalidDef etc. Does this introduce some overhead ?
267 return []( [[maybe_unused]] const Acts::GeometryContext&,
268 [[maybe_unused]] const Acts::CalibrationContext&,
269 [[maybe_unused]] const Acts::Surface&,
270 const measurement_t &measurement,
271 [[maybe_unused]] const typename traits::BoundTrackParameters &) {
272 return std::make_tuple( measurement.template localPosition<DIM>(), measurement.template localCovariance<DIM>(), 0u );
273 };
274 }
275 }
276
277 std::tuple<const measurement_container_variant_t *, abstract_measurement_range_t, bool >
278 containerAndRange(const Acts::Surface &surface) const {
280 auto ret = containerAndRangeSingle(*m_measurementRangesForced, surface, true);
281 if (std::get<0>(ret)) return ret;
282 }
283 return containerAndRangeSingle(*m_measurementRanges, surface, false);
284 }
285
286
287 template <typename MeasurementRangeList_t>
288 static std::tuple<const measurement_container_variant_t *, abstract_measurement_range_t, bool >
289 containerAndRangeSingle(const MeasurementRangeList_t& measurementRanges, const Acts::Surface &surface, bool forced) {
290 typename MeasurementRangeList_t::const_iterator range_iter = measurementRanges.find(surface.geometryId().value());
291 if (range_iter == measurementRanges.end())
292 {
293 return {nullptr, abstract_measurement_range_t{}, forced};
294 }
295 else {
296 abstract_measurement_range_t range{range_iter->second.elementBeginIndex(),
297 range_iter->second.elementEndIndex()};
298 assert( !range_iter->second.isMeasurementExpected() || range.begin() <= range.end());
299 // if surface marked as defect
300 return { forced || range_iter->second.isMeasurementExpected() ? &(measurementRanges.container(range_iter->second.containerIndex())) : nullptr,
301 std::move(range), forced};
302 }
303 }
304
305 bool expectMeasurements([[maybe_unused]] const Acts::Surface &surface,
306 [[maybe_unused]] const measurement_container_variant_t *container_variant_ptr,
307 const abstract_measurement_range_t &abstract_range) const {
308 return (abstract_range.begin()<=abstract_range.end());
309 }
310
311 template <typename measurement_container_t>
312 auto
313 rangeForContainer(const measurement_container_t &concrete_container,
314 const abstract_measurement_range_t &abstract_range) const {
315 unsigned int begin_idx = abstract_range.front();
316 auto begin_iter = concrete_container.container().begin() + begin_idx;
317 auto end_iter = begin_iter + static_cast<unsigned int>(abstract_range.size());
318 return std::ranges::subrange(begin_iter, end_iter);
319 }
320};
321
322namespace {
323 // the track back-end used during track finding
324 using RecoTrackContainer = Acts::TrackContainer<Acts::VectorTrackContainer,
325 Acts::VectorMultiTrajectory>;
326
327 static constexpr std::size_t gAbsoluteMaxBranchesPerSurface = 3; // the absolute maximum number of branches per surface
328 // the actual value is configurable up to this number
329
330
331 // Wrapper class which provides the actual measurement selector and
332 // allows to connect it to the delegate used by the track finder
333 template <typename traj_t>
334 class AtlasActsMeasurmentSelector : public ActsTrk::IMeasurementSelector {
335 public:
336 using TheAtlasMeasurementSelector
337 = AtlasMeasurementSelector<
338 gAbsoluteMaxBranchesPerSurface,
339 traj_t,
341 // where measurement_container_variant_t is e.g.
342 // variant< ContainerRefWithDim<xAOD::PixelClusterContainer,2>, ... >
343 >;
344
345 using BoundState = std::tuple<Acts::BoundTrackParameters, Acts::BoundMatrix, double>;
346 // the delegate used by the track finder to which the measurement selector needs to be connected to
347
348 AtlasActsMeasurmentSelector(ActsTrk::MeasurementCalibrator<traj_t> &&calibrator,
349 const ActsTrk::detail::MeasurementRangeList &measurementRanges,
351 : m_calibrator( std::move(calibrator)),
352 m_measurementSelector(std::move(config),
353 measurementRanges)
354 {
355 // have to register one calibrator per measurement container type and associated dimension.
356 // @TODO unfortunately automatic type deduction does not work, so have to provide the type
357 // additionally
358 if constexpr( s_fullPreCalibration) {
359 m_measurementSelector.template setPreCalibrator<2,xAOD::PixelCluster>(m_calibrator.pixelPreCalibrator());
360 m_measurementSelector.template setPreCalibrator<1,xAOD::StripCluster>(m_calibrator.stripPreCalibrator());
361 m_measurementSelector.template setPreCalibrator<3,xAOD::HGTDCluster>(m_calibrator.hgtdPreCalibrator());
362 m_measurementSelector.template setCalibrator<2,xAOD::PixelCluster>(m_calibrator.pixelPostCalibrator());
363 m_measurementSelector.template setCalibrator<1,xAOD::StripCluster>(m_calibrator.stripPostCalibrator());
364 m_measurementSelector.template setCalibrator<3,xAOD::HGTDCluster>(m_calibrator.hgtdPostCalibrator());
365 }
366 else {
367 m_measurementSelector.template setCalibrator<2,xAOD::PixelCluster>(m_calibrator.pixelPostCalibrator());
368 m_measurementSelector.template setCalibrator<1,xAOD::StripCluster>(m_calibrator.stripPostCalibrator());
369 m_measurementSelector.template setCalibrator<3,xAOD::HGTDCluster>(m_calibrator.hgtdPostCalibrator());
370 }
371 }
372
373 // called by the track finder to connect this measurement selector to the ckf.
374 void connect(std::any delegate_ptr) const override {
375 using TrackStateCreator = Acts::CombinatorialKalmanFilterExtensions<RecoTrackContainer>::TrackStateCreator;
376
377 auto delegate = std::any_cast< TrackStateCreator *>(delegate_ptr);
378 delegate->template connect< & TheAtlasMeasurementSelector::createTrackStates >(&m_measurementSelector);
379 }
380
381 void setMeasurementRangesForced(const ActsTrk::detail::MeasurementRangeListFlat *measurementRangesForced) override {
382 m_measurementSelector.setMeasurementRangesForced(measurementRangesForced);
383 }
384
385 // provides the calibrators
386 ActsTrk::MeasurementCalibrator<traj_t> m_calibrator;
387
388 // the actual measurement selector
389 TheAtlasMeasurementSelector m_measurementSelector;
390 };
391}
392
393namespace ActsTrk::detail {
394// return a configured, wrapper for the measurement selector
395std::unique_ptr<ActsTrk::IMeasurementSelector> getMeasurementSelector(const EventContext &ctx,
399 const ActsTrk::detail::MeasurementRangeList &measurementRanges,
400 const std::vector<float> &etaBinsf,
401 const std::vector<std::pair<float, float> > &chi2CutOffOutlier,
402 const std::vector<size_t> &numMeasurementsCutOff,
403 double edge_hole_border_width) {
404
405 // set calibrators per measurement container type (order does not matter);
407 pixelOnTrackCalibratorTool,
408 stripOnTrackCalibratorTool,
409 hgtdOnTrackCalibratorTool);
410 using AtlMeasurementSelectorCuts = AtlasMeasurementSelectorCuts;
411
412 using AtlMeasurementSelector = AtlasActsMeasurmentSelector<detail::RecoTrackStateContainer>;
413 using AtlMeasurementSelectorConfig = AtlMeasurementSelector::TheAtlasMeasurementSelector::Config;
414
415 std::unique_ptr<ActsTrk::IMeasurementSelector>
416 selector(new AtlMeasurementSelector(
417 std::move(atl_measurement_calibrator),
418 measurementRanges,
419 AtlMeasurementSelectorConfig{
420 {Acts::GeometryIdentifier(),
421 AtlMeasurementSelectorCuts{ etaBinsf,
422 chi2CutOffOutlier,
423 numMeasurementsCutOff,
424 edge_hole_border_width==0.
425 ? std::optional<Acts::BoundaryTolerance>{}
426 : std::optional{Acts::BoundaryTolerance::AbsoluteEuclidean(-std::abs(edge_hole_border_width))}
427 }
428 }}));
429 return selector;
430}
431}
static constexpr bool s_fullPreCalibration
CalibratorRegistryBase< PreCalibratorTypeTraits< MeasurementTypeTraits, measurement_container_variant_t, bound_track_parameters_t >, measurement_container_variant_t > PreCalibratorRegistry
CalibratorRegistryBase< CalibratorTypeTraits< MeasurementTypeTraits, measurement_container_variant_t, track_state_proxy_t >, measurement_container_variant_t > CalibratorRegistry
static Double_t a
A structure to contain data associated with the calibration of a certain sub-module.
Definition Calibrator.h:178
Hash functions to pack the source link into unordered_maps / unordered_sets.
std::unique_ptr< ActsTrk::IMeasurementSelector > getMeasurementSelector(const EventContext &ctx, const ActsTrk::IPixelOnTrackCalibratorTool< detail::RecoTrackStateContainer > *pixelOnTrackCalibratorTool, const ActsTrk::IStripOnTrackCalibratorTool< detail::RecoTrackStateContainer > *stripOnTrackCalibratorTool, const ActsTrk::IHGTDOnTrackCalibratorTool< detail::RecoTrackStateContainer > *hgtdOnTrackCalibratorTool, const ActsTrk::detail::MeasurementRangeList &measurementRanges, const std::vector< float > &etaBinsf, const std::vector< std::pair< float, float > > &chi2CutOffOutlier, const std::vector< size_t > &numMeasurementsCutOff, double edge_hole_border_width)
GenMeasurementRangeListFlat< AtlasMeasurementContainerList > MeasurementRangeListFlat
Acts::TrackContainer< Acts::VectorTrackContainer, Acts::VectorMultiTrajectory > RecoTrackContainer
GenMeasurementRangeList< AtlasMeasurementContainerList > MeasurementRangeList
STL namespace.
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Eigen::Matrix< float, N, N > MeasMatrix
Eigen::Map< const MeasMatrix< N > > ConstMatrixMap
Eigen::Matrix< float, N, 1 > MeasVector
Abrivation of the Matrix & Covariance definitions.
Eigen::Map< const MeasVector< N > > ConstVectorMap
typename traits::template CalibratedMeasurement< DIM > Measurement
typename traits::template MeasurementContainerTraits< T_Container >::value_type MeassurementContainerValueType
typename traits::template CalibratedMeasurementCovariance< DIM > MeasurementCovariance
ATALS specific Implementation of the member functions needed by the measurement selector.
typename traits::template CalibratedMeasurement< DIM > Measurement
CalibratorTypeTraits< CalibratedMeasurementTraits, measurement_container_variant_t, typename traits::TrackStateProxy >::template Calibrator< DIM, measurement_t > Calibrator
void setCalibrator(const Calibrator< DIM, T_ValueType > &calibrator)
AtlasMeasurementSelector(typename BASE::Config &&config, const ActsTrk::detail::MeasurementRangeList &measurementRanges)
const Calibrator< DIM, measurement_t > & postCalibrator() const
BASE::abstract_measurement_range_t abstract_measurement_range_t
MeasurementSelectorBaseImpl< NMeasMax, AtlasMeasurementSelector< NMeasMax, traj_t, measurement_container_variant_t >, measurement_container_variant_t > BASE
void setMeasurementRangesForced(const ActsTrk::detail::MeasurementRangeListFlat *measurementRangesForced)
bool expectMeasurements(const Acts::Surface &surface, const measurement_container_variant_t *container_variant_ptr, const abstract_measurement_range_t &abstract_range) const
ParameterMapping::type< DIM > parameterMap(const Acts::GeometryContext &geometryContext, const Acts::CalibrationContext &calibrationContext, const Acts::Surface &surface) const
PreCalibratorTypeTraits< CalibratedMeasurementTraits, measurement_container_variant_t, typename traits::BoundTrackParameters >::template Calibrator< DIM, measurement_t > PreCalibrator
CalibratorRegistry< CalibratedMeasurementTraits, measurement_container_variant_t, typename traits::TrackStateProxy > m_calibrators
void setPreCalibrator(typename std::enable_if< s_CanPreCalibrate< DIM >, const PreCalibrator< DIM, T_ValueType > & >::type calibrator)
auto rangeForContainer(const measurement_container_t &concrete_container, const abstract_measurement_range_t &abstract_range) const
static std::tuple< const measurement_container_variant_t *, abstract_measurement_range_t, bool > containerAndRangeSingle(const MeasurementRangeList_t &measurementRanges, const Acts::Surface &surface, bool forced)
std::conditional< s_fullPreCalibration, PreCalibratorRegistry< CalibratedMeasurementTraits, measurement_container_variant_t, typenametraits::BoundTrackParameters >, Empty >::type m_preCalibrators
std::tuple< const measurement_container_variant_t *, abstract_measurement_range_t, bool > containerAndRange(const Acts::Surface &surface) const
ConstMatrixMapWithInvalidDef< DIM > & operator=(ConstMatrixMapWithInvalidDef< DIM > &&a)
ConstMatrixMapWithInvalidDef< DIM > & operator=(const xAOD::ConstMatrixMap< DIM > &a)
ConstMatrixMapWithInvalidDef< DIM > & operator=(const ConstMatrixMapWithInvalidDef< DIM > &a)
ConstVectorMapWithInvalidDef< DIM > & operator=(const ConstVectorMapWithInvalidDef< DIM > &a)
ConstVectorMapWithInvalidDef< DIM > & operator=(ConstVectorMapWithInvalidDef< DIM > &&a)
ConstVectorMapWithInvalidDef< DIM > & operator=(const xAOD::ConstVectorMap< DIM > &a)
MeasurementSelectorTraits< AtlasMeasurementSelector< NMeasMax, traj_t, measurement_container_variant_t > >::abstract_measurement_range_t abstract_measurement_range_t
MeasurementSelectorTraits< AtlasMeasurementSelector< NMeasMax, traj_t, measurement_container_variant_t > > traits
std::conditional< s_fullPreCalibration, CalibratedMeasurementCovariance< N >, ConstMatrixMapWithInvalidDef< N > >::type PreSelectionMeasurementCovariance
std::conditional< s_fullPreCalibration, CalibratedMeasurement< N >, ConstVectorMapWithInvalidDef< N > >::type PreSelectionMeasurement
std::array< unsigned char, N > type