ATLAS Offline Software
Loading...
Searching...
No Matches
AtlasMeasurementSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7
11
12#include "Acts/Definitions/Common.hpp"
13#include "Acts/Definitions/Algebra.hpp"
14#include "Acts/Utilities/VectorHelpers.hpp"
15#include "Acts/Utilities/Delegate.hpp"
16#include "Acts/Utilities/Result.hpp"
17#include "Acts/Geometry/GeometryContext.hpp"
18#include "Acts/Utilities/CalibrationContext.hpp"
19#include "Acts/EventData/TrackParameters.hpp"
20#include "Acts/Surfaces/Surface.hpp"
21#include "Acts/Utilities/Logger.hpp"
22#include "Acts/TrackFinding/CombinatorialKalmanFilter.hpp"
23#include "Acts/TrackFinding/TrackStateCreator.hpp"
24
30
35
36#include "boost/container/small_vector.hpp"
37
38#include <tuple>
39#include <type_traits>
40#include <span>
41#include <ranges>
42
44
45template <std::size_t NMeasMax, typename traj_t, typename measurement_container_variant_t>
47
48static constexpr bool s_fullPreCalibration=true;
49
50// need an "Eigen Map" which is default constructable and assignable
51// and where an assignment changes the data pointer not the contents of
52// the data it was pointing to.
53template <std::size_t DIM>
55 ConstVectorMapWithInvalidDef() : xAOD::ConstVectorMap<DIM>{nullptr} {}
57 this->m_data = a.m_data;
58 return *this;
59 }
61 this->m_data = a.m_data;
62 return *this;
63 }
65 this->m_data = a.data();
66 return *this;
67 }
68 using xAOD::ConstVectorMap<DIM>::ConstVectorMap;
69};
70
71// see above
72template <std::size_t DIM>
74 ConstMatrixMapWithInvalidDef() : xAOD::ConstMatrixMap<DIM>{nullptr} {}
76 this->m_data = a.m_data;
77 return *this;
78 }
80 this->m_data = a.m_data;
81 return *this;
82 }
84 this->m_data = a.data();
85 return *this;
86 }
87 using xAOD::ConstMatrixMap<DIM>::ConstMatrixMap;
88};
89
94template <std::size_t NMeasMax, typename traj_t, typename measurement_container_variant_t>
95struct MeasurementSelectorTraits< AtlasMeasurementSelector<NMeasMax, traj_t, measurement_container_variant_t> >
96{
97 // the measurement type after the selection e.g. a Matrix<N,1>
98 template <std::size_t N>
100
101 // the measurement covariance type after the selection e.g. a Matrix<N,N>
102 template <std::size_t N>
104
105 // the measurement type before the selection e.g. an Eigen::Map< Matrix<N,1> > if
106 // the calibration is performed after the selection
107 template <std::size_t N>
111
112 // the measurement covariance type before the selection e.g. an Eigen::Map<Matrix<N,N> > if
113 // the calibration is performed after the selection
114 template <std::size_t N>
118 // e.g. the same as CalibratedMeasurement
119 template <std::size_t N>
121
122 // e.g. the same as CalibratedMeasurementCovariance
123 template <std::size_t N>
125
126 // e.g. helper template to get the value_type from the measurement range iterator type
127 template <typename T_MeasurementRangeIterator>
129 using value_type = typename T_MeasurementRangeIterator::value_type;
130 };
131
132 using abstract_measurement_range_t = std::ranges::iota_view<unsigned int, unsigned int>;
133
134 // the trajectory type to which states for selected measurements are to be added
135 using trajectory_t = traj_t;
136 // the track state type for new track states
137 using TrackStateProxy = typename traj_t::TrackStateProxy;
138
139 // the value type usd for matrices
140 using MatrixFloatType = double;
141 using BoundTrackParameters = Acts::BoundTrackParameters;
142 using BoundMatrix = Acts::BoundMatrix;
143
144 using BoundState = std::tuple<BoundTrackParameters, BoundMatrix, double>;
145
146 // maximum dimension of measurements determined from the measurement "container" variant
148
149 // must be the same as what is used for the CKF
150 static constexpr std::size_t s_maxBranchesPerSurface = 10;
151};
152
154template <std::size_t NMeasMax, typename traj_t, typename measurement_container_variant_t>
156 : public MeasurementSelectorBaseImpl<NMeasMax,
157 AtlasMeasurementSelector<NMeasMax, traj_t, measurement_container_variant_t> ,
158 measurement_container_variant_t >
159{
160 // @TODO can these redundent definitions been avoided ?
163 measurement_container_variant_t >;
164 // BASE::trats are MeasurementSelectorTraits< ... decltype(*this) >
165 using traits = typename BASE::traits;
166
167 template <std::size_t DIM>
168 using Measurement = typename traits::template CalibratedMeasurement<DIM>;
169
171
172 // the delegate used for the final calibration
173 template <std::size_t DIM, typename measurement_t>
174 using Calibrator = Acts::Delegate<
175 std::pair < typename traits::template CalibratedMeasurement<DIM>,
176 typename traits::template CalibratedMeasurementCovariance<DIM> >
177 (const Acts::GeometryContext&,
178 const Acts::CalibrationContext&,
179 const measurement_t &,
180 const typename traits::BoundTrackParameters &)>;
181
182 // helper to determine the calibrator type from the measurement container tyoe
183 // and to define the types used for the calibrated measurement and covariance
185 // the types used for the calibrated measurement and covariance
186 template <std::size_t DIM>
187 using Measurement = typename traits::template CalibratedMeasurement<DIM>;
188 template <std::size_t DIM>
189 using MeasurementCovariance = typename traits::template CalibratedMeasurementCovariance<DIM>;
190
191 // helper to determine the measurement value type from the container type
192 template <typename T_Container>
193 using MeassurementContainerValueType = typename traits::template MeasurementContainerTraits<T_Container>::value_type;
194 };
195
198
200 m_measurementRangesForced = measurementRangesForced;
201 }
202
203 // Helper to provide the mapping between bound parameters and coordinates
204 // @TODO is the default projector always good enough or is there some dependency
205 // on the geoemtry ?
208 struct Empty {};
209 std::conditional<s_fullPreCalibration,
212
213
215 const ActsTrk::detail::MeasurementRangeList &measurementRanges)
216 : BASE{std::move(config)},
217 m_measurementRanges(&measurementRanges)
218 {}
219
220 // register a calibrator for the given measurement type and the measurement dimension i.e. number of coordinates
221 template <std::size_t DIM, typename T_ValueType>
224 }
225
226 template <std::size_t DIM>
227 static constexpr bool s_CanPreCalibrate = std::is_same< typename traits::template PreSelectionMeasurement<DIM>,
228 typename traits::template CalibratedMeasurement<DIM> >::value
229 && std::is_same< typename traits::template PreSelectionMeasurementCovariance<DIM>,
230 typename traits::template CalibratedMeasurementCovariance<DIM> >::value;
231
232 template < std::size_t DIM, typename T_ValueType >
233 void setPreCalibrator(typename std::enable_if<s_CanPreCalibrate<DIM>, const Calibrator<DIM, T_ValueType> &>::type calibrator) {
235 }
236
237 // helper to create a Acts::SourceLink from an uncalibrated measurement pointer
238 template <typename T_Value>
239 static Acts::SourceLink makeSourceLink(T_Value &&value) {
240 // value is pointer
241 static_assert( !std::is_same<std::remove_pointer_t<T_Value>, T_Value>::value );
242 // ... and pointer to xAOD::UncalibgratedMeasurement
243 static_assert(std::is_base_of_v< xAOD::UncalibratedMeasurement, std::remove_cv_t<std::remove_pointer_t<T_Value> > > );
244 return Acts::SourceLink{ ActsTrk::makeATLASUncalibSourceLink(value) };
245 }
246
247 // helper to provide a map from bound parameters to coordinates
248 template <std::size_t DIM>
250 parameterMap(const Acts::GeometryContext& geometryContext,
251 const Acts::CalibrationContext& calibrationContext,
252 const Acts::Surface& surface) const {
253 return m_projector.parameterMap<DIM>(geometryContext,calibrationContext,surface);
254 }
255
256 // helper which returns a delegate to perform the post calibration for the given measurement type and dimension
257 template <std::size_t DIM, typename measurement_t>
260 return m_calibrators.template calibrator<DIM,measurement_t>();
261 }
262
263 // helper which returns a delegate or lambda to get the measurement and covariance used during the selection
264 template <std::size_t DIM, typename measurement_t>
265 auto
267 if constexpr(s_fullPreCalibration) {
268 // full calibration during selection
269 return m_preCalibrators.template calibrator<DIM,measurement_t>();
270 }
271 else {
272 // no calibration is performed before the measurement selection, so just Eigen maps to the stored location
273 // and covariance are returned.
274 // @TODO unfortunately the Eigen Maps cannot be used directly because they are incompatible with the
275 // temporary measurement storage used in the measurement selector, so need to convert to the
276 // above ConstVectorMapWithInvalidDef etc. Does this introduce some overhead ?
277 return []( [[maybe_unused]] const Acts::GeometryContext&,
278 [[maybe_unused]] const Acts::CalibrationContext&,
279 const measurement_t &measurement,
280 [[maybe_unused]] const typename traits::BoundTrackParameters &) {
281 return std::make_pair( measurement.template localPosition<DIM>(), measurement.template localCovariance<DIM>() );
282 };
283 }
284 }
285
286 std::tuple<const measurement_container_variant_t *, abstract_measurement_range_t, bool >
287 containerAndRange(const Acts::Surface &surface) const {
289 auto ret = containerAndRangeSingle(*m_measurementRangesForced, surface, true);
290 if (std::get<0>(ret)) return ret;
291 }
292 return containerAndRangeSingle(*m_measurementRanges, surface, false);
293 }
294
295
296 template <typename MeasurementRangeList_t>
297 static std::tuple<const measurement_container_variant_t *, abstract_measurement_range_t, bool >
298 containerAndRangeSingle(const MeasurementRangeList_t& measurementRanges, const Acts::Surface &surface, bool forced) {
299 typename MeasurementRangeList_t::const_iterator range_iter = measurementRanges.find(surface.geometryId().value());
300 if (range_iter == measurementRanges.end())
301 {
302 return {nullptr, abstract_measurement_range_t{}, forced};
303 }
304 else {
305 abstract_measurement_range_t range{range_iter->second.elementBeginIndex(),
306 range_iter->second.elementEndIndex()};
307 assert( !range_iter->second.isMeasurementExpected() || range.begin() <= range.end());
308 // if surface marked as defect
309 return { forced || range_iter->second.isMeasurementExpected() ? &(measurementRanges.container(range_iter->second.containerIndex())) : nullptr,
310 std::move(range), forced};
311 }
312 }
313
314 bool expectMeasurements([[maybe_unused]] const Acts::Surface &surface,
315 [[maybe_unused]] const measurement_container_variant_t *container_variant_ptr,
316 const abstract_measurement_range_t &abstract_range) const {
317 return (abstract_range.begin()<=abstract_range.end());
318 }
319
320 template <typename measurement_container_t>
321 auto
322 rangeForContainer(const measurement_container_t &concrete_container,
323 const abstract_measurement_range_t &abstract_range) const {
324 unsigned int begin_idx = abstract_range.front();
325 auto begin_iter = concrete_container.container().begin() + begin_idx;
326 auto end_iter = begin_iter + static_cast<unsigned int>(abstract_range.size());
327 return std::ranges::subrange(begin_iter, end_iter);
328 }
329};
330
331namespace {
332 // the track back-end used during track finding
333 using RecoTrackContainer = Acts::TrackContainer<Acts::VectorTrackContainer,
334 Acts::VectorMultiTrajectory>;
335
336 static constexpr std::size_t gAbsoluteMaxBranchesPerSurface = 3; // the absolute maximum number of branches per surface
337 // the actual value is configurable up to this number
338
339
340 // Wrapper class which provides the actual measurement selector and
341 // allows to connect it to the delegate used by the track finder
342 template <typename track_container_t>
343 class AtlasActsMeasurmentSelector : public ActsTrk::IMeasurementSelector {
344 public:
345 using TheAtlasMeasurementSelector
346 = AtlasMeasurementSelector<
347 gAbsoluteMaxBranchesPerSurface,
348 typename track_container_t::TrackStateContainerBackend,
350 // where measurement_container_variant_t is e.g.
351 // variant< ContainerRefWithDim<xAOD::PixelClusterContainer,2>, ... >
352 >;
353
354 using BoundState = std::tuple<Acts::BoundTrackParameters, Acts::BoundMatrix, double>;
355 // the delegate used by the track finder to which the measurement selector needs to be connected to
356
357 AtlasActsMeasurmentSelector(ActsTrk::MeasurementCalibrator &&calibrator,
358 const ActsTrk::detail::MeasurementRangeList &measurementRanges,
360 : m_calibrator( std::move(calibrator)),
361 m_measurementSelector(std::move(config),
362 measurementRanges)
363 {
364 // have to register one calibrator per measurement container type and associated dimension.
365 // @TODO unfortunately automatic type deduction does not work, so have to provide the type
366 // additionally
367 if constexpr( s_fullPreCalibration) {
368 m_measurementSelector.template setPreCalibrator<2,xAOD::PixelCluster>(m_calibrator.pixelPreCalibrator());
369 m_measurementSelector.template setPreCalibrator<1,xAOD::StripCluster>(m_calibrator.stripPreCalibrator());
370 m_measurementSelector.template setPreCalibrator<3,xAOD::HGTDCluster>(m_calibrator.hgtdPreCalibrator());
371 m_measurementSelector.template setCalibrator<2,xAOD::PixelCluster>(m_calibrator.pixelPostCalibrator());
372 m_measurementSelector.template setCalibrator<1,xAOD::StripCluster>(m_calibrator.stripPostCalibrator());
373 m_measurementSelector.template setCalibrator<3,xAOD::HGTDCluster>(m_calibrator.hgtdPostCalibrator());
374 }
375 else {
376 m_measurementSelector.template setCalibrator<2,xAOD::PixelCluster>(m_calibrator.pixelPostCalibrator());
377 m_measurementSelector.template setCalibrator<1,xAOD::StripCluster>(m_calibrator.stripPostCalibrator());
378 m_measurementSelector.template setCalibrator<3,xAOD::HGTDCluster>(m_calibrator.hgtdPostCalibrator());
379 }
380 }
381
382 // called by the track finder to connect this measurement selector to the ckf.
383 void connect(std::any delegate_ptr) const override {
384 using TrackStateCreator = Acts::CombinatorialKalmanFilterExtensions<RecoTrackContainer>::TrackStateCreator;
385
386 auto delegate = std::any_cast< TrackStateCreator *>(delegate_ptr);
387 delegate->template connect< & TheAtlasMeasurementSelector::createTrackStates >(&m_measurementSelector);
388 }
389
390 void setMeasurementRangesForced(const ActsTrk::detail::MeasurementRangeListFlat *measurementRangesForced) override {
391 m_measurementSelector.setMeasurementRangesForced(measurementRangesForced);
392 }
393
394 // provides the calibrators
395 ActsTrk::MeasurementCalibrator m_calibrator;
396
397 // the actual measurement selector
398 TheAtlasMeasurementSelector m_measurementSelector;
399 };
400}
401
402namespace ActsTrk::detail {
403// return a configured, wrapper for the measurement selector
404std::unique_ptr<ActsTrk::IMeasurementSelector> getMeasurementSelector(const ActsTrk::IOnBoundStateCalibratorTool *pixelOnTrackCalibratorTool,
405 const ActsTrk::IOnBoundStateCalibratorTool *stripOnTrackCalibratorTool,
406 const ActsTrk::IOnBoundStateCalibratorTool *hgtdOnTrackCalibratorTool,
407 const ActsTrk::detail::MeasurementRangeList &measurementRanges,
408 const std::vector<float> &etaBinsf,
409 const std::vector<std::pair<float, float> > &chi2CutOffOutlier,
410 const std::vector<size_t> &numMeasurementsCutOff) {
411
412 // set calibrators per measurement container type (order does not matter);
413 ActsTrk::MeasurementCalibrator atl_measurement_calibrator(pixelOnTrackCalibratorTool,
414 stripOnTrackCalibratorTool,
415 hgtdOnTrackCalibratorTool);
416 using AtlMeasurementSelectorCuts = AtlasMeasurementSelectorCuts;
417
418 using AtlMeasurementSelector = AtlasActsMeasurmentSelector<RecoTrackContainer>;
419 using AtlMeasurementSelectorConfig = AtlMeasurementSelector::TheAtlasMeasurementSelector::Config;
420
421 std::unique_ptr<ActsTrk::IMeasurementSelector>
422 selector(new AtlMeasurementSelector(
423 std::move(atl_measurement_calibrator),
424 measurementRanges,
425 AtlMeasurementSelectorConfig{ {Acts::GeometryIdentifier(),
426 AtlMeasurementSelectorCuts{ etaBinsf,
427 chi2CutOffOutlier,
428 numMeasurementsCutOff} }}));
429 return selector;
430
431}
432}
static constexpr bool s_fullPreCalibration
static Double_t a
An instance of this class is created for each sub-level of the TRT by the TRTCalibrator.
Definition Calibrator.h:178
Athena definition of the Eigen plugin.
GenMeasurementRangeListFlat< AtlasMeasurementContainerList > MeasurementRangeListFlat
Acts::TrackContainer< Acts::VectorTrackContainer, Acts::VectorMultiTrajectory > RecoTrackContainer
GenMeasurementRangeList< AtlasMeasurementContainerList > MeasurementRangeList
std::unique_ptr< ActsTrk::IMeasurementSelector > getMeasurementSelector(const ActsTrk::IOnBoundStateCalibratorTool *pixelOnTrackCalibratorTool, const ActsTrk::IOnBoundStateCalibratorTool *stripOnTrackCalibratorTool, const ActsTrk::IOnBoundStateCalibratorTool *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)
ATLASUncalibSourceLink makeATLASUncalibSourceLink(const xAOD::UncalibratedMeasurementContainer *container, std::size_t index, const EventContext &ctx)
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
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
void setMeasurementRangesForced(const ActsTrk::detail::MeasurementRangeListFlat *measurementRangesForced)
std::conditional< s_fullPreCalibration, CalibratorRegistry< CalibratedMeasurementTraits, typenametraits::BoundTrackParameters, measurement_container_variant_t >, Empty >::type m_preCalibrators
static Acts::SourceLink makeSourceLink(T_Value &&value)
MeasurementSelectorBaseImpl< NMeasMax, AtlasMeasurementSelector< NMeasMax, traj_t, measurement_container_variant_t >, measurement_container_variant_t > BASE
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
void setPreCalibrator(typename std::enable_if< s_CanPreCalibrate< DIM >, const Calibrator< DIM, T_ValueType > & >::type calibrator)
auto rangeForContainer(const measurement_container_t &concrete_container, const abstract_measurement_range_t &abstract_range) const
Acts::Delegate< std::pair< typename traits::template CalibratedMeasurement< DIM >, typename traits::template CalibratedMeasurementCovariance< DIM > >(const Acts::GeometryContext &, const Acts::CalibrationContext &, const measurement_t &, const typename traits::BoundTrackParameters &)> Calibrator
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::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