ATLAS Offline Software
Loading...
Searching...
No Matches
MapperSTG.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <iostream>
8//=====================================================================
9uint16_t Muon::nsw::MapperSTG::channel_number (uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t vmm, uint16_t vmm_chan) const
10{
11 // Returns the detector-channel index according to ATHENA conventions.
12
13 int counter {1};
14 int chan = vmm * Muon::nsw::VMM_channels + vmm_chan;
15 const auto& ranges = Muon::nsw::s_stgc_channel_map.at( private_id(channel_type, sector_type, feb_radius, layer) );
16
17 for (const auto& range : ranges) {
18 int chanFirst = range[0]*Muon::nsw::VMM_channels + range[1];
19 int chanLast = range[2]*Muon::nsw::VMM_channels + range[3];
20 int increment = chanLast >= chanFirst ? 1 : -1;
21
22 if ( (chan - chanFirst)*(chan - chanLast) <= 0 ) {
23 uint16_t offline_channel = counter + increment*(chan - chanFirst);
24 return AB_to_Athena_channel_number(channel_type, sector_type, feb_radius, layer, offline_channel);
25 }
26
27 counter += increment*(chanLast - chanFirst) + 1;
28 }
29
30 return 0; // disconnected vmm channel
31}
32
33
34//=====================================================================
35uint16_t Muon::nsw::MapperSTG::nchannels(uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer) const
36{
37 uint16_t pid = private_id(channel_type, sector_type, feb_radius, layer);
38 const auto& ranges = s_stgc_channel_map.at(pid);
39
40 int counter{0};
41 for (const auto& range : ranges) {
42 int chanFirst = range[0]*Muon::nsw::VMM_channels + range[1]; // custom id for the first channel in the range
43 int chanLast = range[2]*Muon::nsw::VMM_channels + range[3]; // custom id for the last channel in the range
44 int increment = chanLast >= chanFirst ? 1 : -1;
45 counter += increment*(chanLast - chanFirst) + 1; // number of channels in the range
46 }
47
48 return counter;
49}
50
51
52//=====================================================================
53bool Muon::nsw::MapperSTG::vmm_info (uint8_t channel_type, uint8_t sector_type, uint8_t mod_radius, uint8_t layer, uint16_t channel_number, uint16_t& vmm, uint16_t& vmm_chan) const
54{
55 // Return vmm and vmm channel given the ATHENA channel index.
56
57 uint16_t AB_channel = Athena_to_AB_channel_number(channel_type, sector_type, mod_radius, layer, channel_number);
58
59 uint16_t pid = private_id(channel_type, sector_type, mod_radius, layer);
60 const auto& ranges = s_stgc_channel_map.at(pid);
61
62 int counter{1};
63 for (const auto& range : ranges) {
64 int chanFirst = range[0]*Muon::nsw::VMM_channels + range[1]; // custom id for the first channel in the range
65 int chanLast = range[2]*Muon::nsw::VMM_channels + range[3]; // custom id for the last channel in the range
66 int increment = chanLast >= chanFirst ? 1 : -1;
67 int nchan = increment*(chanLast - chanFirst) + 1; // number of channels in the range
68
69 if (AB_channel < counter + nchan) {
70 int chan = chanFirst + increment*(AB_channel - counter);
71 vmm = chan/64;
72 vmm_chan = chan%64;
73 return true;
74 }
75
76 counter += nchan;
77 }
78
79 return false;
80}
81
82//=====================================================================
83bool Muon::nsw::MapperSTG::elink_info (uint8_t channel_type, uint8_t sector_type, uint8_t mod_radius, uint8_t layer, uint16_t channel_number, uint &elink) const
84{
85 if(mod_radius>0) {elink = 0; return true;} // The boards on Q2 and Q3 are only read out by one elink per board
86 uint16_t vmm{0}, vmm_chan{0};
87 if(!vmm_info (channel_type, sector_type, mod_radius, layer, channel_number, vmm, vmm_chan)) return false;
89 if(geoVmmToRocVmm(vmm) < 4){
90 elink=0;
91 return true;
92 } else{
93 elink=2;
94 return true;
95 }
97 if(geoVmmToRocVmm(vmm)==2){
98 elink=0;
99 return true;
100 } else{
101 elink=2;
102 return true;
103 }
104 }
105 elink = 0;
106 return false;
107}
108
109
110//=====================================================================
111
112 uint16_t Muon::nsw::MapperSTG::geoVmmToRocVmm(uint16_t VMM) const {
113 constexpr uint16_t vmmRemap[8] = { 2, 3, 0, 1, 5, 4, 6, 7 };
114 return vmmRemap[VMM];
115 }
116
117
118//=====================================================================
119uint16_t Muon::nsw::MapperSTG::AB_to_Athena_channel_number (uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t channel_number) const
120{
121 // Convert an Adapter-Board channel number into ATHENA channel index.
122
123 if (channel_number == 0) return channel_number; // invalid (e.g. case of disconnected channel)
124
126
127 // AB: wire#1 is on the gas-inlet side; right (left) hand side for pivot (confirm) wedges when looking from the IP.
128 // Athena: wire#1 is on the left-hand side both for pivot and confirm wedges.
129 bool isPivot = (sector_type == 0)^(layer < 4);
130 if (isPivot) channel_number = nchannels(channel_type, sector_type, feb_radius, layer) - channel_number + 1;
131
133
134 // AB: pad#1 is on left (right) hand side for even (odd) layers when looking from the IP (counting layers from 0).
135 // Athena: pad#1 is on the right-hand side.
136 uint16_t pid = private_id(channel_type, sector_type, feb_radius, layer);
137 std::pair<uint16_t, uint16_t> pad_grid = s_stgc_pad_grid.at(pid);
138
139 uint16_t padRow_AB = (channel_number - 1)/pad_grid.second + 1;
140 uint16_t padCol_AB = (channel_number - 1)%pad_grid.second + 1;
141 uint16_t padRow_ATH = pad_grid.first - padRow_AB + 1;
142 uint16_t padCol_ATH = (layer%2==0) ? pad_grid.second - padCol_AB + 1 : padCol_AB; // layer is in [0,7]
143
144 // Athena pad numbering assumes 18 eta rows (even if a quadruplet has less)
145 channel_number = (padCol_ATH - 1)*18 + padRow_ATH;
146 }
147
148 return channel_number;
149}
150
151
152//=====================================================================
153uint16_t Muon::nsw::MapperSTG::Athena_to_AB_channel_number (uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t channel_number) const
154{
155 // Convert a channel index according to ATHENA numbering convention
156 // into the Adapter-Board channel number.
157
158 if (channel_number == 0) return channel_number; // invalid (e.g. case of disconnected channel)
159
161
162 // AB: wire#1 is on the gas-inlet side; right (left) hand side for pivot (confirm) wedges when looking from the IP.
163 // Athena: wire#1 is on the left-hand side both for pivot and confirm wedges.
164 bool isPivot = (sector_type == 0)^(layer < 4);
165 if (isPivot) channel_number = nchannels(channel_type, sector_type, feb_radius, layer) - channel_number + 1;
166
168
169 // AB: pad#1 is on left (right) hand side for even (odd) layers when looking from the IP (counting layers from 0).
170 // Athena: pad#1 is on the right-hand side.
171 uint16_t pid = private_id(channel_type, sector_type, feb_radius, layer);
172 std::pair<uint16_t, uint16_t> pad_grid = s_stgc_pad_grid.at(pid);
173
174 // Athena pad numbering assumes 18 eta rows (even if a quadruplet has less)
175 uint16_t padRow_ATH = (channel_number - 1)%18 + 1;
176 uint16_t padCol_ATH = (channel_number - 1)/18 + 1;
177 uint16_t padRow_AB = pad_grid.first - padRow_ATH + 1;
178 uint16_t padCol_AB = (layer%2==0) ? pad_grid.second - padCol_ATH + 1 : padCol_ATH; // layer is in [0,7]
179
180 channel_number = (padRow_AB - 1)*pad_grid.second + padCol_AB;
181 }
182
183 return channel_number;
184}
185
186
187//=====================================================================
188uint16_t Muon::nsw::MapperSTG::NSWID_to_Athena_channel_number (uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t channel_number, bool sideA) const
189{
190 // Convert a channel index according to the NSWID numbering convention
191 // into ATHENA channel index.
192
193 if (channel_number == 0) return channel_number; // invalid (e.g. case of disconnected channel)
194
195 // In NSWID numbering wires and pads follow ATLAS phi.
197
198 // NSWID: wire#1 is on the left (right) hand side for A-side (C-side) when looking from the IP.
199 // Athena: wire#1 is on the left-hand side both for A- and C-side.
200 if (!sideA) channel_number = nchannels(channel_type, sector_type, feb_radius, layer) - channel_number + 1;
201
203
204 // NSWID: pad#1 is on the left (right) hand side for A-side (C-side) when looking from the IP.
205 // Athena: pad#1 is on the right-hand side both for A- and C-side.
206 uint16_t pid = private_id(channel_type, sector_type, feb_radius, layer);
207 std::pair<uint16_t, uint16_t> pad_grid = s_stgc_pad_grid.at(pid);
208
209 uint16_t padRow = (channel_number - 1)/pad_grid.second + 1;
210 uint16_t padCol_NSW = (channel_number - 1)%pad_grid.second + 1;
211 uint16_t padCol_ATH = (sideA) ? pad_grid.second - padCol_NSW + 1 : padCol_NSW;
212
213 // Athena pad numbering assumes 18 eta rows (even if a quadruplet has less)
214 channel_number = (padCol_ATH - 1)*18 + padRow;
215 }
216
217 return channel_number;
218}
219
220
221//=====================================================================
222uint16_t Muon::nsw::MapperSTG::Athena_to_NSWID_channel_number (uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t channel_number, bool sideA) const
223{
224 // Convert a channel index according to ATHENA numbering convention
225 // into NSWID channel index.
226
227 if (channel_number == 0) return channel_number; // invalid (e.g. case of disconnected channel)
228
229 // In NSWID numbering wires and pads follow ATLAS phi.
231
232 // NSWID: wire#1 is on the left (right) hand side for A-side (C-side) when looking from the IP.
233 // Athena: wire#1 is on the left-hand side both for A- and C-side.
234 if (!sideA) channel_number = nchannels(channel_type, sector_type, feb_radius, layer) - channel_number + 1;
235
237
238 // NSWID: pad#1 is on the left (right) hand side for A-side (C-side) when looking from the IP.
239 // Athena: pad#1 is on the right-hand side both for A- and C-side.
240 uint16_t pid = private_id(channel_type, sector_type, feb_radius, layer);
241 std::pair<uint16_t, uint16_t> pad_grid = s_stgc_pad_grid.at(pid);
242
243 // Athena pad numbering assumes 18 eta rows (even if a quadruplet has less)
244 uint16_t padRow = (channel_number - 1)%18 + 1;
245 uint16_t padCol_ATH = (channel_number - 1)/18 + 1;
246 uint16_t padCol_NSW = (sideA) ? pad_grid.second - padCol_ATH + 1 : padCol_ATH;
247 channel_number = (padRow - 1)*pad_grid.second + padCol_NSW;
248 }
249
250 return channel_number;
251}
252
253
254
255
unsigned int uint
uint16_t nchannels(uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer) const
Definition MapperSTG.cxx:35
static uint16_t private_id(uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer)
Definition MapperSTG.h:263
uint16_t Athena_to_AB_channel_number(uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t channel_number) const
uint16_t channel_number(uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t vmm, uint16_t vmm_chan) const
Definition MapperSTG.cxx:9
bool vmm_info(uint8_t channel_type, uint8_t sector_type, uint8_t mod_radius, uint8_t layer, uint16_t channel_number, uint16_t &vmm, uint16_t &vmm_chan) const
Definition MapperSTG.cxx:53
bool elink_info(uint8_t channel_type, uint8_t sector_type, uint8_t mod_radius, uint8_t layer, uint16_t channel_number, uint &elink) const
Definition MapperSTG.cxx:83
uint16_t geoVmmToRocVmm(uint16_t geoVMM) const
uint16_t Athena_to_NSWID_channel_number(uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t channel_number, bool sideA) const
uint16_t NSWID_to_Athena_channel_number(uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t channel_number, bool sideA) const
uint16_t AB_to_Athena_channel_number(uint8_t channel_type, uint8_t sector_type, uint8_t feb_radius, uint8_t layer, uint16_t channel_number) const
static const std::map< uint16_t, std::pair< uint16_t, uint16_t > > s_stgc_pad_grid
Definition MapperSTG.h:197
static const std::map< uint16_t, std::vector< std::vector< uint8_t > > > s_stgc_channel_map
Definition MapperSTG.h:38
@ OFFLINE_CHANNEL_TYPE_STRIP
@ OFFLINE_CHANNEL_TYPE_PAD
@ OFFLINE_CHANNEL_TYPE_WIRE