ATLAS Offline Software
Loading...
Searching...
No Matches
MuonML::SegmentTrackCandidateBuilderTool Class Referencefinal

#include <SegmentTrackCandidateBuilderTool.h>

Inheritance diagram for MuonML::SegmentTrackCandidateBuilderTool:
Collaboration diagram for MuonML::SegmentTrackCandidateBuilderTool:

Public Member Functions

StatusCode buildCandidates (const EventContext &ctx, const SegmentEdgeGraph &graph, const std::vector< SegmentEdgeScore > &scores, std::vector< std::vector< unsigned > > &candidateIdsPerSegment) const override

Private Attributes

Gaudi::Property< float > m_edgeThreshold
Gaudi::Property< float > m_overlapThreshold
Gaudi::Property< bool > m_useRecoveryComponents
Gaudi::Property< bool > m_symmetrizeDirectedEdges
Gaudi::Property< bool > m_addAllSegmentsRecoveryCandidate
Gaudi::Property< bool > m_keepIsolatedSegments {this, "KeepIsolatedSegments", false}
Gaudi::Property< unsigned > m_minCandidateSize {this, "MinCandidateSize", 2}

Detailed Description

Definition at line 12 of file SegmentTrackCandidateBuilderTool.h.

Member Function Documentation

◆ buildCandidates()

StatusCode MuonML::SegmentTrackCandidateBuilderTool::buildCandidates ( const EventContext & ctx,
const SegmentEdgeGraph & graph,
const std::vector< SegmentEdgeScore > & scores,
std::vector< std::vector< unsigned > > & candidateIdsPerSegment ) const
override

Definition at line 91 of file SegmentTrackCandidateBuilderTool.cxx.

95 {
96
97 candidateIdsPerSegment.assign(graph.nNodes, {});
98
99 if (graph.nNodes == 0) return StatusCode::SUCCESS;
100
101 const auto pairScore = makeUndirectedScores(graph, scores, m_symmetrizeDirectedEdges.value());
102
103 // 1. High-purity cores.
104 std::vector<NodeVec> candidates =
105 componentsAboveThreshold(graph, pairScore,
106 m_overlapThreshold.value(),
107 m_keepIsolatedSegments.value());
108
109 // 2. Recall recovery components.
110 //
111 // This is the important no-loss improvement. A true trajectory may contain
112 // only 0.3--0.7 edge probabilities, especially for difficult segments.
113 // The previous implementation never created a candidate unless some edge
114 // crossed OverlapThreshold. Here we add an extra low-threshold connected
115 // component candidate.
116 if (m_useRecoveryComponents.value()) {
117 std::vector<NodeVec> recovery =
118 componentsAboveThreshold(graph, pairScore,
119 m_edgeThreshold.value(),
120 m_keepIsolatedSegments.value());
121 candidates.insert(candidates.end(),
122 std::make_move_iterator(recovery.begin()),
123 std::make_move_iterator(recovery.end()));
124 }
125
126 // 3. Optional validation/debug safety net.
127 //
128 // This should be disabled for production timing studies, but it is useful
129 // when proving that remaining losses are due to the model/graph pruning
130 // rather than the seeding wrapper.
132 graph.nNodes >= m_minCandidateSize.value()) {
133 NodeVec all(graph.nNodes);
134 std::iota(all.begin(), all.end(), 0);
135 candidates.push_back(std::move(all));
136 }
137
138 // 4. Remove exact duplicate candidate node sets and assign IDs.
139 std::set<NodeVec> seen;
140 unsigned next = 0;
141 for (NodeVec& nodes : candidates) {
142 std::sort(nodes.begin(), nodes.end());
143 nodes.erase(std::unique(nodes.begin(), nodes.end()), nodes.end());
144 if (nodes.size() < m_minCandidateSize.value()) continue;
145 if (!seen.insert(nodes).second) continue;
146
147 for (std::size_t n : nodes) {
148 addUnique(candidateIdsPerSegment[n], next);
149 }
150 ++next;
151 }
152
153 for (auto& ids : candidateIdsPerSegment) {
154 std::sort(ids.begin(), ids.end());
155 }
156
157 std::unordered_map<unsigned, unsigned> candSegCount;
158 candSegCount.reserve(next);
159 for (const auto& ids : candidateIdsPerSegment) {
160 for (unsigned id : ids) ++candSegCount[id];
161 }
162
163 std::size_t assignedNodes = 0;
164 std::size_t multiAssignedNodes = 0;
165 for (const auto& ids : candidateIdsPerSegment) {
166 assignedNodes += !ids.empty();
167 multiAssignedNodes += ids.size() > 1;
168 }
169
170 ATH_MSG_DEBUG("buildCandidates: " << candSegCount.size()
171 << " candidate(s) from " << graph.nNodes
172 << " segment(s); assignedNodes=" << assignedNodes
173 << ", multiAssignedNodes=" << multiAssignedNodes
174 << ", edgeThreshold=" << m_edgeThreshold.value()
175 << ", overlapThreshold=" << m_overlapThreshold.value()
176 << ", recovery=" << m_useRecoveryComponents.value()
177 << ", symmetrize=" << m_symmetrizeDirectedEdges.value());
178 if (msgLvl(MSG::VERBOSE)) {
179 for (const auto& [id, nSegs] : candSegCount) {
180 ATH_MSG_VERBOSE(" candidate " << id << ": " << nSegs << " segment(s)");
181 }
182 }
183
184 return StatusCode::SUCCESS;
185}
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
FastGraph::NodeVec NodeVec
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

Member Data Documentation

◆ m_addAllSegmentsRecoveryCandidate

Gaudi::Property<bool> MuonML::SegmentTrackCandidateBuilderTool::m_addAllSegmentsRecoveryCandidate
private
Initial value:
{
this, "AddAllSegmentsRecoveryCandidate", false,
"Add one final candidate containing all graph nodes; use only for no-loss validation/debugging"}

Definition at line 36 of file SegmentTrackCandidateBuilderTool.h.

36 {
37 this, "AddAllSegmentsRecoveryCandidate", false,
38 "Add one final candidate containing all graph nodes; use only for no-loss validation/debugging"};

◆ m_edgeThreshold

Gaudi::Property<float> MuonML::SegmentTrackCandidateBuilderTool::m_edgeThreshold
private
Initial value:
{
this, "EdgeThreshold", 0.25f,
"Loose edge probability threshold used for recall/recovery components"}

Definition at line 20 of file SegmentTrackCandidateBuilderTool.h.

20 {
21 this, "EdgeThreshold", 0.25f,
22 "Loose edge probability threshold used for recall/recovery components"};

◆ m_keepIsolatedSegments

Gaudi::Property<bool> MuonML::SegmentTrackCandidateBuilderTool::m_keepIsolatedSegments {this, "KeepIsolatedSegments", false}
private

Definition at line 40 of file SegmentTrackCandidateBuilderTool.h.

40{this, "KeepIsolatedSegments", false};

◆ m_minCandidateSize

Gaudi::Property<unsigned> MuonML::SegmentTrackCandidateBuilderTool::m_minCandidateSize {this, "MinCandidateSize", 2}
private

Definition at line 41 of file SegmentTrackCandidateBuilderTool.h.

41{this, "MinCandidateSize", 2};

◆ m_overlapThreshold

Gaudi::Property<float> MuonML::SegmentTrackCandidateBuilderTool::m_overlapThreshold
private
Initial value:
{
this, "OverlapThreshold", 0.8f,
"High-purity edge probability threshold used to build core components"}

Definition at line 24 of file SegmentTrackCandidateBuilderTool.h.

24 {
25 this, "OverlapThreshold", 0.8f,
26 "High-purity edge probability threshold used to build core components"};

◆ m_symmetrizeDirectedEdges

Gaudi::Property<bool> MuonML::SegmentTrackCandidateBuilderTool::m_symmetrizeDirectedEdges
private
Initial value:
{
this, "SymmetrizeDirectedEdges", true,
"Use max(score i->j, score j->i) for undirected segment association"}

Definition at line 32 of file SegmentTrackCandidateBuilderTool.h.

32 {
33 this, "SymmetrizeDirectedEdges", true,
34 "Use max(score i->j, score j->i) for undirected segment association"};

◆ m_useRecoveryComponents

Gaudi::Property<bool> MuonML::SegmentTrackCandidateBuilderTool::m_useRecoveryComponents
private
Initial value:
{
this, "UseRecoveryComponents", true,
"Add additional low-threshold connected components to recover true candidates missed by the high-purity core"}

Definition at line 28 of file SegmentTrackCandidateBuilderTool.h.

28 {
29 this, "UseRecoveryComponents", true,
30 "Add additional low-threshold connected components to recover true candidates missed by the high-purity core"};

The documentation for this class was generated from the following files: