ATLAS Offline Software
Loading...
Searching...
No Matches
FloatingTrackSelector.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 L1Muon::TgcSLCandidate &candidate) {
21 return {candidate.subdetectorId, candidate.sectorId};
22}
23
24float selectionPt(const L1Muon::TgcSLCandidate &candidate) {
25 return std::isfinite(candidate.pt) && candidate.pt > 0.F ? candidate.pt : 0.F;
26}
27
28void fillOutputCandidate(const L1Muon::TgcSLCandidate &input, std::uint8_t tcId,
29 xAOD::L1TGCCandData &output) {
30 output.initialize(input.subdetectorId, input.sectorId, input.bcTag);
31 output.setL1Eta(input.eta);
32 output.setL1Phi(input.phi);
33 output.setL1Pt(selectionPt(input));
34 output.setL1Threshold(input.threshold);
35 output.setL1CandCharge(input.charge > 0 ? 1U : 0U);
36 output.setCoinType(0U);
37 output.setHasInnerCoincidence(input.hasInnerCoincidence);
38 output.setGoodMagneticField(input.goodMagneticField);
39 output.setDeltaPhi(input.deltaPhi);
40 output.setDeltaTheta(input.deltaTheta);
41 output.setL1NswSegment(input.nswSegment);
42 output.setTcId(tcId);
43}
44
45} // namespace
46
47namespace L1Muon::L1TGC {
48
50 xAOD::L1TGCCandDataContainer &output) const {
51 std::vector<const TgcSLCandidate *> orderedCandidates;
52 orderedCandidates.reserve(candidates.size());
53 for (const TgcSLCandidate &candidate : candidates) {
54 if (candidate.threshold == 0U)
55 continue;
56 orderedCandidates.emplace_back(&candidate);
57 }
58
59 std::stable_sort(orderedCandidates.begin(), orderedCandidates.end(),
60 [](const TgcSLCandidate *left, const TgcSLCandidate *right) {
61 const CandidateGroup leftGroup = candidateGroup(*left);
62 const CandidateGroup rightGroup = candidateGroup(*right);
63 if (leftGroup != rightGroup)
64 return leftGroup < rightGroup;
65
66 if (left->threshold != right->threshold) {
67 return left->threshold > right->threshold;
68 }
69 const float leftPt = selectionPt(*left);
70 const float rightPt = selectionPt(*right);
71 if (leftPt != rightPt)
72 return leftPt > rightPt;
73 return left->selectorPriority > right->selectorPriority;
74 });
75
76 CandidateGroup currentGroup{};
77 bool haveCurrentGroup{false};
78 std::size_t groupCandidate{0U};
79 for (const TgcSLCandidate *candidate : orderedCandidates) {
80 const CandidateGroup group = candidateGroup(*candidate);
81 if (!haveCurrentGroup || group != currentGroup) {
82 currentGroup = group;
83 haveCurrentGroup = true;
84 groupCandidate = 0U;
85 }
86 if (groupCandidate >= s_maxCandidatesPerSector)
87 continue;
88
89 ++groupCandidate;
90 xAOD::L1TGCCandData *outputCandidate =
91 output.push_back(std::make_unique<xAOD::L1TGCCandData>());
92 fillOutputCandidate(*candidate, static_cast<std::uint8_t>(groupCandidate),
93 *outputCandidate);
94 }
95}
96
97} // namespace L1Muon::L1TGC
void select(const TgcSLCandidateContainer &candidates, xAOD::L1TGCCandDataContainer &output) const
Fill the xAOD output with the six highest-threshold candidates per sector for one BC processing chain...
std::vector< TgcSLCandidate > TgcSLCandidateContainer
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.
L1TGCCandData_v1 L1TGCCandData
L1TGCCandDataContainer_v1 L1TGCCandDataContainer
Event-local candidate used by the TGC simulation tools.
std::uint16_t sectorId
Trigger Sector identifier.
std::uint16_t subdetectorId
Subdetector identifier.
float pt
TGC pT estimate after Inner Coincidence, in GeV.
std::uint8_t selectorPriority
Track-Selector priority.