ATLAS Offline Software
Loading...
Searching...
No Matches
LVL1BS::PpmCompressionV1 Class Reference

PPM Compressed Format Version 1.04 packing and unpacking utilities. More...

#include <PpmCompressionV1.h>

Collaboration diagram for LVL1BS::PpmCompressionV1:

Public Member Functions

 PpmCompressionV1 ()
 ~PpmCompressionV1 ()

Static Public Member Functions

static bool pack (PpmSubBlockV1 &subBlock)
 Pack data.
static bool unpack (PpmSubBlockV1 &subBlock)
 Unpack data.

Static Private Member Functions

static bool unpackV100 (PpmSubBlockV1 &subBlock)
static bool unpackV101 (PpmSubBlockV1 &subBlock)
static bool unpackV104 (PpmSubBlockV1 &subBlock)

Static Private Attributes

static const int s_formatsV0 = 6
static const int s_lowerRange = 12
static const int s_upperRange = 3
static const int s_formats = 7
static const int s_fadcRange = 15
static const int s_peakOnly = 4
static const int s_lutDataBits = 8
static const int s_lutBcidBits = 3
static const int s_fadcDataBits = 10
static const int s_glinkPins = 16
static const int s_statusBits = 5
static const int s_errorBits = 6
static const int s_statusMask = 0x1f

Detailed Description

PPM Compressed Format Version 1.04 packing and unpacking utilities.

Based on:

"ATLAS L1Calo Pre-processor compressed S-Link data formats", Version 1.7, D.P.C.Sankey.

Author
Peter Faulkner

Definition at line 22 of file PpmCompressionV1.h.

Constructor & Destructor Documentation

◆ PpmCompressionV1()

LVL1BS::PpmCompressionV1::PpmCompressionV1 ( )

◆ ~PpmCompressionV1()

LVL1BS::PpmCompressionV1::~PpmCompressionV1 ( )

Member Function Documentation

◆ pack()

bool LVL1BS::PpmCompressionV1::pack ( PpmSubBlockV1 & subBlock)
static

Pack data.

Definition at line 33 of file PpmCompressionV1.cxx.

34{
35 const int dataFormat = subBlock.format();
36 if (dataFormat != L1CaloSubBlock::COMPRESSED &&
37 dataFormat != L1CaloSubBlock::SUPERCOMPRESSED) return false;
38 const int sliceL = subBlock.slicesLut();
39 const int sliceF = subBlock.slicesFadc();
40 if (sliceL != 1 || sliceF != 5) return false;
41 const int trigOffset = subBlock.fadcOffset() - subBlock.lutOffset();
42 const int fadcBaseline = subBlock.fadcBaseline();
43 const int fadcThreshold = subBlock.fadcThreshold();
44 const int channels = subBlock.channelsPerSubBlock();
45 subBlock.setStreamed();
46 std::vector<uint32_t> compStats(s_formats);
47 std::vector<int> fadcDout(sliceF-1);
48 std::vector<int> fadcLens(sliceF-1);
49 for (int chan = 0; chan < channels; ++chan) {
50 std::vector<int> lutData;
51 std::vector<int> lutBcid;
52 std::vector<int> fadcData;
53 std::vector<int> fadcBcid;
54 subBlock.ppmData(chan, lutData, fadcData, lutBcid, fadcBcid);
55 if (dataFormat == L1CaloSubBlock::SUPERCOMPRESSED) {
56 int dataPresent = lutData[0] || lutBcid[0];
57 if ( !dataPresent ) {
58 for (int sl = 0; sl < sliceF; ++sl) {
59 if (fadcData[sl] >= fadcThreshold || fadcBcid[sl]) {
60 dataPresent = 1;
61 break;
62 }
63 }
64 }
65 subBlock.packer(dataPresent, 1);
66 if ( !dataPresent ) continue;
67 }
68 const int lutLen = subBlock.minBits(lutData[0]);
69 int minFadc = 0;
70 int minOffset = 0;
71 bool fadcSame = true;
72 for (int sl = 0; sl < sliceF; ++sl) {
73 if (sl == 0) minFadc = fadcData[sl];
74 if (fadcData[sl] < minFadc) {
75 minFadc = fadcData[sl];
76 minOffset = sl;
77 }
78 if (fadcData[sl] != fadcData[0] || fadcBcid[sl] != 0) fadcSame = false;
79 }
80 if (minOffset) std::swap(fadcData[0], fadcData[minOffset]);
81
82 int format = 0;
83 if (lutData[0] == 0 && lutBcid[0] == 0 && fadcSame) { // format 6
84 const int header = 15;
85 subBlock.packer(header, 4);
86 if (fadcData[0]) {
87 subBlock.packer(1, 1);
88 subBlock.packer(fadcData[0], s_fadcDataBits);
89 } else subBlock.packer(0, 1);
90 format = 6;
91 } else {
92 const bool minFadcInRange = minFadc >= fadcBaseline &&
93 minFadc <= fadcBaseline + s_fadcRange;
94 int anyFadcBcid = 0;
95 int maxFadcLen = 0;
96 int idx = 0;
97 for (int sl = 0; sl < sliceF; ++sl) {
98 if (sl != 0) {
99 fadcDout[idx] = fadcData[sl] - minFadc;
100 fadcLens[idx] = subBlock.minBits(fadcDout[idx]);
101 if (idx == 0 || fadcLens[idx] > maxFadcLen) {
102 maxFadcLen = fadcLens[idx];
103 }
104 ++idx;
105 }
106 if (sl != trigOffset) anyFadcBcid |= fadcBcid[sl];
107 else if (fadcBcid[sl] != (lutBcid[0] & 0x1)) anyFadcBcid |= 1;
108 }
109 if (lutData[0] == 0 && lutBcid[0] == 0 &&
110 !anyFadcBcid && minFadcInRange && maxFadcLen < 4) {
111 // formats 0,1
112 int header = minOffset;
113 if (maxFadcLen == 3) header += 5;
114 subBlock.packer(header, 4);
115 minFadc -= fadcBaseline;
116 subBlock.packer(minFadc, 4);
117 if (maxFadcLen < 2) maxFadcLen = 2;
118 for (int idx = 0; idx < sliceF-1; ++idx) {
119 subBlock.packer(fadcDout[idx], maxFadcLen);
120 }
121 format = maxFadcLen - 2;
122 } else if (lutLen <= 3 && ((lutData[0] == 0 && lutBcid[0] == 0) ||
123 (lutData[0] > 0 && lutBcid[0] == s_peakOnly))
124 && !anyFadcBcid && minFadcInRange && maxFadcLen <= 4) {
125 // format 2
126 const int header = minOffset + 10;
127 subBlock.packer(header, 4);
128 format = 2;
129 subBlock.packer(format - 2, 2);
130 if (lutData[0]) {
131 subBlock.packer(1, 1);
132 subBlock.packer(lutData[0], 3);
133 } else subBlock.packer(0, 1);
134 minFadc -= fadcBaseline;
135 subBlock.packer(minFadc, 4);
136 for (int idx = 0; idx < sliceF-1; ++idx) {
137 subBlock.packer(fadcDout[idx], 4);
138 }
139 } else {
140 // formats 3,4,5
141 const int header = minOffset + 10;
142 subBlock.packer(header, 4);
143 if ( !minFadcInRange) {
144 const int minFadcLen = subBlock.minBits(minFadc);
145 if (minFadcLen > maxFadcLen) maxFadcLen = minFadcLen;
146 }
147 format = 5;
148 if (maxFadcLen <= 8) format = 4;
149 if (maxFadcLen <= 6) format = 3;
150 subBlock.packer(format - 2, 2);
151 if (lutData[0] || lutBcid[0]) subBlock.packer(1, 1);
152 else subBlock.packer(0, 1);
153 subBlock.packer(anyFadcBcid, 1);
154 if (lutData[0] || lutBcid[0]) {
155 subBlock.packer(lutData[0], s_lutDataBits);
156 subBlock.packer(lutBcid[0], s_lutBcidBits);
157 }
158 if (anyFadcBcid) {
159 for (int idx = 0; idx < sliceF; ++idx) {
160 subBlock.packer(fadcBcid[idx], 1);
161 }
162 }
163 if (minFadcInRange) {
164 subBlock.packer(0, 1);
165 minFadc -= fadcBaseline;
166 subBlock.packer(minFadc, 4);
167 } else {
168 subBlock.packer(1, 1);
169 subBlock.packer(minFadc, format * 2);
170 }
171 for (int idx = 0; idx < sliceF-1; ++idx) {
172 if (fadcLens[idx] <= 4) {
173 subBlock.packer(0, 1);
174 subBlock.packer(fadcDout[idx], 4);
175 } else {
176 subBlock.packer(1, 1);
177 subBlock.packer(fadcDout[idx], format * 2);
178 }
179 }
180 }
181 }
182 ++compStats[format];
183 }
184 // Errors
185 std::vector<int> status(s_glinkPins);
186 std::vector<int> error(s_glinkPins);
187 int statusBit = 0;
188 int errorBit = 0;
189 for (int pin = 0; pin < s_glinkPins; ++pin) {
190 const int errorWord = subBlock.ppmPinError(pin);
191 status[pin] = errorWord & s_statusMask;
192 error[pin] = errorWord >> s_statusBits;
193 if (status[pin]) statusBit = 1;
194 if (error[pin]) errorBit = 1;
195 }
196 subBlock.packer(statusBit, 1);
197 subBlock.packer(errorBit, 1);
198 if (statusBit || errorBit) {
199 for (int pin = 0; pin < s_glinkPins; ++pin) {
200 if (status[pin] || error[pin]) subBlock.packer(1, 1);
201 else subBlock.packer(0, 1);
202 }
203 for (int pin = 0; pin < s_glinkPins; ++pin) {
204 if (status[pin] || error[pin]) {
205 if (statusBit) subBlock.packer(status[pin], s_statusBits);
206 if (errorBit) subBlock.packer(error[pin], s_errorBits);
207 }
208 }
209 }
210 subBlock.packerFlush();
211 subBlock.setCompStats(compStats);
212 return true;
213}
static const int s_peakOnly
static const int s_glinkPins
static const int s_lutBcidBits
static const int s_errorBits
static const int s_statusMask
static const int s_lutDataBits
static const int s_fadcRange
static const int s_statusBits
static const int s_fadcDataBits
status
Definition merge.py:16
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)

