ATLAS Offline Software
Loading...
Searching...
No Matches
TrackFindingMeasurements.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
9
10namespace ActsTrk::detail {
11
12 TrackFindingMeasurements::TrackFindingMeasurements(std::size_t nMeasurementContainerMax)
13 : m_measurementOffsets(nMeasurementContainerMax, 0ul) {
14 m_containers.reserve(nMeasurementContainerMax);
15 }
16
18 const xAOD::UncalibratedMeasurementContainer &clusterContainer,
19 const DetectorElementToActsGeometryIdMap &detectorElementToGeoid,
20 const MeasurementIndex *measurementIndex) {
21 unsigned int typeIndex32 = static_cast<unsigned int>(typeIndex);
22 if (typeIndex < m_measurementOffsets.size())
24 if (!(typeIndex < m_containers.size()))
25 m_containers.resize(typeIndex + 1);
26 m_containers[typeIndex] = &clusterContainer;
27 if (measurementIndex)
28 m_surfaceIndices.resize(measurementIndex->size());
29
30 if (m_measurementRanges.empty()) {
31 // try to reserve needed space,
32 // this however will reserve more than necessary not just the space needed for the surfaces of
33 // all the measurements that are going to be added (e.g. pixel+strips).
34 m_measurementRanges.reserve(detectorElementToGeoid.size());
35 }
36 m_measurementRanges.setContainer(typeIndex32, &clusterContainer);
37
38 xAOD::DetectorIDHashType lastIdHash = std::numeric_limits<xAOD::DetectorIDHashType>::max();
39 MeasurementRange *currentRange = nullptr;
40
41 std::size_t n_elements = clusterContainer.size();
42 unsigned int sl_idx = 0;
43 Acts::GeometryIdentifier measurementSurfaceId{};
44 for (; sl_idx < n_elements; ++sl_idx) {
45 const auto *measurement = clusterContainer[sl_idx];
46 xAOD::DetectorIDHashType idHash = measurement->identifierHash();
47 if (idHash != lastIdHash) {
48 if (currentRange) {
49 currentRange->updateEnd(typeIndex, sl_idx);
50 }
51 lastIdHash = idHash;
52
53 measurementSurfaceId = ActsTrk::getSurfaceGeometryIdOfMeasurement(detectorElementToGeoid, *measurement);
54
55 currentRange = addMeasurementToRange(m_measurementRanges, typeIndex32, sl_idx, sl_idx, measurement, measurementSurfaceId);
56 }
57 if (measurementIndex) {
58 // sl_idx may be different from measurement->index() if we aren't passed the owning container (eg. with cached mode).
59 // So we save the mapping here. This is only needed by setMeasurementRangesForced(), so measurementIndex is optional.
60 // We also save the measurementSurfaceId for quick access. Note that this may have been calculated on a previous iteration for the same id hash.
61 std::size_t idx = measurementIndex->index(*measurement);
62 if (idx < m_surfaceIndices.size())
63 m_surfaceIndices.at(idx) = {measurementSurfaceId, typeIndex32, sl_idx};
64 }
65 }
66
67 if (currentRange) {
68 currentRange->updateEnd(typeIndex, sl_idx);
69 }
70
71 m_measurementsTotal += clusterContainer.size();
72 }
73
74 template <typename MeasurementRangeList_t>
77 unsigned int typeIndex,
78 unsigned int sl_idx,
79 unsigned int sl_idx_end,
80 const xAOD::UncalibratedMeasurement *measurement,
81 Acts::GeometryIdentifier measurementSurfaceId) {
82 if (measurementSurfaceId.value() == 0u) {
83 std::stringstream msg;
84 msg << "No Acts surface associated to measurement "
85 << sl_idx << " type = " << static_cast<unsigned int>(measurement->type())
86 << " idHash=" << measurement->identifierHash();
87 throw std::domain_error(msg.str());
88 }
89
90 // start with en empty range which is updated later.
91 auto ret = measurementRanges.insert(std::make_pair(measurementSurfaceId.value(),
92 MeasurementRange(typeIndex, sl_idx, sl_idx_end)));
93 if (!ret.second) {
94 std::stringstream msg;
95 msg << "Measurement not clustered by identifierHash / geometryId. New measurement "
96 << sl_idx << " with geo Id " << measurementSurfaceId
97 << " type = " << static_cast<unsigned int>(measurement->type())
98 << " idHash=" << measurement->identifierHash()
99 << " but already recorded for this geo ID the range : [" << ret.first->second.containerIndex() << "]"
100 << ret.first->second.elementBeginIndex()
101 << " .. " << ret.first->second.elementEndIndex()
102 << (ret.first->second.isConsistentRange() ? "" : " !Container index inconsistent or not in increasing order!");
103 throw std::runtime_error(msg.str());
104 }
105 return &ret.first->second;
106 }
107
108 MeasurementRange TrackFindingMeasurements::markSurfaceInsensitive(const Acts::GeometryIdentifier &identifier) {
109 auto ret = m_measurementRanges.insert(std::make_pair(identifier.value(),
111 if (!ret.second) {
112 return ret.first->second;
113 } else {
114 return MeasurementRange();
115 }
116 }
117
120 const MeasurementIndex &measurementIndex) const {
121 ActsTrk::detail::MeasurementRangeListFlat measurementRangesForced;
122 measurementRangesForced.reserve(seed.sp().size()); // wrong for strip seeds, but just means an extra allocation in this rare case
123 for (const xAOD::SpacePoint *sp : seed.sp()) {
124 for (const xAOD::UncalibratedMeasurement *measurement : sp->measurements()) {
125 std::size_t idx = measurementIndex.index(*measurement);
126 if (!(idx < m_surfaceIndices.size())) {
127 // The measurement was not found in the measurementIndex.
128 // This could happen if no measurements in the same owning container were provided to addMeasurements().
129 continue;
130 }
131 auto [measurementSurfaceId, typeIndex, sl_idx] = m_surfaceIndices.at(idx);
132 if (measurementSurfaceId.value() == 0ul) {
133 // This measurement was not provided to addMeasurements(), so we can't force the track onto it.
134 // This happens in secondary passes, which are given a reduced set of measurements.
135 // Note that the test uses measurementSurfaceId=0, since 0 is valid for the other members.
136 continue;
137 }
138 assert(container(typeIndex)->at(sl_idx) == measurement);
139 measurementRangesForced.setContainer(typeIndex, container(typeIndex));
140 addMeasurementToRange(measurementRangesForced,
141 typeIndex,
142 sl_idx,
143 sl_idx + 1,
144 measurement,
145 measurementSurfaceId);
146 }
147 }
148 return measurementRangesForced;
149 }
150
151} // namespace ActsTrk::detail
void setContainer(unsigned int container_index, const xAOD::UncalibratedMeasurementContainer *container)
std::size_t index(const xAOD::UncalibratedMeasurement &hit) const
std::vector< const xAOD::UncalibratedMeasurementContainer * > m_containers
const xAOD::UncalibratedMeasurementContainer * container(std::size_t typeIndex) const
std::vector< MeasurementSurfaceIndex > m_surfaceIndices
void addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer &clusterContainer, const DetectorElementToActsGeometryIdMap &detectorElementToGeoid, const MeasurementIndex *measurementIndex=nullptr)
MeasurementRangeListFlat setMeasurementRangesForced(const ActsTrk::Seed &seed, const MeasurementIndex &measurementIndex) const
const MeasurementRangeList & measurementRanges() const
static MeasurementRange * addMeasurementToRange(MeasurementRangeList_t &measurementRanges, unsigned int typeIndex, unsigned int sl_idx, unsigned int sl_idx_end, const xAOD::UncalibratedMeasurement *measurement, Acts::GeometryIdentifier measurementSurfaceId)
MeasurementRange markSurfaceInsensitive(const Acts::GeometryIdentifier &identifier)
TrackFindingMeasurements(std::size_t nMeasurementContainerMax)
size_type size() const noexcept
Returns the number of elements in the collection.
DetectorIDHashType identifierHash() const
Returns the IdentifierHash of the measurement (corresponds to the detector element IdentifierHash)
virtual xAOD::UncalibMeasType type() const =0
Returns the type of the measurement type as a simple enumeration.
Athena definition of the Eigen plugin.
GenMeasurementRangeListFlat< AtlasMeasurementContainerList > MeasurementRangeListFlat
Acts::GeometryIdentifier getSurfaceGeometryIdOfMeasurement(const DetectorElementToActsGeometryIdMap &detector_element_to_geoid, const xAOD::UncalibratedMeasurement &measurement)
UncalibratedMeasurementContainer_v1 UncalibratedMeasurementContainer
Define the version of the uncalibrated measurement container.
unsigned int DetectorIDHashType
@ detector ID element hash
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
void updateEnd(std::size_t container_idx, unsigned int end_element_idx)
MsgStream & msg
Definition testRead.cxx:32