19 {
20 SG::AuxElement::ConstAccessor<std::vector<unsigned>>
acc{
m_cfg.candidateDecoration};
21 std::unordered_map<unsigned, std::vector<const xAOD::MuonSegment*>> groups;
22 groups.reserve(segments.
size());
23
24 bool sawDecor = false;
26 if (!seg || !
acc.isAvailable(*seg))
continue;
27 sawDecor = true;
28 for (
const unsigned id :
acc(*seg)) groups[
id].push_back(seg);
29 }
30
31 if (!sawDecor) {
32 ATH_MSG_DEBUG(
"MlMsTrackSeeder: no ML decoration found on any segment."
33 << (
m_cfg.fallbackToBaselineIfUndecorated ?
" Falling back to baseline seeder." :
" Returning empty seed set."));
35 return std::make_unique<MsTrackSeedContainer>();
36 }
37
38 ATH_MSG_DEBUG(
"MlMsTrackSeeder: " << groups.size() <<
" ML candidate group(s) from "
39 << segments.size() << " segment(s)");
40
41 auto out = std::make_unique<MsTrackSeedContainer>();
42
43 std::vector<unsigned> orderedIds;
44 orderedIds.reserve(groups.size());
45 for (const auto& [id, _] : groups) orderedIds.push_back(id);
46 std::sort(orderedIds.begin(), orderedIds.end());
47
48 struct CandidateResult {
49 unsigned id{0};
50 std::size_t nSegments{0};
51 std::unique_ptr<MsTrackSeedContainer> seeds{};
52 };
53
54 std::vector<CandidateResult>
results(orderedIds.size());
55
56 auto runOneCandidate = [&](std::size_t
idx) {
57 const unsigned id = orderedIds[
idx];
58 auto& segs = groups[
id];
60 segs.erase(
std::unique(segs.begin(), segs.end()), segs.end());
63
64 if (segs.size() <
m_cfg.minSegmentsPerCandidate) {
65 return;
66 }
67
71 }
73 };
74
75 if (
m_cfg.runCandidatesInParallel && orderedIds.size() > 1) {
76 tbb::parallel_for(tbb::blocked_range<std::size_t>(0, orderedIds.size()),
77 [&](const tbb::blocked_range<std::size_t>& range) {
78 for (std::size_t idx = range.begin(); idx != range.end(); ++idx) {
79 runOneCandidate(idx);
80 }
81 });
82 } else {
83 for (std::size_t idx = 0;
idx < orderedIds.size(); ++
idx) {
84 runOneCandidate(idx);
85 }
86 }
87
88 for (CandidateResult& result :
results) {
89 const std::size_t nSeeds =
result.seeds ?
result.seeds->size() : 0;
91 <<
result.nSegments <<
" segment(s) -> "
92 << nSeeds << " seed(s)");
93 if (!
result.seeds)
continue;
94 for (MsTrackSeed& seed : *
result.seeds) {
95 out->push_back(std::move(seed));
96 }
97 }
98
99
100
101
102 std::set<std::vector<const xAOD::MuonSegment*>> seen;
104 for (MsTrackSeed& seed : *out) {
105 std::vector<const xAOD::MuonSegment*>
key =
seed.segments();
107 if (!seen.insert(key).second) continue;
108 uniqueSeeds.push_back(std::move(seed));
109 }
110 *
out = std::move(uniqueSeeds);
111
113 << (
out->empty() &&
m_cfg.fallbackToBaselineIfNoCandidates ?
" — falling back to baseline seeder" :
""));
116}
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: