20 {
21 SG::AuxElement::ConstAccessor<std::vector<unsigned>>
acc{
m_cfg.candidateDecoration};
22 std::unordered_map<unsigned, std::vector<const xAOD::MuonSegment*>> groups;
23 groups.reserve(segments.
size());
24
25 bool sawDecor = false;
27 if (!seg || !
acc.isAvailable(*seg))
continue;
28 sawDecor = true;
29 for (
const unsigned id :
acc(*seg)) groups[
id].push_back(seg);
30 }
31
32 if (!sawDecor) {
33 ATH_MSG_DEBUG(
"MlMsTrackSeeder: no ML decoration found on any segment."
34 << (
m_cfg.fallbackToBaselineIfUndecorated ?
" Falling back to baseline seeder." :
" Returning empty seed set."));
35 if (
m_cfg.fallbackToBaselineIfUndecorated)
return m_baselineSeeder.findTrackSeeds(ctx, gctx, segments);
36 return std::make_unique<MsTrackSeedContainer>();
37 }
38
39 ATH_MSG_DEBUG(
"MlMsTrackSeeder: " << groups.size() <<
" ML candidate group(s) from "
40 << segments.size() << " segment(s)");
41
42 auto out = std::make_unique<MsTrackSeedContainer>();
43
44 std::vector<unsigned> orderedIds;
45 orderedIds.reserve(groups.size());
46 for (const auto& [id, _] : groups) orderedIds.push_back(id);
47 std::sort(orderedIds.begin(), orderedIds.end());
48
49 struct CandidateResult {
50 unsigned id{0};
51 std::size_t nSegments{0};
52 std::unique_ptr<MsTrackSeedContainer> seeds{};
53 };
54
55 std::vector<CandidateResult>
results(orderedIds.size());
56
57 auto runOneCandidate = [&](std::size_t
idx) {
58 const unsigned id = orderedIds[
idx];
59 auto& segs = groups[
id];
61 segs.erase(
std::unique(segs.begin(), segs.end()), segs.end());
64
65 if (segs.size() <
m_cfg.minSegmentsPerCandidate) {
66 return;
67 }
68
72 }
74 };
75
76 if (
m_cfg.runCandidatesInParallel && orderedIds.size() > 1) {
77 tbb::parallel_for(tbb::blocked_range<std::size_t>(0, orderedIds.size()),
78 [&](const tbb::blocked_range<std::size_t>& range) {
79 for (std::size_t idx = range.begin(); idx != range.end(); ++idx) {
80 runOneCandidate(idx);
81 }
82 });
83 } else {
84 for (std::size_t idx = 0;
idx < orderedIds.size(); ++
idx) {
85 runOneCandidate(idx);
86 }
87 }
88
89 for (CandidateResult& result :
results) {
90 const std::size_t nSeeds =
result.seeds ?
result.seeds->size() : 0;
92 <<
result.nSegments <<
" segment(s) -> "
93 << nSeeds << " seed(s)");
94 if (!
result.seeds)
continue;
95 for (MsTrackSeed& seed : *
result.seeds) {
96 out->push_back(std::move(seed));
97 }
98 }
99
100
101
102
103 std::set<std::vector<const xAOD::MuonSegment*>> seen;
105 for (MsTrackSeed& seed : *out) {
106 std::vector<const xAOD::MuonSegment*>
key =
seed.segments();
108 if (!seen.insert(key).second) continue;
109 uniqueSeeds.push_back(std::move(seed));
110 }
111 *
out = std::move(uniqueSeeds);
112
114 << (
out->empty() &&
m_cfg.fallbackToBaselineIfNoCandidates ?
" — falling back to baseline seeder" :
""));
115 if (
out->empty() &&
m_cfg.fallbackToBaselineIfNoCandidates)
return m_baselineSeeder.findTrackSeeds(ctx, gctx, segments);
117}
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
size_type size() const noexcept
Returns the number of elements in the collection.
std::vector< MsTrackSeed > MsTrackSeedContainer
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
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.
MuonSegment_v1 MuonSegment
Reference the current persistent version: