ATLAS Offline Software
Loading...
Searching...
No Matches
Muon/L1MuonNSW/src/MMT_Road.cxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3 */
4
5#include "MMT_Road.h"
6#include <algorithm>
7#include <stdexcept>
8
9namespace L1Muon::L1MM {
10
11MMT_Road::MMT_Road(const char sector, const int roadSize,
12 const int UpX, const int DownX, const int UpUV, const int DownUV,
13 const int xthr, const int uvthr,
14 const int iroadx, const int iroadu, const int iroadv) :
15 m_iroadx(iroadx),
16 m_iroadu(iroadu != -1 ? iroadu : iroadx),
17 m_iroadv(iroadv != -1 ? iroadv : iroadx),
18 m_xthr(xthr),
19 m_uvthr(uvthr),
20 m_sector(sector)
21{
22 // Pre-calculate slopes
23 m_slopeXlow = roadSize*m_iroadx + 0.5 - DownX;
24 m_slopeXhigh = roadSize*(m_iroadx+1) + 0.5 + UpX;
25
26 m_slopeUlow = roadSize*m_iroadu + 0.5 - DownUV;
27 m_slopeUhigh = roadSize*(m_iroadu+1) + 0.5 + UpUV;
28
29 m_slopeVlow = roadSize*m_iroadv + 0.5 - DownUV;
30 m_slopeVhigh = roadSize*(m_iroadv+1) + 0.5 + UpUV;
31}
32
33void MMT_Road::addHits(const std::vector<const MMT_Hit*>& hits) {
34 for (const MMT_Hit* hit_i : hits) {
35 double low{0.}, high{0.};
36 switch (hit_i->getType()) {
37 case LayerType::X:
38 low = m_slopeXlow;
39 high = m_slopeXhigh;
40 break;
41 case LayerType::U:
42 low = m_slopeUlow;
43 high = m_slopeUhigh;
44 break;
45 case LayerType::V:
46 low = m_slopeVlow;
47 high = m_slopeVhigh;
48 break;
49 default:
50 continue;
51 }
52 const double slow = hit_i->getShift() + low * hit_i->getPitchOverZ();
53 const double shigh = hit_i->getShift() + high * hit_i->getPitchOverZ();
54
55 const double val = hit_i->getRZSlope();
56 bool has_hit = (val > 0.) ? (val > slow && val < shigh) : (val > shigh && val < slow);
57 if (!has_hit) continue;
58
59 const int pl = hit_i->getPlane();
60 if (std::ranges::any_of(m_road_hits, [&pl](const auto &hit) { return (hit.getPlane() == pl); })) continue;
61
62 m_road_hits.emplace_back(*hit_i);
63 m_road_hits.back().setAge(0);
64 }
65}
66
67double MMT_Road::avgSofXUV(const LayerType type) const {
68 double sum = 0;
69 unsigned short int N = 0;
70 for (const auto &hit : m_road_hits) {
71 if (hit.getType() != type) continue;
72 sum += hit.getRZSlope();
73 ++N;
74 }
75 if (N == 0)[[unlikely]]{
76 throw std::runtime_error("MMT_Road::avgSofXUV: N is zero.");
77 }
78 return sum/N;
79}
80
81unsigned int MMT_Road::countUHits() const {
82 return std::ranges::count_if(m_road_hits, [](const auto& hit) { return hit.isU(); });
83}
84
85unsigned int MMT_Road::countXHits() const {
86 return std::ranges::count_if(m_road_hits, [](const auto& hit) { return hit.isX(); });
87}
88
90 unsigned short int nhits1 = 0, nhits2 = 0;
91 for (const auto &hit : m_road_hits) {
92 nhits1 += hit.getPlane() < 4;
93 nhits2 += hit.getPlane() > 3;
94 }
95 return (nhits1 < 4 || nhits2 < 4);
96}
97
99 unsigned short int nx1 = 0, nx2 = 0;
100 for (const auto &hit : m_road_hits) {
101 nx1 += hit.getPlane() < 2;
102 nx2 += hit.getPlane() > 5;
103
104 if (nx1 > 0 && nx2 > 0 && (nx1+nx2) >= m_xthr) return true;
105 }
106 return false;
107}
108
109void MMT_Road::incrementAge(const int bcwind) {
110 unsigned short int old_ihits = 0;
111 for (auto &hit : m_road_hits) {
112 hit.setAge(hit.getAge()+1);
113 if (hit.getAge() > (bcwind-1)) ++old_ihits;
114 }
115 m_road_hits.erase(m_road_hits.begin(), m_road_hits.begin()+old_ihits);
116}
117
118bool MMT_Road::matureCheck(const int bcwind) const {
119 for (const auto &hit : m_road_hits) {
120 if (hit.getAge() == (bcwind - 1)) return true;
121 }
122 return false;
123}
124
125double MMT_Road::mxl() const {
126 std::vector<double> ys, zs;
127 for (const auto &hit : m_road_hits) {
128 if (hit.isX()) {
129 ys.push_back(hit.getR());
130 zs.push_back(hit.getZ());
131 }
132 }
133 double mxl = 0;
134 double avg_z = std::accumulate(zs.begin(), zs.end(), 0.0)/static_cast<double>(zs.size());
135 double sum_sq_z = std::inner_product(zs.begin(), zs.end(), zs.begin(), 0.0);
136 for (unsigned int i = 0; i < ys.size(); i++) {
137 mxl += ys[i]*( (zs[i]-avg_z) / (sum_sq_z - zs.size()*std::pow(avg_z,2)) );
138 }
139
140 return mxl;
141}
142
144 unsigned short int nu = 0, nv = 0;
145 for (const auto &hit : m_road_hits) {
146 nu += hit.isU();
147 nv += hit.isV();
148
149 if (nu > 0 && nv > 0 && (nu+nv) >= m_uvthr) return true;
150 }
151 return false;
152}
153
154} // namespace L1Muon::L1MM
bool hit(const Container &ids, int pdgId)
One MM strip hit as seen by the MM trigger processor.
std::vector< MMT_Hit > m_road_hits
double avgSofXUV(const LayerType type) const
Average R/Z slope of the hits of one layer type.
bool matureCheck(const int bcwind) const
void addHits(const std::vector< const MMT_Hit * > &hits)
Offer the hits of the current bunch crossing to the road (accepted hits are copied).
MMT_Road(const char sector, const int roadSize, const int UpX, const int DownX, const int UpUV, const int DownUV, const int xthr, const int uvthr, const int iroadx, const int iroadu=-1, const int iroadv=-1)
Definitions shared by the classes of the MM trigger processor emulation.
LayerType
Type of an MM layer: X (eta strips), U (stereo +1.5 deg) or V (stereo -1.5 deg).
#define unlikely(x)