Line data Source code
1 : /**
2 : * @file PdspChannelMapService.cpp PDSP Channel Map
3 : * Inherited from Offline. Further details of author below.
4 : *
5 : * This is part of the DUNE DAQ , copyright 2020.
6 : * Licensing/copyright details are in the COPYING file that you should have
7 : * received with this code.
8 : * */
9 : ///////////////////////////////////////////////////////////////////////////////////////////////////
10 : // Class: PdspChannelMapService
11 : // Module type: service
12 : // File: PdspChannelMapService.h
13 : // Author: Jingbo Wang (jiowang@ucdavis.edu), February 2018
14 : //
15 : // Implementation of hardware-offline channel mapping reading from a file.
16 : ///////////////////////////////////////////////////////////////////////////////////////////////////
17 :
18 : #include "logging/Logging.hpp"
19 :
20 : #include "PdspChannelMapService.hpp"
21 :
22 : #include <limits>
23 : #include <sstream>
24 : #include <stdexcept>
25 : #include <string>
26 :
27 : namespace dunedaq {
28 : namespace detchannelmaps {
29 :
30 : // Bad channel value
31 : unsigned int
32 0 : bad()
33 : {
34 0 : unsigned int val = std::numeric_limits<unsigned int>::max();
35 0 : return val;
36 : }
37 :
38 0 : PdspChannelMapService::PdspChannelMapService(std::string rcename, std::string felixname)
39 : {
40 :
41 0 : fBadCrateNumberWarningsIssued = 0;
42 0 : fBadSlotNumberWarningsIssued = 0;
43 0 : fBadFiberNumberWarningsIssued = 0;
44 0 : fSSPBadChannelNumberWarningsIssued = 0;
45 0 : fASICWarningsIssued = 0;
46 0 : fASICChanWarningsIssued = 0;
47 :
48 0 : std::ifstream inFile(rcename, std::ios::in);
49 0 : if (inFile.bad() || inFile.fail() || !inFile.is_open()) {
50 0 : throw std::runtime_error(std::string("Bad file ") + std::string(rcename));
51 : }
52 0 : std::string line;
53 :
54 0 : while (std::getline(inFile, line)) {
55 0 : unsigned int crateNo, slotNo, fiberNo, FEMBChannel, StreamChannel, slotID, fiberID, chipNo, chipChannel, asicNo,
56 : asicChannel, planeType, offlineChannel;
57 0 : std::stringstream linestream(line);
58 0 : linestream >> crateNo >> slotNo >> fiberNo >> FEMBChannel >> StreamChannel >> slotID >> fiberID >> chipNo >>
59 0 : chipChannel >> asicNo >> asicChannel >> planeType >> offlineChannel;
60 :
61 : // fill lookup tables. Throw an exception if any number is out of expected bounds.
62 : // checking for negative values produces compiler warnings as these are unsigned ints
63 :
64 0 : if (offlineChannel >= fNChans) {
65 0 : throw std::logic_error("Ununderstood Offline Channel");
66 : }
67 0 : if (crateNo >= fNCrates) {
68 0 : throw std::logic_error("Ununderstood Crate Number");
69 : }
70 0 : if (slotNo >= fNSlots) {
71 0 : throw std::logic_error("Ununderstood Slot Number");
72 : }
73 0 : if (fiberNo >= fNFibers) {
74 0 : throw std::logic_error("Ununderstood Fiber Number");
75 : }
76 0 : if (StreamChannel >= fNFEMBChans) {
77 0 : throw std::logic_error("Ununderstood FEMB (Stream) Channel Number");
78 : }
79 :
80 0 : farrayCsfcToOffline[crateNo][slotNo][fiberNo][StreamChannel] = offlineChannel;
81 0 : fvAPAMap[offlineChannel] = crateNo;
82 0 : fvWIBMap[offlineChannel] = slotNo;
83 0 : fvFEMBMap[offlineChannel] = fiberNo;
84 0 : fvFEMBChannelMap[offlineChannel] = FEMBChannel;
85 0 : fvStreamChannelMap[offlineChannel] = StreamChannel;
86 0 : fvSlotIdMap[offlineChannel] = slotID;
87 0 : fvFiberIdMap[offlineChannel] = fiberID;
88 0 : fvChipMap[offlineChannel] = chipNo;
89 0 : fvChipChannelMap[offlineChannel] = chipChannel;
90 0 : fvASICMap[offlineChannel] = asicNo;
91 0 : fvASICChannelMap[offlineChannel] = asicChannel;
92 0 : fvPlaneMap[offlineChannel] = planeType;
93 0 : }
94 0 : inFile.close();
95 :
96 0 : std::ifstream FELIXinFile(felixname, std::ios::in);
97 0 : if (FELIXinFile.bad() || FELIXinFile.fail() || !FELIXinFile.is_open()) {
98 0 : throw std::runtime_error(std::string("Bad file ") + std::string(felixname));
99 : }
100 :
101 0 : while (std::getline(FELIXinFile, line)) {
102 0 : unsigned int crateNo, slotNo, fiberNo, FEMBChannel, StreamChannel, slotID, fiberID, chipNo, chipChannel, asicNo,
103 : asicChannel, planeType, offlineChannel;
104 0 : std::stringstream linestream(line);
105 0 : linestream >> crateNo >> slotNo >> fiberNo >> FEMBChannel >> StreamChannel >> slotID >> fiberID >> chipNo >>
106 0 : chipChannel >> asicNo >> asicChannel >> planeType >> offlineChannel;
107 :
108 : // fill lookup tables. Throw an exception if any number is out of expected bounds.
109 : // checking for negative values produces compiler warnings as these are unsigned ints
110 :
111 0 : if (offlineChannel >= fNChans) {
112 0 : throw std::logic_error("Ununderstood Offline Channel");
113 : }
114 0 : if (crateNo >= fNCrates) {
115 0 : throw std::logic_error("Ununderstood Crate Number");
116 : }
117 0 : if (slotNo >= fNSlots) {
118 0 : throw std::logic_error("Ununderstood Slot Number");
119 : }
120 0 : if (fiberNo >= fNFibers) {
121 0 : throw std::logic_error("Ununderstood Fiber Number");
122 : }
123 0 : if (StreamChannel >= fNFEMBChans) {
124 0 : throw std::logic_error("Ununderstood FEMB (Stream) Channel Number");
125 : }
126 :
127 0 : fFELIXarrayCsfcToOffline[crateNo][slotNo][fiberNo][StreamChannel] = offlineChannel;
128 0 : fFELIXvAPAMap[offlineChannel] = crateNo;
129 0 : fFELIXvWIBMap[offlineChannel] = slotNo;
130 0 : fFELIXvFEMBMap[offlineChannel] = fiberNo;
131 0 : fFELIXvFEMBChannelMap[offlineChannel] = FEMBChannel;
132 0 : fFELIXvStreamChannelMap[offlineChannel] = StreamChannel;
133 0 : fFELIXvSlotIdMap[offlineChannel] = slotID;
134 0 : fFELIXvFiberIdMap[offlineChannel] = fiberID;
135 0 : fFELIXvChipMap[offlineChannel] = chipNo;
136 0 : fFELIXvChipChannelMap[offlineChannel] = chipChannel;
137 0 : fFELIXvASICMap[offlineChannel] = asicNo;
138 0 : fFELIXvASICChannelMap[offlineChannel] = asicChannel;
139 0 : fFELIXvPlaneMap[offlineChannel] = planeType;
140 0 : }
141 0 : inFile.close();
142 :
143 : // APA numbering -- hardcoded here.
144 : // Installation numbering:
145 : // APA5 APA6 APA4
146 : // beam -->
147 : // APA3 APA2 APA1
148 : //
149 : // The Offline numbering:
150 : // APA1 APA3 APA5
151 : // beam -->
152 : // APA0 APA2 APA4
153 : //
154 0 : fvInstalledAPA[0] = 3;
155 0 : fvInstalledAPA[1] = 5;
156 0 : fvInstalledAPA[2] = 2;
157 0 : fvInstalledAPA[3] = 6;
158 0 : fvInstalledAPA[4] = 1;
159 0 : fvInstalledAPA[5] = 4;
160 :
161 : // and the inverse map -- shifted by 1 -- the above list must start counting at 1.
162 :
163 0 : for (size_t i = 0; i < 6; ++i) {
164 0 : fvTPCSet_VsInstalledAPA[fvInstalledAPA[i] - 1] = i;
165 : }
166 :
167 0 : } // NOLINT(readability/fn_size)
168 :
169 : // assumes crate goes from 1-6, in "installed crate ordering"
170 : // assumes slot goes from 0-5.
171 : // assumes fiber goes from 1-4.
172 : // These conventions are observed in Run 2973, a cryo commissioning run.
173 :
174 : unsigned int
175 0 : PdspChannelMapService::GetOfflineNumberFromDetectorElements(unsigned int crate,
176 : unsigned int slot,
177 : unsigned int fiber,
178 : unsigned int streamchannel,
179 : FelixOrRCE frswitch)
180 : {
181 :
182 0 : unsigned int offlineChannel = 0;
183 0 : unsigned int lcrate = crate;
184 0 : unsigned int lslot = slot;
185 0 : unsigned int lfiber = fiber;
186 :
187 0 : if (crate > fNCrates || crate == 0) {
188 0 : if (count_bits(fBadCrateNumberWarningsIssued) == 1) {
189 0 : TLOG() << "PdspChannelMapService: Bad Crate Number, expecting a number between 1 and 6. "
190 0 : << "Falling back to 1. Ununderstood crate number=" << crate;
191 : }
192 0 : fBadCrateNumberWarningsIssued++;
193 0 : lcrate = 1;
194 : }
195 :
196 0 : if (slot >= fNSlots) {
197 0 : if (count_bits(fBadSlotNumberWarningsIssued) == 1) {
198 0 : TLOG() << "PdspChannelMapService: Bad slot number, using slot number zero as a fallback. "
199 0 : << "Ununderstood slot number: " << slot;
200 : }
201 0 : fBadSlotNumberWarningsIssued++;
202 0 : lslot = 0;
203 : }
204 :
205 0 : if (fiber > fNFibers || fiber == 0) {
206 0 : if (count_bits(fBadFiberNumberWarningsIssued) == 1) {
207 0 : TLOG() << "PdspChannelMapService: Bad fiber number, falling back to 1. "
208 0 : << "Ununderstood fiber number: " << fiber;
209 : }
210 0 : fBadFiberNumberWarningsIssued++;
211 0 : lfiber = 1;
212 : }
213 :
214 0 : if (streamchannel >= fNFEMBChans) {
215 0 : TLOG() << streamchannel << " >= " << fNFEMBChans;
216 0 : throw std::logic_error("Ununderstood Stream (FEMB) chan");
217 : }
218 :
219 0 : if (frswitch == kRCE) {
220 0 : offlineChannel = farrayCsfcToOffline[fvTPCSet_VsInstalledAPA[lcrate - 1]][lslot][lfiber - 1][streamchannel];
221 : } else {
222 0 : offlineChannel = fFELIXarrayCsfcToOffline[fvTPCSet_VsInstalledAPA[lcrate - 1]][lslot][lfiber - 1][streamchannel];
223 : }
224 :
225 0 : return offlineChannel;
226 : }
227 :
228 : // does not depend on FELIX or RCE -- offline channels should always map to the same APA/crate regardless of RCE or
229 : // FELIX
230 :
231 : unsigned int
232 0 : PdspChannelMapService::APAFromOfflineChannel(unsigned int offlineChannel) const
233 : {
234 0 : check_offline_channel(offlineChannel);
235 0 : return fvAPAMap[offlineChannel];
236 : // return fFELIXvAPAMap[offlineChannel]; // -- FELIX one -- should be the same
237 : }
238 :
239 : unsigned int
240 0 : PdspChannelMapService::InstalledAPAFromOfflineChannel(unsigned int offlineChannel) const
241 : {
242 0 : check_offline_channel(offlineChannel);
243 0 : unsigned int offlineAPA = fvAPAMap[offlineChannel];
244 0 : if (offlineAPA > 5) {
245 0 : throw std::logic_error("Offline APA Number out of range");
246 : }
247 0 : return fvInstalledAPA[fvAPAMap[offlineChannel]];
248 : }
249 :
250 : // does not depend on FELIX or RCE
251 :
252 : unsigned int
253 0 : PdspChannelMapService::WIBFromOfflineChannel(unsigned int offlineChannel) const
254 : {
255 0 : check_offline_channel(offlineChannel);
256 0 : return fvWIBMap[offlineChannel];
257 : // return fFELIXvWIBMap[offlineChannel]; // -- FELIX one -- should be the same
258 : }
259 :
260 : // does not depend on FELIX or RCE
261 :
262 : unsigned int
263 0 : PdspChannelMapService::FEMBFromOfflineChannel(unsigned int offlineChannel) const
264 : {
265 0 : check_offline_channel(offlineChannel);
266 0 : return fvFEMBMap[offlineChannel] + 1;
267 : // return fFELIXvFEMBMap[offlineChannel];
268 : }
269 :
270 : // does not depend on FELIX or RCE
271 :
272 : unsigned int
273 0 : PdspChannelMapService::FEMBChannelFromOfflineChannel(unsigned int offlineChannel) const
274 : {
275 0 : check_offline_channel(offlineChannel);
276 0 : return fvFEMBChannelMap[offlineChannel];
277 : // return fFELIXvFEMBChannelMap[offlineChannel]; // -- FELIX one -- should be the same
278 : }
279 :
280 : // this one does depend on FELIX or RCE
281 :
282 : unsigned int
283 0 : PdspChannelMapService::StreamChannelFromOfflineChannel(unsigned int offlineChannel, FelixOrRCE frswitch) const
284 : {
285 0 : check_offline_channel(offlineChannel);
286 0 : if (frswitch == kRCE) {
287 0 : return fvStreamChannelMap[offlineChannel];
288 : } else {
289 0 : return fFELIXvStreamChannelMap[offlineChannel];
290 : }
291 : }
292 :
293 : // does not depend on FELIX or RCE
294 :
295 : unsigned int
296 0 : PdspChannelMapService::SlotIdFromOfflineChannel(unsigned int offlineChannel) const
297 : {
298 0 : check_offline_channel(offlineChannel);
299 0 : return fvSlotIdMap[offlineChannel];
300 : // return fFELIXvSlotIdMap[offlineChannel]; // -- FELIX one -- should be the same
301 : }
302 :
303 : // may potentially depend on FELIX or RCE, but if fibers are switched between the WIB and the FELIX or RCE,
304 : // we can fix this in the channel map but report with this method the fiber coming out of the WIB, not the
305 : // one going in to the FELIX or RCE
306 :
307 : unsigned int
308 0 : PdspChannelMapService::FiberIdFromOfflineChannel(unsigned int offlineChannel) const
309 : {
310 0 : check_offline_channel(offlineChannel);
311 0 : return fvFiberIdMap[offlineChannel];
312 : }
313 :
314 : // does not depend on FELIX or RCE
315 :
316 : unsigned int
317 0 : PdspChannelMapService::ChipFromOfflineChannel(unsigned int offlineChannel) const
318 : {
319 0 : check_offline_channel(offlineChannel);
320 0 : return fvChipMap[offlineChannel];
321 : }
322 :
323 : unsigned int
324 0 : PdspChannelMapService::AsicFromOfflineChannel(unsigned int offlineChannel) const
325 : {
326 0 : check_offline_channel(offlineChannel);
327 0 : return fvChipMap[offlineChannel];
328 : }
329 :
330 : unsigned int
331 0 : PdspChannelMapService::ChipChannelFromOfflineChannel(unsigned int offlineChannel) const
332 : {
333 0 : check_offline_channel(offlineChannel);
334 0 : return fvChipChannelMap[offlineChannel];
335 : }
336 :
337 : // from David Adams -- use the chip channel instead of the asic channel
338 :
339 : unsigned int
340 0 : PdspChannelMapService::AsicChannelFromOfflineChannel(unsigned int offlineChannel) const
341 : {
342 0 : check_offline_channel(offlineChannel);
343 0 : return fvChipChannelMap[offlineChannel];
344 : }
345 :
346 : // really shouldn't be using this as it doesn't mean asic
347 :
348 : unsigned int
349 0 : PdspChannelMapService::ASICFromOfflineChannel(unsigned int offlineChannel)
350 : {
351 0 : if (count_bits(fASICWarningsIssued) == 1) {
352 0 : TLOG() << "PdspChannelMapService: Deprecated call to ASICFromOfflineChannel. "
353 0 : << "Use AsicLinkFromOfflineChannel";
354 : }
355 0 : fASICWarningsIssued++;
356 0 : check_offline_channel(offlineChannel);
357 0 : return fvASICMap[offlineChannel];
358 : }
359 :
360 : unsigned int
361 0 : PdspChannelMapService::AsicLinkFromOfflineChannel(unsigned int offlineChannel) const
362 : {
363 0 : check_offline_channel(offlineChannel);
364 0 : return fvASICMap[offlineChannel];
365 : }
366 :
367 : unsigned int
368 0 : PdspChannelMapService::ASICChannelFromOfflineChannel(unsigned int offlineChannel)
369 : {
370 0 : if (count_bits(fASICChanWarningsIssued) == 1) {
371 0 : TLOG() << "PdspChannelMapService: Deprecated call to ASICChannelFromOfflineChannel. "
372 0 : << "Not a meaningful number -- channels are grouped by 16's not 8's";
373 : }
374 0 : fASICChanWarningsIssued++;
375 0 : check_offline_channel(offlineChannel);
376 0 : return fvASICChannelMap[offlineChannel];
377 : }
378 :
379 : unsigned int
380 0 : PdspChannelMapService::PlaneFromOfflineChannel(unsigned int offlineChannel) const
381 : {
382 0 : check_offline_channel(offlineChannel);
383 0 : return fvPlaneMap[offlineChannel];
384 : }
385 :
386 : size_t
387 0 : PdspChannelMapService::count_bits(size_t i)
388 : {
389 0 : size_t result = 0;
390 0 : size_t s = sizeof(size_t) * 8;
391 0 : for (size_t j = 0; j < s; ++j) {
392 0 : if (i & 1)
393 0 : ++result;
394 0 : i >>= 1;
395 : }
396 0 : return result;
397 : }
398 :
399 : unsigned int
400 0 : PdspChannelMapService::SSPOfflineChannelFromOnlineChannel(unsigned int onlineChannel)
401 : {
402 0 : unsigned int lchannel = onlineChannel;
403 :
404 0 : if (onlineChannel > fNSSPChans) {
405 0 : if (count_bits(fSSPBadChannelNumberWarningsIssued) == 1) {
406 0 : TLOG() << "PdspChannelMapService: Online Channel Number too high, using zero as a fallback: " << onlineChannel;
407 : }
408 0 : fSSPBadChannelNumberWarningsIssued++;
409 0 : lchannel = 0;
410 : }
411 0 : return farraySSPOnlineToOffline[lchannel];
412 : }
413 :
414 : unsigned int
415 0 : PdspChannelMapService::SSPOnlineChannelFromOfflineChannel(unsigned int offlineChannel) const
416 : {
417 0 : SSP_check_offline_channel(offlineChannel);
418 0 : return farraySSPOfflineToOnline[offlineChannel];
419 : }
420 :
421 : unsigned int
422 0 : PdspChannelMapService::SSPAPAFromOfflineChannel(unsigned int offlineChannel) const
423 : {
424 0 : SSP_check_offline_channel(offlineChannel);
425 0 : return fvSSPAPAMap[offlineChannel];
426 : }
427 :
428 : unsigned int
429 0 : PdspChannelMapService::SSPWithinAPAFromOfflineChannel(unsigned int offlineChannel) const
430 : {
431 0 : SSP_check_offline_channel(offlineChannel);
432 0 : return fvSSPWithinAPAMap[offlineChannel];
433 : }
434 :
435 : unsigned int
436 0 : PdspChannelMapService::SSPGlobalFromOfflineChannel(unsigned int offlineChannel) const
437 : {
438 0 : SSP_check_offline_channel(offlineChannel);
439 0 : return fvSSPGlobalMap[offlineChannel];
440 : }
441 :
442 : unsigned int
443 0 : PdspChannelMapService::SSPChanWithinSSPFromOfflineChannel(unsigned int offlineChannel) const
444 : {
445 0 : SSP_check_offline_channel(offlineChannel);
446 0 : return fvSSPChanWithinSSPMap[offlineChannel];
447 : }
448 :
449 : unsigned int
450 0 : PdspChannelMapService::OpDetNoFromOfflineChannel(unsigned int offlineChannel) const
451 : {
452 0 : SSP_check_offline_channel(offlineChannel);
453 0 : return fvOpDetNoMap[offlineChannel];
454 : }
455 :
456 : } // namespace detchannelmaps
457 : } // namespace dunedaq
|