ATLAS Offline Software
Loading...
Searching...
No Matches
MMT_Diamond.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "MMT_Diamond.h"
6
7
8namespace {
9 // The stereo angle is fixed and can be hardcoded
10 const double tan_stereo_angle = std::tan(0.02618);
11
12 constexpr int bc_wind = 4; // fixed time window (in bunch crossings) during which the algorithm collects ART hits
13 constexpr int n_addc = 4;
14 constexpr int n_vmm = 128;
15}
16
17
18MMT_Diamond::MMT_Diamond(const int diamXthreshold, const bool uv, const int diamUVthreshold, const int roadSize,
19 const int olapEtaUp, const int olapEtaDown, const int olapStereoUp, const int olapStereoDown): AthMessaging(Athena::getMessageSvc(), "MMT_Diamond") {
20 m_xthr = diamXthreshold;
21 m_uvthr = diamUVthreshold;
22 m_uvflag = uv;
23 m_roadSize = roadSize;
24 m_roadSizeUpX = olapEtaUp;
25 m_roadSizeDownX = olapEtaDown;
26 m_roadSizeUpUV = olapStereoUp;
27 m_roadSizeDownUV = olapStereoDown;
28}
29
30void MMT_Diamond::createRoads(std::vector<MMT_Road>& roads, const bool isLarge) const {
31 const char sec = (isLarge) ? 'L' : 'S';
32 /*
33 * This computation is done as follows: 1024 X roads
34 * MML: for i in [0,8] -> i*6 UV roads. Then: (1024-9)*6*9 UV roads
35 * MMS: for i in [0,6] -> i*6 UV roads. Then: (1024-7)*6*7 UV roads
36 */
37 const unsigned int vecRoads = (isLarge) ? 56050 : 43864;
38 roads.reserve(vecRoads);
39 int nroad = 8192/this->getRoadSize();
40 for (int i = 0; i < nroad; ++i) {
42
43 /*
44 * The computation of "nuv" is:
45 * B = (1./std::tan(1.5/180.*M_PI));
46 * nuv = std::round( par->getlWidth() / (B * 0.4 * 2.)/this->getRoadSize() );
47 * As getlWidth() has to deal with the full wedge, only two (fixed by construction) integer values are allowed, according to small (7) or large (9) wedge
48 */
49 if(m_uvflag) {
50 const int nuv = (isLarge) ? 9 : 7;
51 for (int uv = 1; uv <= nuv; uv++) {
52 if (i-uv < 0) continue;
53 roads.emplace_back(sec, m_roadSize, m_roadSizeUpX, m_roadSizeDownX, m_roadSizeUpUV, m_roadSizeDownUV, m_xthr, m_uvthr, i, i+uv, i-uv);
54 roads.emplace_back(sec, m_roadSize, m_roadSizeUpX, m_roadSizeDownX, m_roadSizeUpUV, m_roadSizeDownUV, m_xthr, m_uvthr, i, i-uv, i+uv);
55 roads.emplace_back(sec, m_roadSize, m_roadSizeUpX, m_roadSizeDownX, m_roadSizeUpUV, m_roadSizeDownUV, m_xthr, m_uvthr, i, i+uv-1, i-uv);
56 roads.emplace_back(sec, m_roadSize, m_roadSizeUpX, m_roadSizeDownX, m_roadSizeUpUV, m_roadSizeDownUV, m_xthr, m_uvthr, i, i-uv, i+uv-1);
57 roads.emplace_back(sec, m_roadSize, m_roadSizeUpX, m_roadSizeDownX, m_roadSizeUpUV, m_roadSizeDownUV, m_xthr, m_uvthr, i, i-uv+1, i+uv);
58 roads.emplace_back(sec, m_roadSize, m_roadSizeUpX, m_roadSizeDownX, m_roadSizeUpUV, m_roadSizeDownUV, m_xthr, m_uvthr, i, i+uv, i-uv+1);
59 }
60 }
61 }
62}
63
64void MMT_Diamond::findDiamonds(std::vector<std::shared_ptr<MMT_Hit> >& hits, std::vector<MMT_Road>& roads, std::vector<slope_t>& diamondSlopes, const int sectorPhi) const {
65
66 // Comparison with lambda function (easier to implement)
67 std::sort(hits.begin(), hits.end(), [](const auto &h1, const auto &h2){ return h1->getBC() < h2->getBC(); });
68 const int bc_start = hits.front()->getBC();
69 const int bc_end = hits.front()->getBC() + 16;
70 ATH_MSG_DEBUG("Window Start: " << bc_start << " - Window End: " << bc_end);
71
72 std::vector<std::shared_ptr<MMT_Hit> > hits_now;
73 std::vector< std::pair<int, float> > vmm_same;
74 std::vector< std::pair<int, int> > addc_same;
75 std::vector<int> to_erase;
76
77 // each road makes independent triggers, evaluated on each BC
78 unsigned int ibc = 0;
79 for (int bc = hits.front()->getBC(); bc < bc_end; bc++) {
80 // Cleaning stuff
81 hits_now.clear();
82
83 for (unsigned int j = ibc; j < hits.size(); j++) {
84 if (hits[j]->getBC() == bc) hits_now.push_back(hits[j]);
85 else if (hits[j]->getBC() > bc) {
86 ibc = j;
87 break;
88 }
89 }
90
91 // Simulate harware filters: ART hits + ADDC filter
92 for (unsigned int ib = 0; ib < 8; ib++) { //loop on plane from 0 to 7
93 // VMM-ART-hit filter
94 for (int j = 0; j < n_vmm; j++) {
95 vmm_same.clear();
96 unsigned int k = 0;
97 for (const auto &hit_pointer: hits_now) {
98 if (static_cast<unsigned int>(hit_pointer->getPlane()) != ib) continue;
99 if (hit_pointer->getVMM() == j){
100 vmm_same.push_back( std::make_pair(k, hit_pointer->getTime()) );
101 }
102 k++;
103 }
104 if (vmm_same.size() > 1) {
105 to_erase.clear();
106 std::sort(vmm_same.begin(), vmm_same.end(), [](const std::pair<int, float>& p1, const std::pair<int, float>& p2) { return p1.second < p2.second; });
107 for (auto pair: vmm_same) to_erase.push_back(pair.first);
108 // reverse and erase
109 std::sort(to_erase.rbegin(), to_erase.rend());
110 to_erase.pop_back(); //removes the hit with the earliest time
111 for (auto l : to_erase) {
112 hits_now.erase(hits_now.begin() + l);
113 }
114 }
115 }
116 // ADDC-like filter
117 for (int ia = 0; ia < n_addc; ia++) { // From 0 to 3 (local index of the ART ASIC in the layer)
118 addc_same.clear();
119 for (unsigned int k = 0; k < hits_now.size(); k++) {
120 if ((unsigned int)(hits_now[k]->getPlane()) != ib) continue;
121 int istrip = (std::abs(hits_now[k]->getStationEta())-1) * (64*8*10) + hits_now[k]->getChannel(); //needed the global strip index on the sector layer (getChannel returns chamber's local strip index)
122 if (hits_now[k]->getART() == ia) addc_same.emplace_back(k, istrip);
123 }
124
125 if (addc_same.size() > 8) {
126 // priority encode the hits by channel number; remember hits 8+
127 to_erase.clear();
128
129 std::sort(addc_same.begin(), addc_same.end(), [](const std::pair<int, int>& p1, const std::pair<int, int>& p2) { return p1.second < p2.second; });
130 for (unsigned int it = 8; it < addc_same.size(); it++) to_erase.push_back(addc_same[it].first);
131
132 // reverse and erase
133 std::sort(to_erase.rbegin(), to_erase.rend());
134 for (auto l : to_erase) {
135 hits_now.erase(hits_now.begin() + l);
136 }
137 }
138 }
139 } // loop on plane for VMM and ART ASIC filter
140
141 for (auto &road : roads) {
142
143 if (!road.getHitVector().empty()) road.incrementAge(bc_wind);
144 if (!hits_now.empty()) road.addHits(hits_now);
145
146 if (road.checkCoincidences(bc_wind) && bc >= (bc_start - 1)) {
147
148 ATH_MSG_DEBUG("------------------------------------------------------------------");
149 ATH_MSG_DEBUG("Coincidence FOUND @BC: " << bc);
150 ATH_MSG_DEBUG("Road (x, u, v, count): (" << road.iRoadx() << ", " << road.iRoadu() << ", " << road.iRoadv() << ", " << road.countHits() << ")");
151 ATH_MSG_DEBUG("------------------------------------------------------------------");
152
153 std::vector<int> bcidVec;
154 for (const auto &hit: road.getHitVector()) {
155 bcidVec.push_back(hit.getBC());
156 }
157 std::sort(bcidVec.begin(), bcidVec.end());
158
159 // evaluating mode of the BCID of the hits in the diamond
160 // default setting in the firmware is the mode of the hits's bcid in the diamond
161 int bcidVal=bcidVec[0], bcidCount=1, modeCount=1, bcidMode=bcidVec[0];
162 for (unsigned int i=1; i<bcidVec.size(); i++){
163 if (bcidVec[i] == bcidVal){
164 bcidCount++;
165 } else {
166 bcidCount = 1;
167 bcidVal = bcidVec[i];
168 }
169 if (bcidCount > modeCount) {
170 modeCount = bcidCount;
171 bcidMode = bcidVal;
172 }
173 }
174
175 slope_t slope;
176 slope.BC = bcidMode;
177 slope.totalCount = road.countHits();
178 slope.realCount = road.countRealHits();
179 slope.iRoad = road.iRoadx();
180 slope.iRoadu = road.iRoadu();
181 slope.iRoadv = road.iRoadv();
182 slope.uvbkg = road.countUVHits(true); // the bool in the following 4 functions refers to background/noise hits
183 slope.xbkg = road.countXHits(true);
184 slope.uvmuon = road.countUVHits(false);
185 slope.xmuon = road.countXHits(false);
186 slope.age = slope.BC - bc_start;
187 slope.mxl = road.mxl();
188 slope.my = road.avgSofX(); // defined as my in ATL-COM-UPGRADE-2015-033
189 slope.uavg = road.avgSofUV(2,4);
190 slope.vavg = road.avgSofUV(3,5);
191 slope.mx = (slope.uavg-slope.vavg)/(2.*tan_stereo_angle);
192 const double theta = std::atan(std::sqrt(std::pow(slope.mx,2) + std::pow(slope.my,2)));
193 slope.theta = (slope.my > 0.) ? theta : M_PI - theta;
194 slope.eta = -1.*std::log(std::tan(slope.theta/2.));
195 slope.dtheta = (slope.mxl - slope.my)/(1. + slope.mxl*slope.my);
196 slope.side = (slope.my > 0.) ? 'A' : 'C';
197 slope.phi = std::atan(slope.mx/slope.my);
198 slope.phiShf = phiShift(sectorPhi, slope.phi, slope.side);
199 slope.lowRes = road.evaluateLowRes();
200
201 diamondSlopes.push_back(slope);
202 }
203 }
204 }
205}
206
207double MMT_Diamond::phiShift(const int n, const double phi, const char side) const {
208 double Phi = (side == 'A') ? -phi : phi;
209 double shift = (n > 8) ? (16-n)*M_PI/8. : n*M_PI/8.;
210 if (n < 8) return (Phi + shift);
211 else if (n == 8) return (Phi + ((Phi > 0.) ? -1. : 1.)*shift);
212 else return (Phi - shift);
213}
#define M_PI
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_MSG_DEBUG(x)
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
MMT_Diamond(const int diamXthreshold, const bool uv, const int diamUVthreshold, const int roadSize, const int olapEtaUp, const int olapEtaDown, const int olapStereoUp, const int olapStereoDown)
int getRoadSize() const
Definition MMT_Diamond.h:50
double phiShift(const int n, const double phi, const char side) const
int m_roadSizeDownUV
Definition MMT_Diamond.h:56
void createRoads(std::vector< MMT_Road > &roads, const bool isLarge) const
int m_roadSizeUpUV
Definition MMT_Diamond.h:56
int m_roadSizeDownX
Definition MMT_Diamond.h:56
int m_roadSizeUpX
Definition MMT_Diamond.h:56
void findDiamonds(std::vector< std::shared_ptr< MMT_Hit > > &hits, std::vector< MMT_Road > &roads, std::vector< slope_t > &diamondSlopes, const int sectorPhi) const
STL class.
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
double my
Definition MMT_Diamond.h:27
double phi
Definition MMT_Diamond.h:34
double phiShf
Definition MMT_Diamond.h:35
unsigned int uvmuon
Definition MMT_Diamond.h:23
double eta
Definition MMT_Diamond.h:32
int iRoadu
Definition MMT_Diamond.h:19
unsigned int realCount
Definition MMT_Diamond.h:17
double mx
Definition MMT_Diamond.h:30
int iRoadv
Definition MMT_Diamond.h:20
double mxl
Definition MMT_Diamond.h:26
unsigned int totalCount
Definition MMT_Diamond.h:16
double theta
Definition MMT_Diamond.h:31
double vavg
Definition MMT_Diamond.h:29
double dtheta
Definition MMT_Diamond.h:33
char side
Definition MMT_Diamond.h:36
bool lowRes
Definition MMT_Diamond.h:37
unsigned int xbkg
Definition MMT_Diamond.h:22
unsigned int uvbkg
Definition MMT_Diamond.h:21
unsigned int xmuon
Definition MMT_Diamond.h:24
double uavg
Definition MMT_Diamond.h:28
int iRoad
Definition MMT_Diamond.h:18