File indexing completed on 2024-04-06 12:10:29
0001 #include "EventFilter/CSCTFRawToDigi/src/CSCTFEvent.h"
0002 #include "EventFilter/CSCTFRawToDigi/src/CSCSPHeader.h"
0003 #include <cstring>
0004 #include <stdexcept>
0005
0006 unsigned int CSCTFEvent::unpack(const unsigned short *buf, unsigned int length) {
0007
0008 nRecords = 0;
0009 bzero(sp, sizeof(sp));
0010
0011
0012 if (sizeof(unsigned long long) != 8 || sizeof(unsigned short) != 2)
0013 throw std::runtime_error(std::string("Wrong platform: sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2"));
0014
0015
0016 unsigned long coruptions = 0;
0017
0018
0019 const unsigned long long *dduWord = reinterpret_cast<const unsigned long long *>(buf);
0020 unsigned long long word_1 = 0, word_2 = 0;
0021
0022 length /= sizeof(unsigned long long) / sizeof(unsigned short);
0023
0024 bool spHeader = false, spTrailer = false;
0025 unsigned long spWordCount = 0, spWordCountExpected = 0;
0026
0027
0028 unsigned int index = 0;
0029 while (index < length) {
0030 word_1 = word_2;
0031 word_2 = dduWord[index];
0032
0033 if (spHeader && !spTrailer)
0034 spWordCount++;
0035
0036 if ((word_1 & 0xF000F000F000F000LL) == 0x9000900090009000LL &&
0037 (word_2 & 0xF000F000F000F000LL) == 0xA000A000A000A000LL) {
0038 if (spHeader) {
0039 coruptions |= MISSING_TRAILER;
0040 break;
0041 }
0042 spHeader = true;
0043 spTrailer = false;
0044
0045 spWordCount = 0;
0046 spWordCountExpected = 0;
0047
0048 CSCSPHeader header;
0049 const unsigned short *spWord = reinterpret_cast<const unsigned short *>(&dduWord[index - 1]);
0050
0051 header.unpack(spWord);
0052
0053
0054 if (header.format_version() && !header.empty()) {
0055 if (length > index + 1) {
0056 spWord += 4;
0057 } else {
0058 coruptions |= OUT_OF_BUFFER;
0059 break;
0060 }
0061 }
0062
0063
0064 for (unsigned short tbin = 0, shift = 0; tbin < header.nTBINs() && !header.empty(); tbin++) {
0065
0066 if (length <= index + spWordCountExpected + 2) {
0067 coruptions |= OUT_OF_BUFFER;
0068 break;
0069 } else {
0070
0071 if (header.format_version() >= 3 && header.suppression()) {
0072
0073 if (((spWord[shift + 7] >> 8) & 0x7) != tbin + 1)
0074 continue;
0075
0076 if ((spWord[shift + 0] & 0xF000) == 0xF000 && (spWord[shift + 1] & 0xF000) == 0xF000 &&
0077 (spWord[shift + 2] & 0xF000) == 0xF000 && (spWord[shift + 3] & 0xF000) == 0xF000 &&
0078 (spWord[shift + 4] & 0xF000) == 0xE000 && (spWord[shift + 5] & 0xF000) == 0xE000 &&
0079 (spWord[shift + 6] & 0xF000) == 0xE000 && (spWord[shift + 7] & 0xF000) == 0xE000)
0080 break;
0081 }
0082
0083
0084 spWordCountExpected += 2;
0085
0086 for (unsigned int me_block = 0; me_block < 15; me_block++)
0087 if (header.active() & (1 << (me_block / 3)) &&
0088 (!header.suppression() || spWord[shift + 0] & (1 << me_block)))
0089 spWordCountExpected += 1;
0090
0091 for (unsigned int mb_block = 0; mb_block < 2; mb_block++)
0092 if (header.active() & 0x20 && (!header.suppression() || spWord[shift + 1] & (1 << (mb_block + 12))))
0093 spWordCountExpected += 1;
0094
0095 for (unsigned int sp_block = 0; sp_block < 3; sp_block++)
0096 if (header.active() & 0x40 && (!header.suppression() || spWord[shift + 1] & (0xF << (sp_block * 4))))
0097 spWordCountExpected += 1;
0098
0099
0100 shift = spWordCountExpected * 4;
0101 }
0102 }
0103
0104
0105 if (header.format_version() && !header.empty())
0106 spWordCountExpected += 1;
0107
0108 if (coruptions & OUT_OF_BUFFER)
0109 break;
0110 }
0111
0112
0113
0114 if ((word_1 & 0xF000F000F000F000LL) == 0xF000F000F000F000LL &&
0115 (word_2 & 0xF000F000F000F000LL) == 0xE000E000E000E000LL) {
0116 if (spTrailer) {
0117 coruptions |= MISSING_HEADER;
0118 break;
0119 }
0120 spHeader = false;
0121 spTrailer = true;
0122
0123 if (spWordCount != spWordCountExpected + 2) {
0124 coruptions |= WORD_COUNT;
0125 break;
0126 }
0127
0128 const unsigned short *spWord = reinterpret_cast<const unsigned short *>(&dduWord[index - spWordCount - 1]);
0129 if (nRecords < 12) {
0130 if (sp[nRecords++].unpack(spWord))
0131 coruptions |= NONSENSE;
0132 } else {
0133 coruptions |= CONFIGURATION;
0134 break;
0135 }
0136 }
0137
0138 index++;
0139 }
0140
0141 return coruptions;
0142 }