ATLAS Offline Software
Loading...
Searching...
No Matches
TgcL0TrackSelector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <algorithm>
8#include <cmath>
9#include <cstdint>
10#include <memory>
11#include <utility>
12#include <vector>
13
15
16namespace {
17
18using CandidateGroup = std::pair<std::uint16_t, std::uint16_t>;
19
20CandidateGroup candidateGroup(const L0Muon::TgcL0Candidate &candidate) {
21 return {candidate.subdetectorId, candidate.sectorId};
22}
23
24float selectionPt(const L0Muon::TgcL0Candidate &candidate) {
25 return std::isfinite(candidate.pt) && candidate.pt > 0.F ? candidate.pt : 0.F;
26}
27
28void fillOutputCandidate(const L0Muon::TgcL0Candidate &input, std::uint8_t tcId,
29 xAOD::TGCCandData &output) {
30 output.initialize(input.subdetectorId, input.sectorId, input.bcTag);
31 output.setEta(input.eta);
32 output.setPhi(input.phi);
33 output.setPt(selectionPt(input));
34 output.setThreshold(input.threshold);
35 output.setCandCharge(input.charge > 0 ? 1U : 0U);
36 output.setMdtFlag(0U);
38 output.setCoinType(0U);
39 output.setHasInnerCoincidence(input.hasInnerCoincidence);
40 output.setGoodMagneticField(input.goodMagneticField);
41 output.setDeltaPhi(input.deltaPhi);
42 output.setDeltaTheta(input.deltaTheta);
43 output.setNswSegment(input.nswSegment);
44 output.setTcId(tcId);
45}
46
47} // namespace
48
49namespace L0Muon {
50namespace TgcL0Floating {
51
53 xAOD::TGCCandDataContainer &output) const {
54 std::vector<const TgcL0Candidate *> orderedCandidates;
55 orderedCandidates.reserve(candidates.size());
56 for (const TgcL0Candidate &candidate : candidates) {
57 if (candidate.threshold == 0U)
58 continue;
59 orderedCandidates.emplace_back(&candidate);
60 }
61
62 std::stable_sort(orderedCandidates.begin(), orderedCandidates.end(),
63 [](const TgcL0Candidate *left, const TgcL0Candidate *right) {
64 const CandidateGroup leftGroup = candidateGroup(*left);
65 const CandidateGroup rightGroup = candidateGroup(*right);
66 if (leftGroup != rightGroup)
67 return leftGroup < rightGroup;
68
69 if (left->threshold != right->threshold) {
70 return left->threshold > right->threshold;
71 }
72 const float leftPt = selectionPt(*left);
73 const float rightPt = selectionPt(*right);
74 if (leftPt != rightPt)
75 return leftPt > rightPt;
76 return left->selectorPriority > right->selectorPriority;
77 });
78
79 CandidateGroup currentGroup{};
80 bool haveCurrentGroup{false};
81 std::size_t groupCandidate{0U};
82 for (const TgcL0Candidate *candidate : orderedCandidates) {
83 const CandidateGroup group = candidateGroup(*candidate);
84 if (!haveCurrentGroup || group != currentGroup) {
85 currentGroup = group;
86 haveCurrentGroup = true;
87 groupCandidate = 0U;
88 }
89 if (groupCandidate >= s_maxCandidatesPerSector)
90 continue;
91
92 ++groupCandidate;
93 xAOD::TGCCandData *outputCandidate =
94 output.push_back(std::make_unique<xAOD::TGCCandData>());
95 fillOutputCandidate(*candidate, static_cast<std::uint8_t>(groupCandidate),
96 *outputCandidate);
97 }
98}
99
100} // namespace TgcL0Floating
101} // namespace L0Muon
void select(const TgcL0CandidateContainer &candidates, xAOD::TGCCandDataContainer &output) const
Fill the xAOD output with the six highest-threshold candidates per sector for one BC processing chain...
std::vector< TgcL0Candidate > TgcL0CandidateContainer
Event-local candidate collection.
output
Definition merge.py:16
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
Event-local candidate used by the TGC simulation tools.
float pt
TGC pT estimate after Inner Coincidence, in GeV.
std::uint16_t sectorId
Trigger Sector identifier.
std::uint16_t subdetectorId
Subdetector identifier.
std::uint8_t selectorPriority
Track-Selector priority.