Back to home page

Project CMSSW displayed by LXR

 
 

    


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   // Clean up
0008   nRecords = 0;
0009   bzero(sp, sizeof(sp));
0010 
0011   // Make sure that we are running right platform (can't imagine opposite)
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   // Type of coruptions
0016   unsigned long coruptions = 0;
0017 
0018   // Combine 64-bit ddu word for simlicity and efficiency
0019   const unsigned long long *dduWord = reinterpret_cast<const unsigned long long *>(buf);
0020   unsigned long long word_1 = 0, word_2 = 0;
0021   // 'length' counts ddu words now
0022   length /= sizeof(unsigned long long) / sizeof(unsigned short);
0023   // Set of markers
0024   bool spHeader = false, spTrailer = false;
0025   unsigned long spWordCount = 0, spWordCountExpected = 0;
0026 
0027   // Run through the buffer and check its structure
0028   unsigned int index = 0;
0029   while (index < length) {
0030     word_1 = word_2;          // delay by 1 DDU word
0031     word_2 = dduWord[index];  // current DDU word
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       // number of 64-bit words between header and trailer
0045       spWordCount = 0;
0046       spWordCountExpected = 0;
0047       // need header to calculate expected word count
0048       CSCSPHeader header;
0049       const unsigned short *spWord = reinterpret_cast<const unsigned short *>(&dduWord[index - 1]);
0050       // we are here because we have a header => we are safe from crash instantiating one
0051       header.unpack(spWord);
0052 
0053       // Counter block exists only in format version 4.3 and higher
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       // Calculate expected record length (internal variable 'shift' counts 16-bit words)
0064       for (unsigned short tbin = 0, shift = 0; tbin < header.nTBINs() && !header.empty(); tbin++) {
0065         // check if didn't pass end of event, keep in mind that 'length', 'index', and 'spWordCountExpected' counts 64-bit words
0066         if (length <= index + spWordCountExpected + 2) {
0067           coruptions |= OUT_OF_BUFFER;
0068           break;
0069         } else {
0070           // In the format version >=5.3 with zero_supression
0071           if (header.format_version() >= 3 && header.suppression()) {
0072             //  we seek the loop index untill it matches the current non-empty tbin
0073             if (((spWord[shift + 7] >> 8) & 0x7) != tbin + 1)
0074               continue;
0075             //  otherwise there may be no more non-empty tbins and we ran into the trailer
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           // Data Block Header always exists if we got so far
0084           spWordCountExpected += 2;
0085           // 15 ME data blocks
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           // 2 MB data blocks
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           // 3 SP data blocks
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           // multiply by 4 because 'shift' is a 16-bit array index and 'spWordCountExpected' conuts 64-bit words
0100           shift = spWordCountExpected * 4;
0101         }
0102       }
0103 
0104       // Counter block exists only in format version 4.3 and higher
0105       if (header.format_version() && !header.empty())
0106         spWordCountExpected += 1;
0107 
0108       if (coruptions & OUT_OF_BUFFER)
0109         break;
0110     }
0111 
0112     //if( !spHeader && spTrailer ) coruptions |= NONSENSE; ///???
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       // main unpacking
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 }