Project
Loading...
Searching...
No Matches
DigitModifier.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
16#include <fmt/format.h>
17#include <functional>
18#include <array>
19#include <vector>
20#include <unordered_map>
21#include <stdexcept>
22#include <limits>
23
24namespace
25{
26using PadRemappingTable = std::unordered_map<int, int>;
27using PadRemappingTableWithLimits = std::pair<PadRemappingTable, std::pair<int, int>>;
28using PadRemappingTablesForDE = std::vector<PadRemappingTableWithLimits>;
29using PadRemappingTables = std::unordered_map<int, PadRemappingTablesForDE>;
30
31// utility function that updates a digit with a given pad remapping table
32bool updateDigitMapping(o2::mch::Digit& digit, const PadRemappingTables& padsRemapping)
33{
34 int deId = digit.getDetID();
35 // check if the current DE is included in the pad remapping table
36 auto padsRemappingForDE = padsRemapping.find(deId);
37 if (padsRemappingForDE == padsRemapping.end()) {
38 return false;
39 }
40
41 // find the remapping table that contains this padId, if existing
42 int padId = digit.getPadID();
43 for (auto& padsRemappingForDS : padsRemappingForDE->second) {
44 if (padId < padsRemappingForDS.second.first || padId > padsRemappingForDS.second.second) {
45 continue;
46 }
47
48 auto padIDRemapped = padsRemappingForDS.first.find(digit.getPadID());
49 if (padIDRemapped == padsRemappingForDS.first.end()) {
50 continue;
51 }
52
53 // update the digit
54 digit.setPadID(padIDRemapped->second);
55 return true;
56 }
57 return false;
58}
59
63void initST1PadsRemappingTable(PadRemappingTables& fullTable)
64{
65 std::array<int, 8> deToRemap{100, 101, 102, 103, 200, 201, 202, 203};
66 std::array<int, 7> dsToRemap{1, 27, 53, 79, 105, 131, 157};
67
68 std::vector<int> newToOld(64);
69 newToOld[0] = 55;
70 newToOld[1] = 1;
71 newToOld[2] = 11;
72 newToOld[3] = 48;
73 newToOld[4] = 4;
74 newToOld[5] = 52;
75 newToOld[6] = 12;
76 newToOld[7] = 61;
77 newToOld[8] = 59;
78 newToOld[9] = 9;
79 newToOld[10] = 10;
80 newToOld[11] = 17;
81 newToOld[12] = 5;
82 newToOld[13] = 36;
83 newToOld[14] = 57;
84 newToOld[15] = 13;
85 newToOld[16] = 21;
86 newToOld[17] = 23;
87 newToOld[18] = 34;
88 newToOld[19] = 58;
89 newToOld[20] = 20;
90 newToOld[21] = 62;
91 newToOld[22] = 43;
92 newToOld[23] = 24;
93 newToOld[24] = 38;
94 newToOld[25] = 49;
95 newToOld[26] = 26;
96 newToOld[27] = 47;
97 newToOld[28] = 50;
98 newToOld[29] = 41;
99 newToOld[30] = 31;
100 newToOld[31] = 53;
101 newToOld[32] = 32;
102 newToOld[33] = 15;
103 newToOld[34] = 33;
104 newToOld[35] = 42;
105 newToOld[36] = 3;
106 newToOld[37] = 18;
107 newToOld[38] = 37;
108 newToOld[39] = 40;
109 newToOld[40] = 30;
110 newToOld[41] = 39;
111 newToOld[42] = 46;
112 newToOld[43] = 22;
113 newToOld[44] = 35;
114 newToOld[45] = 45;
115 newToOld[46] = 0;
116 newToOld[47] = 25;
117 newToOld[48] = 51;
118 newToOld[49] = 27;
119 newToOld[50] = 28;
120 newToOld[51] = 44;
121 newToOld[52] = 6;
122 newToOld[53] = 29;
123 newToOld[54] = 2;
124 newToOld[55] = 56;
125 newToOld[56] = 19;
126 newToOld[57] = 60;
127 newToOld[58] = 54;
128 newToOld[59] = 16;
129 newToOld[60] = 8;
130 newToOld[61] = 14;
131 newToOld[62] = 7;
132 newToOld[63] = 63;
133
134 for (auto deId : deToRemap) {
135
136 // create an empty table, or reset the existing one
137 fullTable[deId] = PadRemappingTablesForDE();
138 // get a reference to the table for the current DE
139 auto& tableForDE = fullTable[deId];
140
142 for (auto dsId : dsToRemap) {
143 // add an empty table for the currend DS board
144 auto& tableForDSWithLimits = tableForDE.emplace_back();
145 auto& tableForDS = tableForDSWithLimits.first;
146
147 int padIdMin = std::numeric_limits<int>::max();
148 int padIdMax = -1;
149 for (int channel = 0; channel < 64; channel++) {
150 // get the pad ID associated to the channel in the new mapping
151 // this IS NOT the pad that originally fired
152 int padId = segment.findPadByFEE(dsId, channel);
153 // get the corresponding channel number in the old mapping
154 // this IS the electronic channel that originally fired
155 int channelInOldMapping = newToOld[channel];
156 // get the pad ID associated to the fired channel in the new mapping
157 int padIdRemapped = segment.findPadByFEE(dsId, channelInOldMapping);
158 // update the pad remapping table
159 tableForDS[padId] = padIdRemapped;
160
161 padIdMin = std::min(padIdMin, padId);
162 padIdMax = std::max(padIdMax, padId);
163 }
164
165 tableForDSWithLimits.second.first = padIdMin;
166 tableForDSWithLimits.second.second = padIdMax;
167 }
168 }
169}
170
171o2::mch::DigitModifier createST1MappingCorrector(int runNumber)
172{
173 static PadRemappingTables padsRemapping;
174
175 constexpr int lastRunToBeFixed = 560402;
176 // ST2 mapping needs to be corrected only for data collected up to the end of 2024 Pb-Pb
177 if (runNumber > lastRunToBeFixed) {
178 // do not modify digits collected after 2024 Pb-Pb
179 return {};
180 }
181
182 if (padsRemapping.empty()) {
183 initST1PadsRemappingTable(padsRemapping);
184 }
185
186 return [](o2::mch::Digit& digit) {
187 updateDigitMapping(digit, padsRemapping);
188 };
189}
190
194void initST2PadsRemappingTable(PadRemappingTables& fullTable)
195{
196 // Remapping of ST2 DS boards near the rounded part
197 std::array<int, 8> deToRemap{300, 301, 302, 303, 400, 401, 402, 403};
198 std::array<int, 5> dsToRemap{99, 100, 101, 102, 103};
199
200 for (auto deId : deToRemap) {
201
202 // create an empty table, or reset the existing one
203 fullTable[deId] = PadRemappingTablesForDE();
204 // get a reference to the table for the current DE
205 auto& tableForDE = fullTable[deId];
206
208 for (auto dsId : dsToRemap) {
209
210 auto& tableForDSWithLimits = tableForDE.emplace_back();
211 auto& tableForDS = tableForDSWithLimits.first;
212
213 // double loop on DS channels
214 // 1. find the minimum pad index of the DS board
215 int padIdMin = -1;
216 int channelForPadIdMin = -1;
217 for (int channel = 0; channel < 64; channel++) {
218 auto padId = segment.findPadByFEE(dsId, int(channel));
219 if (padId < 0) {
220 // this should never occur in this specific case, as all channels of this group of boards
221 // is connected to pads, hence we rise an exception
222 throw std::out_of_range(fmt::format("Unknown padId for DE{} DS{} channel {}", deId, dsId, channel));
223 }
224 if (padIdMin < 0 || padId < padIdMin) {
225 padIdMin = padId;
226 channelForPadIdMin = channel;
227 }
228 }
229
230 int padIdMax = -1;
231 // 2. build the re-mapping table
232 for (int channel = 0; channel < 64; channel++) {
233 auto padId = segment.findPadByFEE(dsId, int(channel));
234 if (padId < padIdMin) {
235 // something is wrong here...
236 continue;
237 }
238
239 // update maximum padId value
240 padIdMax = std::max(padIdMax, padId);
241
242 int padIdInDS = padId - padIdMin;
243 int padColumn = padIdInDS / 16;
244 int padRow = padIdInDS % 16;
245
246 int padIdRemapped = -1;
247
248 switch (padColumn) {
249 case 0:
250 // shift right by 3 columns
251 padIdRemapped = padId + 16 * 3;
252 break;
253 case 1:
254 // shift right by 1 column
255 padIdRemapped = padId + 16;
256 break;
257 case 2:
258 // shift left by 1 column
259 padIdRemapped = padId - 16;
260 break;
261 case 3:
262 // shift left by 3 columns
263 padIdRemapped = padId - 16 * 3;
264 break;
265 }
266
267 // padsRemapping[deId][padId] = padIdRemapped;
268 tableForDS[padId] = padIdRemapped;
269 }
270
271 tableForDSWithLimits.second.first = padIdMin;
272 tableForDSWithLimits.second.second = padIdMax;
273 }
274 }
275}
276
277o2::mch::DigitModifier createST2MappingCorrector(int runNumber)
278{
279 // static std::unordered_map<int, std::unordered_map<int, int>> padsRemapping;
280 static PadRemappingTables padsRemapping;
281
282 constexpr int lastRunToBeFixed = 560402;
283 // ST2 mapping needs to be corrected only for data collected up to the end of 2024 Pb-Pb
284 if (runNumber > lastRunToBeFixed) {
285 // do not modify digits collected after 2024 Pb-Pb
286 return {};
287 }
288
289 if (padsRemapping.empty()) {
290 initST2PadsRemappingTable(padsRemapping);
291 }
292
293 return [](o2::mch::Digit& digit) {
294 updateDigitMapping(digit, padsRemapping);
295 };
296}
297} // namespace
298
299namespace o2::mch
300{
302 bool updateST1,
303 bool updateST2)
304{
305 DigitModifier modifierST1 = updateST1 ? createST1MappingCorrector(runNumber) : DigitModifier{};
306 DigitModifier modifierST2 = updateST2 ? createST2MappingCorrector(runNumber) : DigitModifier{};
307
308 if (modifierST1 || modifierST2) {
309 return [modifierST1, modifierST2](Digit& digit) {
310 // the ST1/ST2 modifiers are mutually exclusive, depending on the DeID associated to the digit
311 auto detID = digit.getDetID();
312 if (modifierST1 && detID >= 100 && detID < 300) {
313 modifierST1(digit);
314 }
315 if (modifierST2 && detID >= 300 && detID < 500) {
316 modifierST2(digit);
317 }
318 };
319 } else {
320 // return an empty function if none of the modifiers is set
321 return {};
322 }
323}
324
325} // namespace o2::mch
MCH digit implementation.
Definition Digit.h:31
int getPadID() const
Definition Digit.h:54
int getDetID() const
Definition Digit.h:52
void setPadID(int padID)
Definition Digit.h:55
A Segmentation lets you find pads of a detection element and then inspect those pads.
GLuint segment
Definition glcorearb.h:4945
O2MCHMAPPINGIMPL3_EXPORT const Segmentation & segmentation(int detElemId)
std::function< void(Digit &)> DigitModifier
DigitModifier createDigitModifier(int runNumber, bool updateST1, bool updateST2)