◆ unpack()

bool LVL1BS::PpmCompressionV1::unpack ( PpmSubBlockV1 & subBlock)
static

Unpack data.

Definition at line 217 of file PpmCompressionV1.cxx.

218{
219 bool rc = false;
220 switch (subBlock.seqno()) {
221 case 0:
222 rc = unpackV100(subBlock);
223 break;
224 case 1:
225 rc = unpackV101(subBlock);
226 break;
227 case 2:
228 case 3:
229 case 4:
230 case 5: // runs 88701-24 only
231 rc = unpackV104(subBlock);
232 break;
233 default:
234 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_COMPRESSION_VERSION);
235 break;
236 }
237 return rc;
238}
static Double_t rc
static bool unpackV100(PpmSubBlockV1 &subBlock)
static bool unpackV101(PpmSubBlockV1 &subBlock)
static bool unpackV104(PpmSubBlockV1 &subBlock)

◆ unpackV100()

bool LVL1BS::PpmCompressionV1::unpackV100 ( PpmSubBlockV1 & subBlock)
staticprivate

Definition at line 242 of file PpmCompressionV1.cxx.

243{
244 if (subBlock.format() != L1CaloSubBlock::COMPRESSED) {
245 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_FORMAT);
246 return false;
247 }
248 const int sliceL = subBlock.slicesLut();
249 const int sliceF = subBlock.slicesFadc();
250 if (sliceL != 1 || sliceF != 5) {
251 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_COMPRESSION_SLICES);
252 return false;
253 }
254 const int trigOffset = subBlock.fadcOffset();
255 const int pedestal = subBlock.pedestal();
256 const int channels = subBlock.channelsPerSubBlock();
257 subBlock.setStreamed();
258 subBlock.unpackerInit();
259 std::vector<uint32_t> compStats(s_formatsV0);
260 std::vector<int> lutData;
261 std::vector<int> lutBcid;
262 std::vector<int> fadcData;
263 std::vector<int> fadcBcid;
264 for (int chan = 0; chan < channels; ++chan) {
265 lutData.clear();
266 lutBcid.clear();
267 fadcData.clear();
268 fadcBcid.clear();
269 int format = 0;
270 const int header = subBlock.unpacker(4);
271 if (header < 10) {
272 // formats 0,1 - LUT zero, FADC around pedestal
273 const int minOffset = header % 5;
274 format = header / 5;
275 // LUT = 0
276 lutData.push_back(0);
277 lutBcid.push_back(0);
278 // FADC
279 const uint32_t minFadc = subBlock.unpacker(4) + pedestal - s_lowerRange;
280 for (int sl = 0; sl < sliceF; ++sl) {
281 if (sl == minOffset) fadcData.push_back(minFadc);
282 else fadcData.push_back(subBlock.unpacker(format + 2) + minFadc);
283 fadcBcid.push_back(0);
284 }
285 } else {
286 // formats 2-5
287 const int minOffset = header - 10;
288 format = subBlock.unpacker(2) + 2;
289 const int anyLut = subBlock.unpacker(1);
290 int lut = 0;
291 int bcid = 0;
292 if (format == 2) {
293 // LUT
294 if (anyLut) {
295 lut = subBlock.unpacker(3);
296 bcid = s_peakOnly; // just peak-finding BCID set
297 }
298 lutData.push_back(lut);
299 lutBcid.push_back(bcid);
300 // FADC as formats 0,1
301 const int minFadc = subBlock.unpacker(4) + pedestal - s_lowerRange;
302 for (int sl = 0; sl < sliceF; ++sl) {
303 if (sl == minOffset) fadcData.push_back(minFadc);
304 else fadcData.push_back(subBlock.unpacker(format + 2) + minFadc);
305 fadcBcid.push_back(0);
306 }
307 } else {
308 // formats 3,4,5 - full LUT word, variable FADC
309 const int anyBcid = subBlock.unpacker(1);
310 // LUT
311 if (anyLut) {
312 lut = subBlock.unpacker(s_lutDataBits);
313 bcid = subBlock.unpacker(s_lutBcidBits);
314 }
315 lutData.push_back(lut);
316 lutBcid.push_back(bcid);
317 // FADC
318 for (int sl = 0; sl < sliceF; ++sl) {
319 int fbcid = 0;
320 if (sl == trigOffset) fbcid = bcid & 0x1; // take from LUT word
321 else if (anyBcid) fbcid = subBlock.unpacker(1);
322 fadcBcid.push_back(fbcid);
323 }
324 int minFadc = 0;
325 if (subBlock.unpacker(1)) minFadc = subBlock.unpacker(format * 2);
326 else minFadc = subBlock.unpacker(4) + pedestal - s_lowerRange;
327 for (int sl = 0; sl < sliceF; ++sl) {
328 int fadc = minFadc;
329 if (sl != minOffset) {
330 if (subBlock.unpacker(1)) fadc += subBlock.unpacker(format * 2);
331 else fadc += subBlock.unpacker(4);
332 }
333 fadcData.push_back(fadc);
334 }
335 }
336 }
337 subBlock.fillPpmData(chan, lutData, fadcData, lutBcid, fadcBcid);
338 ++compStats[format];
339 }
340 subBlock.setCompStats(compStats);
341 const bool rc = subBlock.unpackerSuccess();
342 if (!rc) subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_DATA_TRUNCATED);
343 return rc;
344}
static const int s_formatsV0
static const int s_lowerRange
constexpr auto lut(Generator &&f)
setEventNumber setTimeStamp bcid
setEventNumber uint32_t

◆ unpackV101()

bool LVL1BS::PpmCompressionV1::unpackV101 ( PpmSubBlockV1 & subBlock)
staticprivate

Definition at line 348 of file PpmCompressionV1.cxx.

349{
350 if (subBlock.format() != L1CaloSubBlock::COMPRESSED) {
351 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_FORMAT);
352 return false;
353 }
354 const int sliceL = subBlock.slicesLut();
355 const int sliceF = subBlock.slicesFadc();
356 if (sliceL != 1 || sliceF != 5) {
357 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_COMPRESSION_SLICES);
358 return false;
359 }
360 const int trigOffset = subBlock.fadcOffset();
361 const int pedestal = subBlock.pedestal();
362 const int channels = subBlock.channelsPerSubBlock();
363 subBlock.setStreamed();
364 subBlock.unpackerInit();
365 std::vector<uint32_t> compStats(s_formats);
366 std::vector<int> lutData;
367 std::vector<int> lutBcid;
368 std::vector<int> fadcData;
369 std::vector<int> fadcBcid;
370 for (int chan = 0; chan < channels; ++chan) {
371 lutData.clear();
372 lutBcid.clear();
373 fadcData.clear();
374 fadcBcid.clear();
375 int format = 0;
376 const int header = subBlock.unpacker(4);
377 if (header < 10) {
378 // formats 0,1 - LUT zero, FADC around pedestal
379 const int minOffset = header % 5;
380 format = header / 5;
381 // LUT = 0
382 lutData.push_back(0);
383 lutBcid.push_back(0);
384 // FADC
385 const int minFadc = subBlock.unpacker(4) + pedestal - s_lowerRange;
386 fadcData.push_back(minFadc);
387 fadcBcid.push_back(0);
388 for (int sl = 1; sl < sliceF; ++sl) {
389 fadcData.push_back(subBlock.unpacker(format + 2) + minFadc);
390 fadcBcid.push_back(0);
391 }
392 if (minOffset) std::swap(fadcData[0], fadcData[minOffset]);
393 } else if (header < 15) {
394 // formats 2-5
395 const int minOffset = header - 10;
396 format = subBlock.unpacker(2) + 2;
397 const int anyLut = subBlock.unpacker(1);
398 int lut = 0;
399 int bcid = 0;
400 if (format == 2) {
401 // LUT
402 if (anyLut) {
403 lut = subBlock.unpacker(3);
404 bcid = s_peakOnly; // just peak-finding BCID set
405 }
406 lutData.push_back(lut);
407 lutBcid.push_back(bcid);
408 // FADC as formats 0,1
409 const int minFadc = subBlock.unpacker(4) + pedestal - s_lowerRange;
410 fadcData.push_back(minFadc);
411 fadcBcid.push_back(0);
412 for (int sl = 1; sl < sliceF; ++sl) {
413 fadcData.push_back(subBlock.unpacker(format + 2) + minFadc);
414 fadcBcid.push_back(0);
415 }
416 if (minOffset) std::swap(fadcData[0], fadcData[minOffset]);
417 } else {
418 // formats 3,4,5 - full LUT word, variable FADC
419 const int anyBcid = subBlock.unpacker(1);
420 // LUT
421 if (anyLut) {
422 lut = subBlock.unpacker(s_lutDataBits);
423 bcid = subBlock.unpacker(s_lutBcidBits);
424 }
425 lutData.push_back(lut);
426 lutBcid.push_back(bcid);
427 // FADC
428 for (int sl = 0; sl < sliceF; ++sl) {
429 int fbcid = 0;
430 if (sl == trigOffset) fbcid = bcid & 0x1; // take from LUT word
431 else if (anyBcid) fbcid = subBlock.unpacker(1);
432 fadcBcid.push_back(fbcid);
433 }
434 int minFadc = 0;
435 if (subBlock.unpacker(1)) minFadc = subBlock.unpacker(format * 2);
436 else minFadc = subBlock.unpacker(4) + pedestal - s_lowerRange;
437 fadcData.push_back(minFadc);
438 for (int sl = 1; sl < sliceF; ++sl) {
439 int len = 4;
440 if (subBlock.unpacker(1)) len = format * 2;
441 fadcData.push_back(subBlock.unpacker(len) + minFadc);
442 }
443 if (minOffset) std::swap(fadcData[0], fadcData[minOffset]);
444 }
445 } else {
446 // format 6 - LUT zero, FADC all equal
447 format = 6;
448 // LUT
449 lutData.push_back(0);
450 lutBcid.push_back(0);
451 // FADC
452 int fadc = 0;
453 if (subBlock.unpacker(1)) fadc = subBlock.unpacker(s_fadcDataBits);
454 for (int sl = 0; sl < sliceF; ++sl) {
455 fadcData.push_back(fadc);
456 fadcBcid.push_back(0);
457 }
458 }
459 subBlock.fillPpmData(chan, lutData, fadcData, lutBcid, fadcBcid);
460 ++compStats[format];
461 }
462 // Errors
463 const int statusBit = subBlock.unpacker(1);
464 const int errorBit = subBlock.unpacker(1);
465 if (statusBit || errorBit) {
466 std::vector<int> err(s_glinkPins);
467 for (int pin = 0; pin < s_glinkPins; ++pin) {
468 err[pin] = subBlock.unpacker(1);
469 }
470 for (int pin = 0; pin < s_glinkPins; ++pin) {
471 if (err[pin]) {
472 int status = 0;
473 int error = 0;
474 if (statusBit) status = subBlock.unpacker(s_statusBits-1);
475 if (errorBit) error = subBlock.unpacker(s_errorBits+1);
476 subBlock.fillPpmPinError(pin, (error << (s_statusBits-1)) | status);
477 }
478 }
479 }
480 subBlock.setCompStats(compStats);
481 const bool rc = subBlock.unpackerSuccess();
482 if (!rc) subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_DATA_TRUNCATED);
483 return rc;
484}

◆ unpackV104()

bool LVL1BS::PpmCompressionV1::unpackV104 ( PpmSubBlockV1 & subBlock)
staticprivate

Definition at line 488 of file PpmCompressionV1.cxx.

489{
490 const int dataFormat = subBlock.format();
491 if (dataFormat != L1CaloSubBlock::COMPRESSED &&
492 dataFormat != L1CaloSubBlock::SUPERCOMPRESSED) {
493 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_FORMAT);
494 return false;
495 }
496 const int compressionVersion = subBlock.seqno();
497 if (compressionVersion == 2 && dataFormat != L1CaloSubBlock::COMPRESSED) {
498 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_FORMAT);
499 return false;
500 }
501 if (compressionVersion == 5) {
502 const int run = subBlock.runNumber();
503 if (run < 88701 || run > 88724) {
504 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_COMPRESSION_VERSION);
505 return false;
506 }
507 }
508 const int sliceL = subBlock.slicesLut();
509 const int sliceF = subBlock.slicesFadc();
510 if (sliceL != 1 || sliceF != 5) {
511 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_COMPRESSION_SLICES);
512 return false;
513 }
514 const int trigOffset = subBlock.fadcOffset() - subBlock.lutOffset();
515 const int fadcBaseline = subBlock.fadcBaseline();
516 const int channels = subBlock.channelsPerSubBlock();
517 subBlock.setStreamed();
518 subBlock.unpackerInit();
519 std::vector<uint32_t> compStats(s_formats);
520 std::vector<int> lutData;
521 std::vector<int> lutBcid;
522 std::vector<int> fadcData;
523 std::vector<int> fadcBcid;
524 for (int chan = 0; chan < channels; ++chan) {
525 if (dataFormat == L1CaloSubBlock::SUPERCOMPRESSED) {
526 if ( !subBlock.unpacker(1) ) continue;
527 }
528 lutData.clear();
529 lutBcid.clear();
530 fadcData.clear();
531 fadcBcid.clear();
532 int format = 0;
533 const int header = subBlock.unpacker(4);
534 if (header < 10) {
535 // formats 0,1 - LUT zero, FADC around pedestal
536 const int minOffset = header % 5;
537 format = header / 5;
538 // LUT = 0
539 lutData.push_back(0);
540 lutBcid.push_back(0);
541 // FADC
542 const int minFadc = subBlock.unpacker(4) + fadcBaseline;
543 fadcData.push_back(minFadc);
544 fadcBcid.push_back(0);
545 for (int sl = 1; sl < sliceF; ++sl) {
546 fadcData.push_back(subBlock.unpacker(format + 2) + minFadc);
547 fadcBcid.push_back(0);
548 }
549 if (minOffset) std::swap(fadcData[0], fadcData[minOffset]);
550 } else if (header < 15) {
551 // formats 2-5
552 const int minOffset = header - 10;
553 format = subBlock.unpacker(2) + 2;
554 const int anyLut = subBlock.unpacker(1);
555 int lut = 0;
556 int bcid = 0;
557 if (format == 2) {
558 // LUT
559 if (anyLut) {
560 lut = subBlock.unpacker(3);
561 bcid = s_peakOnly; // just peak-finding BCID set
562 }
563 lutData.push_back(lut);
564 lutBcid.push_back(bcid);
565 // FADC as formats 0,1
566 const int minFadc = subBlock.unpacker(4) + fadcBaseline;
567 fadcData.push_back(minFadc);
568 fadcBcid.push_back(0);
569 for (int sl = 1; sl < sliceF; ++sl) {
570 fadcData.push_back(subBlock.unpacker(format + 2) + minFadc);
571 fadcBcid.push_back(0);
572 }
573 if (minOffset) std::swap(fadcData[0], fadcData[minOffset]);
574 } else {
575 // formats 3,4,5 - full LUT word, variable FADC
576 const int anyBcid = subBlock.unpacker(1);
577 // LUT
578 if (anyLut) {
579 lut = subBlock.unpacker(s_lutDataBits);
580 bcid = subBlock.unpacker(s_lutBcidBits);
581 }
582 lutData.push_back(lut);
583 lutBcid.push_back(bcid);
584 // FADC
585 for (int sl = 0; sl < sliceF; ++sl) {
586 int fbcid = 0;
587 if (anyBcid) fbcid = subBlock.unpacker(1);
588 else if (sl == trigOffset) fbcid = bcid & 0x1; // take from LUT word
589 fadcBcid.push_back(fbcid);
590 }
591 int minFadc = 0;
592 if (subBlock.unpacker(1)) minFadc = subBlock.unpacker(format * 2);
593 else minFadc = subBlock.unpacker(4) + fadcBaseline;
594 fadcData.push_back(minFadc);
595 for (int sl = 1; sl < sliceF; ++sl) {
596 int len = 4;
597 if (subBlock.unpacker(1)) len = format * 2;
598 fadcData.push_back(subBlock.unpacker(len) + minFadc);
599 }
600 if (minOffset) std::swap(fadcData[0], fadcData[minOffset]);
601 }
602 } else {
603 // format 6 - LUT zero, FADC all equal
604 format = 6;
605 // LUT
606 lutData.push_back(0);
607 lutBcid.push_back(0);
608 // FADC
609 int fadc = 0;
610 if (subBlock.unpacker(1)) fadc = subBlock.unpacker(s_fadcDataBits);
611 for (int sl = 0; sl < sliceF; ++sl) {
612 fadcData.push_back(fadc);
613 fadcBcid.push_back(0);
614 }
615 }
616 subBlock.fillPpmData(chan, lutData, fadcData, lutBcid, fadcBcid);
617 ++compStats[format];
618 }
619 // Errors
620 const int statusBit = subBlock.unpacker(1);
621 const int errorBit = subBlock.unpacker(1);
622 const bool mcmAbsentIsError = compressionVersion < 4;
623 const int sBits = (mcmAbsentIsError) ? s_statusBits - 1 : s_statusBits;
624 const int eBits = (mcmAbsentIsError) ? s_errorBits + 1 : s_errorBits;
625 if (statusBit || errorBit) {
626 std::vector<int> err(s_glinkPins);
627 for (int pin = 0; pin < s_glinkPins; ++pin) {
628 err[pin] = subBlock.unpacker(1);
629 }
630 for (int pin = 0; pin < s_glinkPins; ++pin) {
631 if (err[pin]) {
632 int status = 0;
633 int error = 0;
634 if (statusBit) status = subBlock.unpacker(sBits);
635 if (errorBit) error = subBlock.unpacker(eBits);
636 subBlock.fillPpmPinError(pin, (error << sBits) | status);
637 }
638 }
639 // There is a bug in versions < 4 but if I've understood it correctly
640 // it is not possible to detect it reliably in data.
641 }
642 subBlock.setCompStats(compStats);
643 bool rc = subBlock.unpackerSuccess();
644 if (!rc) subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_DATA_TRUNCATED);
645 else {
646 // Check no more non-zero data - indicates corruption
647 while (subBlock.unpackerSuccess()) {
648 if (subBlock.unpacker(31)) {
649 subBlock.setUnpackErrorCode(L1CaloSubBlock::UNPACK_EXCESS_DATA);
650 rc = false;
651 break;
652 }
653 }
654 }
655 return rc;
656}

