12 using namespace MuonStationIndex;
15 declareInterface<IMuonLayerAmbiguitySolverTool>(
this);
24 return StatusCode::SUCCESS;
28 std::vector<MuonCandidate>& resolvedCandidates)
const {
30 std::vector<std::vector<MuonLayerIntersection> > muonLayerDataHashVec;
34 unsigned int nseeds = 0;
35 std::set<const MuonSegment*> usedSegments;
41 if (!
getNextSeed(muonLayerDataHashVec, usedSegments, inverseSeedLayerOrder, layerIntersection)) {
47 std::vector<MuonLayerIntersection> layerIntersections = {layerIntersection};
54 msg(
MSG::VERBOSE) <<
" Candidate with layers " << candidate.layerIntersections.size();
55 for (
const auto&
entry : candidate.layerIntersections) {
64 for (
const auto&
layer : candidate.layerIntersections) { usedSegments.insert(
layer.segment.get()); }
66 resolvedCandidates.insert(resolvedCandidates.end(), std::make_move_iterator(
candidates.begin()),
72 ATH_MSG_DEBUG(
"Completed ambiguity solving using " << nseeds <<
" seeds, resulting in " << resolvedCandidates.size()
73 <<
" track candidates ");
77 const EventContext& ctx, std::vector<MuonCandidate>&
candidates,
78 const std::vector<std::vector<MuonLayerIntersection> >& muonLayerDataHashVec,
79 const std::vector<MuonStationIndex::StIndex>& inverseSeedLayerOrder)
const {
81 if (inverseSeedLayerOrder.empty())
return true;
87 const std::vector<MuonLayerIntersection>& layerIntersections = muonLayerDataHashVec[
toInt(currentStIndex)];
88 if (!layerIntersections.empty()) {
90 std::vector<MuonCandidate> newCandidates;
95 unsigned int selectedSegmentsInLayer = 0;
100 if (
match(ctx, candidate, layerIntersection)) {
102 if (selectedSegmentsInLayer == 0) {
103 candidate.layerIntersections.push_back(layerIntersection);
108 newCandidates.emplace_back(std::move(newCandidate));
110 ++selectedSegmentsInLayer;
115 if (!newCandidates.empty()) {
116 ATH_MSG_VERBOSE(
"Found multiple solutions, add new candidates " << newCandidates.size());
118 std::make_move_iterator(newCandidates.end()));
123 std::vector<MuonStationIndex::StIndex> newInverseSeedLayerOrder = inverseSeedLayerOrder;
124 newInverseSeedLayerOrder.pop_back();
138 std::set<const MuonSegment*>& usedSegments,
139 std::vector<MuonStationIndex::StIndex>& inverseSeedLayerOrder,
141 ATH_MSG_VERBOSE(
"getNextSeed, remaining layers " << inverseSeedLayerOrder.size());
143 std::vector<MuonStationIndex::StIndex>::const_reverse_iterator rit = inverseSeedLayerOrder.rbegin();
144 std::vector<MuonStationIndex::StIndex>::const_reverse_iterator rit_end = inverseSeedLayerOrder.rend();
145 for (; rit != rit_end; ++rit) {
152 if (usedSegments.count(
segment))
continue;
156 layerIntersection = muonLayerIntersection;
161 inverseSeedLayerOrder.pop_back();
167 std::vector<std::vector<MuonLayerIntersection> >& muonLayerDataHashVec)
const {
169 muonLayerDataHashVec.clear();
170 muonLayerDataHashVec.resize(
toInt(StIndex::StIndexMax));
178 std::vector<MuonLayerIntersection> layerIntersections;
179 layerIntersections.reserve(
layer.segments.size());
180 for (
const std::shared_ptr<const MuonSegment>&
segment :
layer.segments) {
188 if (muonLayerDataHashVec[
toInt(stIndex)].empty()) {
189 muonLayerDataHashVec[
toInt(stIndex)] = std::move(layerIntersections);
196 std::ranges::stable_sort(muonLayerDataHashVec[
toInt(stIndex)],
202 for (
const auto&
vec : muonLayerDataHashVec) {
210 std::vector<MuonLayerIntersection>& existingLayerIntersections,
211 std::vector<MuonLayerIntersection>& newLayerIntersections)
const {
212 ATH_MSG_VERBOSE(
" resolveSmallLargeOverlaps: existing " << existingLayerIntersections.size() <<
" new "
213 << newLayerIntersections.size());
216 std::set<const MuonSegment*> combinedSegments;
217 std::vector<MuonLayerIntersection> combinedIntersections;
231 if (!
m_segmentMatchingTool->match(ctx, *layerIntersection1.segment, *layerIntersection2.segment))
continue;
235 std::shared_ptr<const MuonSegment> newseg{
236 m_muonTrackBuilder->combineToSegment(ctx, *layerIntersection1.segment, *layerIntersection2.segment, emptyVec)};
255 if (qualitynew < layerIntersection1.quality || qualitynew < layerIntersection2.quality) {
256 ATH_MSG_DEBUG(
"Quality got worse after combination: new " << qualitynew <<
" q1 " << layerIntersection1.quality
257 <<
" q2 " << layerIntersection2.quality);
269 double dist1 =
getDistance(layerIntersection1, direction);
270 double dist2 =
getDistance(layerIntersection2, direction);
272 combinedIntersections.emplace_back(layerIntersection1.intersection, newseg, qualitynew);
274 combinedIntersections.emplace_back(layerIntersection2.intersection, newseg, qualitynew);
277 <<
" first " <<
m_printer->print(*layerIntersection1.segment) << std::endl
278 <<
" second " <<
m_printer->print(*layerIntersection2.segment) << std::endl
279 <<
" combined " <<
m_printer->print(*newseg));
282 combinedSegments.insert(layerIntersection1.segment.get());
283 combinedSegments.insert(layerIntersection2.segment.get());
289 return !combinedSegments.count(inter_sect.segment.get());
292 combinedIntersections.reserve(existingLayerIntersections.size() + newLayerIntersections.size());
293 std::copy_if(std::make_move_iterator(existingLayerIntersections.begin()), std::make_move_iterator(existingLayerIntersections.end()),
294 std::back_inserter(combinedIntersections), insert_intersection);
295 std::copy_if(std::make_move_iterator(newLayerIntersections.begin()), std::make_move_iterator(newLayerIntersections.end()),
296 std::back_inserter(combinedIntersections), insert_intersection);
297 existingLayerIntersections = std::move(combinedIntersections);