Member Data Documentation

◆ s_errorBits

const int LVL1BS::PpmCompressionV1::s_errorBits = 6
staticprivate

Definition at line 45 of file PpmCompressionV1.h.

◆ s_fadcDataBits

const int LVL1BS::PpmCompressionV1::s_fadcDataBits = 10
staticprivate

Definition at line 42 of file PpmCompressionV1.h.

◆ s_fadcRange

const int LVL1BS::PpmCompressionV1::s_fadcRange = 15
staticprivate

Definition at line 38 of file PpmCompressionV1.h.

◆ s_formats

const int LVL1BS::PpmCompressionV1::s_formats = 7
staticprivate

Definition at line 37 of file PpmCompressionV1.h.

◆ s_formatsV0

const int LVL1BS::PpmCompressionV1::s_formatsV0 = 6
staticprivate

Definition at line 34 of file PpmCompressionV1.h.

◆ s_glinkPins

const int LVL1BS::PpmCompressionV1::s_glinkPins = 16
staticprivate

Definition at line 43 of file PpmCompressionV1.h.

◆ s_lowerRange

const int LVL1BS::PpmCompressionV1::s_lowerRange = 12
staticprivate

Definition at line 35 of file PpmCompressionV1.h.

◆ s_lutBcidBits

const int LVL1BS::PpmCompressionV1::s_lutBcidBits = 3
staticprivate

Definition at line 41 of file PpmCompressionV1.h.

◆ s_lutDataBits

const int LVL1BS::PpmCompressionV1::s_lutDataBits = 8
staticprivate

Definition at line 40 of file PpmCompressionV1.h.

◆ s_peakOnly

const int LVL1BS::PpmCompressionV1::s_peakOnly = 4
staticprivate

Definition at line 39 of file PpmCompressionV1.h.

◆ s_statusBits

const int LVL1BS::PpmCompressionV1::s_statusBits = 5
staticprivate

Definition at line 44 of file PpmCompressionV1.h.

◆ s_statusMask

const int LVL1BS::PpmCompressionV1::s_statusMask = 0x1f
staticprivate

Definition at line 46 of file PpmCompressionV1.h.

◆ s_upperRange

const int LVL1BS::PpmCompressionV1::s_upperRange = 3
staticprivate

Definition at line 36 of file PpmCompressionV1.h.


The documentation for this class was generated from the following files: