Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-07 05:50:21

0001 #include "EventFilter/CSCRawToDigi/interface/CSCDCCExaminer.h"
0002 
0003 #ifdef LOCAL_UNPACK
0004 #include <string.h>
0005 
0006 #else
0007 
0008 #include <cstring>
0009 #include <cassert>
0010 
0011 /*
0012 #ifdef CSC_DEBUG
0013 #include <iostream>
0014 #define COUT std::COUT
0015 #define CERR std::CERR
0016 #else
0017 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0018 #define COUT LogTrace("CSCDCCExaminer")
0019 // #define CERR edm::LogWarning("CSCDCCExaminer")
0020 #define CERR LogDebug("CSCDCCExaminer")
0021 #endif
0022 */
0023 
0024 #endif
0025 
0026 #include <iomanip>
0027 using namespace std;
0028 
0029 void CSCDCCExaminer::crcALCT(bool enable) {
0030   checkCrcALCT = enable;
0031   if (checkCrcALCT)
0032     sERROR[10] = "ALCT CRC Error                                   ";
0033   else
0034     sERROR[10] = "ALCT CRC Error ( disabled )                      ";
0035 }
0036 
0037 void CSCDCCExaminer::crcTMB(bool enable) {
0038   checkCrcTMB = enable;
0039   if (checkCrcTMB)
0040     sERROR[15] = "TMB CRC Error                                    ";
0041   else
0042     sERROR[15] = "TMB CRC Error ( disabled )                       ";
0043 }
0044 
0045 void CSCDCCExaminer::crcCFEB(bool enable) {
0046   checkCrcCFEB = enable;
0047   if (checkCrcCFEB)
0048     sERROR[18] = "CFEB CRC Error                                   ";
0049   else
0050     sERROR[18] = "CFEB CRC Error ( disabled )                      ";
0051 }
0052 
0053 void CSCDCCExaminer::modeDDU(bool enable) {
0054   modeDDUonly = enable;
0055   if (modeDDUonly) {
0056     sERROR[25] = "DCC Trailer Missing                              ";
0057     sERROR[26] = "DCC Header Missing                               ";
0058   } else {
0059     sERROR[25] = "DCC Trailer Missing (disabled)                   ";
0060     sERROR[26] = "DCC Header Missing (disabled)                    ";
0061   }
0062 }
0063 
0064 CSCDCCExaminer::CSCDCCExaminer(ExaminerMaskType mask)
0065     : nERRORS(29),
0066       nWARNINGS(5),
0067       nPAYLOADS(16),
0068       nSTATUSES(29),
0069       sERROR(nERRORS),
0070       sWARNING(nWARNINGS),
0071       sERROR_(nERRORS),
0072       sWARNING_(nWARNINGS),
0073       sDMBExpectedPayload(nPAYLOADS),
0074       sDMBEventStaus(nSTATUSES),
0075       examinerMask(mask) {
0076 #ifdef LOCAL_UNPACK
0077   COUT.redirect(std::cout);
0078   CERR.redirect(std::cerr);
0079 #endif
0080 
0081   sERROR[0] = " Any errors                                       ";
0082   sERROR[1] = " DDU Trailer Missing                              ";
0083   sERROR[2] = " DDU Header Missing                               ";
0084   sERROR[3] = " DDU CRC Error (not yet implemented)              ";
0085   sERROR[4] = " DDU Word Count Error                             ";
0086   sERROR[5] = " DMB Trailer Missing                              ";
0087   sERROR[6] = " DMB Header Missing                               ";
0088   sERROR[7] = " ALCT Trailer Missing                             ";
0089   sERROR[8] = " ALCT Header Missing                              ";
0090   sERROR[9] = " ALCT Word Count Error                            ";
0091   sERROR[10] = "ALCT CRC Error                                   ";
0092   sERROR[11] = "ALCT Trailer Bit Error                           ";
0093   // ^^^ This is due to seeing many events in ddu293 (also, some in ddu294)
0094   // with some bits in the 1st ALCT D-Header being lost. This causes a chain of errors:
0095   // - TMB Trailer is not identified and TMB word count mismatch occur when Trailer is found
0096   // - CFEB sample count is not reset on ALCT Trailer.
0097   // To merge all these errors in one,
0098   // the D-signature in the 1st ALCT Trailer will not be required for identifying the ALCT Trailer;
0099   // However, if these bits are found to be missing, ERROR[11] will be flagged.
0100   // This is just a temporary patch to make the output look less clattered.
0101   sERROR[12] = "TMB Trailer Missing                              ";
0102   sERROR[13] = "TMB Header Missing                               ";
0103   sERROR[14] = "TMB Word Count Error                             ";
0104   sERROR[15] = "TMB CRC Error                                    ";
0105   sERROR[16] = "CFEB Word Count Per Sample Error                 ";
0106   sERROR[17] = "CFEB Sample Count Error                          ";
0107   sERROR[18] = "CFEB CRC Error                                   ";
0108   sERROR[19] = "DDU Event Size Limit Error                       ";
0109   sERROR[20] = "C-Words                                          ";
0110   sERROR[21] = "ALCT DAV Error                                   ";
0111   sERROR[22] = "TMB DAV Error                                    ";
0112   sERROR[23] = "CFEB DAV Error                                   ";
0113   sERROR[24] = "DMB Active Error                                 ";
0114   sERROR[25] = "DCC Trailer Missing                              ";
0115   sERROR[26] = "DCC Header Missing                               ";
0116   sERROR[27] = "DMB DAV vs. DMB Active mismatch Error            ";
0117   sERROR[28] = "Extra words between DDU Header and first DMB header";
0118 
0119   //    sERROR[21] = "DDU Header vs. Trailer mismatch for DAV or Avtive"; // oboslete since 16.09.05
0120 
0121   sWARNING[0] = " Extra words between DDU Trailer and DDU Header ";
0122   sWARNING[1] = " DDU Header Incomplete                          ";
0123 
0124   sDMBExpectedPayload[0] = "CFEB1_ACTIVE";
0125   sDMBExpectedPayload[1] = "CFEB2_ACTIVE";
0126   sDMBExpectedPayload[2] = "CFEB3_ACTIVE";
0127   sDMBExpectedPayload[3] = "CFEB4_ACTIVE";
0128   sDMBExpectedPayload[4] = "CFEB5_ACTIVE";
0129   sDMBExpectedPayload[5] = "ALCT_DAV";
0130   sDMBExpectedPayload[6] = "TMB_DAV";
0131   sDMBExpectedPayload[7] = "CFEB1_DAV";
0132   sDMBExpectedPayload[8] = "CFEB2_DAV";
0133   sDMBExpectedPayload[9] = "CFEB3_DAV";
0134   sDMBExpectedPayload[10] = "CFEB4_DAV";
0135   sDMBExpectedPayload[11] = "CFEB5_DAV";
0136   /// 2013 Format additions
0137   sDMBExpectedPayload[12] = "CFEB6_DAV";
0138   sDMBExpectedPayload[13] = "CFEB7_DAV";
0139   sDMBExpectedPayload[14] = "CFEB6_ACTIVE";
0140   sDMBExpectedPayload[15] = "CFEB7_ACTIVE";
0141 
0142   sDMBEventStaus[0] = "ALCT_FIFO_FULL";
0143   sDMBEventStaus[1] = "TMB_FIFO_FULL";
0144   sDMBEventStaus[2] = "CFEB1_FIFO_FULL";
0145   sDMBEventStaus[3] = "CFEB2_FIFO_FULL";
0146   sDMBEventStaus[4] = "CFEB3_FIFO_FULL";
0147   sDMBEventStaus[5] = "CFEB4_FIFO_FULL";
0148   sDMBEventStaus[6] = "CFEB5_FIFO_FULL";
0149   sDMBEventStaus[7] = "ALCT_START_TIMEOUT";
0150   sDMBEventStaus[8] = "TMB_START_TIMEOUT";
0151   sDMBEventStaus[9] = "CFEB1_START_TIMEOUT";
0152   sDMBEventStaus[10] = "CFEB2_START_TIMEOUT";
0153   sDMBEventStaus[11] = "CFEB3_START_TIMEOUT";
0154   sDMBEventStaus[12] = "CFEB4_START_TIMEOUT";
0155   sDMBEventStaus[13] = "CFEB5_START_TIMEOUT";
0156   sDMBEventStaus[14] = "ALCT_END_TIMEOUT";
0157   sDMBEventStaus[15] = "TMB_END_TIMEOUT";
0158   sDMBEventStaus[16] = "CFEB1_END_TIMEOUT";
0159   sDMBEventStaus[17] = "CFEB2_END_TIMEOUT";
0160   sDMBEventStaus[18] = "CFEB3_END_TIMEOUT";
0161   sDMBEventStaus[19] = "CFEB4_END_TIMEOUT";
0162   sDMBEventStaus[20] = "CFEB5_END_TIMEOUT";
0163   sDMBEventStaus[21] = "CFEB Active-DAV mismatch";
0164   sDMBEventStaus[22] = "B-words found";
0165   /// 2013 Format additions
0166   sDMBEventStaus[23] = "CFEB6_FIFO_FULL";
0167   sDMBEventStaus[24] = "CFEB7_FIFO_FULL";
0168   sDMBEventStaus[25] = "CFEB6_START_TIMEOUT";
0169   sDMBEventStaus[26] = "CFEB7_START_TIMEOUT";
0170   sDMBEventStaus[27] = "CFEB6_END_TIMEOUT";
0171   sDMBEventStaus[28] = "CFEB7_END_TIMEOUT";
0172 
0173   sERROR_[0] = " Any errors: 00";
0174   sERROR_[1] = " DDU Trailer Missing: 01";
0175   sERROR_[2] = " DDU Header Missing: 02";
0176   sERROR_[3] = " DDU CRC Error (not yet implemented): 03";
0177   sERROR_[4] = " DDU Word Count Error: 04";
0178   sERROR_[5] = " DMB Trailer Missing: 05";
0179   sERROR_[6] = " DMB Header Missing: 06";
0180   sERROR_[7] = " ALCT Trailer Missing: 07";
0181   sERROR_[8] = " ALCT Header Missing: 08";
0182   sERROR_[9] = " ALCT Word Count Error: 09";
0183   sERROR_[10] = "ALCT CRC Error: 10";
0184   sERROR_[11] = "ALCT Trailer Bit Error: 11";
0185   sERROR_[12] = "TMB Trailer Missing: 12";
0186   sERROR_[13] = "TMB Header Missing: 13";
0187   sERROR_[14] = "TMB Word Count Error: 14";
0188   sERROR_[15] = "TMB CRC Error: 15";
0189   sERROR_[16] = "CFEB Word Count Per Sample Error: 16";
0190   sERROR_[17] = "CFEB Sample Count Error: 17";
0191   sERROR_[18] = "CFEB CRC Error: 18";
0192   sERROR_[19] = "DDU Event Size Limit Error: 19";
0193   sERROR_[20] = "C-Words: 20";
0194   sERROR_[21] = "ALCT DAV Error: 21";
0195   sERROR_[22] = "TMB DAV Error: 22";
0196   sERROR_[23] = "CFEB DAV Error: 23";
0197   sERROR_[24] = "DMB Active Error: 24";
0198   sERROR_[25] = "DCC Trailer Missing: 25";
0199   sERROR_[26] = "DCC Header Missing: 26";
0200   sERROR_[27] = "DMB DAV vs. DMB Active mismatch Error: 27";
0201   sERROR_[28] = "Extra words between DDU Header and first DMB header: 28";
0202   //    sERROR_[21] = "DDU Header vs. Trailer mismatch for DAV or Avtive: 21"; // oboslete since 16.09.05
0203 
0204   sWARNING_[0] = " Extra words between DDU Trailer and DDU Header: 00";
0205   sWARNING_[1] = " DDU Header Incomplete: 02";
0206 
0207   fDCC_Header = false;
0208   fDCC_Trailer = false;
0209   fDDU_Header = false;
0210   fDDU_Trailer = false;
0211   fDMB_Header = false;
0212   fDMB_Trailer = false;
0213   fALCT_Header = false;
0214   fTMB_Header = false;
0215   fALCT_Format2007 = true;
0216   fTMB_Format2007 = true;
0217   fFormat2013 = false;
0218 
0219   cntDDU_Headers = 0;
0220   cntDDU_Trailers = 0;
0221   cntCHAMB_Headers.clear();
0222   cntCHAMB_Trailers.clear();
0223 
0224   DAV_ALCT = false;
0225   DAV_TMB = false;
0226   DAV_CFEB = 0;
0227   DMB_Active = 0;
0228   nDMBs = 0;
0229   DDU_WordsSinceLastHeader = 0;
0230   DDU_WordCount = 0;
0231   DDU_WordMismatch_Occurrences = 0;
0232   DDU_WordsSinceLastTrailer = 0;
0233   ALCT_ZSE = 0;
0234   nWG_round_up = 0;
0235 
0236   TMB_WordsRPC = 0;
0237   TMB_WordsGEM = 0;
0238   TMB_Firmware_Revision = 0;
0239   DDU_Firmware_Revision = 0;
0240   zeroCounts();
0241 
0242   checkCrcALCT = false;
0243   ALCT_CRC = 0;
0244   checkCrcTMB = false;
0245   TMB_CRC = 0;
0246   checkCrcCFEB = false;
0247   CFEB_CRC = 0;
0248 
0249   modeDDUonly = false;
0250   sourceID = 0xFFF;
0251   currentChamber = -1;
0252 
0253   //headerDAV_Active = -1; // Trailer vs. Header check // Obsolete since 16.09.05
0254 
0255   clear();
0256   buf_1 = &(tmpbuf[0]);
0257   buf0 = &(tmpbuf[4]);
0258   buf1 = &(tmpbuf[8]);
0259   buf2 = &(tmpbuf[12]);
0260 
0261   bzero(tmpbuf, sizeof(uint16_t) * 16);
0262 }
0263 
0264 int32_t CSCDCCExaminer::check(const uint16_t*& buffer, int32_t length) {
0265   if (length <= 0)
0266     return -1;
0267 
0268   /// 'buffer' is a sliding pointer; keep track of the true buffer
0269   buffer_start = buffer;
0270 
0271   /// Check for presence of data blocks inside TMB data
0272   bool fTMB_MiniScope_Start = false;
0273   bool fTMB_RPC_Start = false;
0274   bool fTMB_GEM_Start = false;
0275   bool fTMB_BlockedCFEBs_Start = false;
0276 
0277   bool fTMB_MiniScope = false;
0278   bool fTMB_RPC = false;
0279   bool fTMB_GEM = false;
0280   bool fTMB_BlockedCFEBs = false;
0281 
0282   while (length > 0) {
0283     // == Store last 4 read buffers in pipeline-like memory (note that memcpy works quite slower!)
0284     buf_2 = buf_1;  //  This bufer was not needed so far
0285     buf_1 = buf0;
0286     buf0 = buf1;
0287     buf1 = buf2;
0288     buf2 = buffer;
0289 
0290     // check for too long event
0291     if (!fERROR[19] && DDU_WordsSinceLastHeader > 100000) {
0292       fERROR[19] = true;
0293       bERROR |= 0x80000;
0294     }
0295 
0296     // increment counter of 64-bit words since last DDU Header
0297     // this counter is reset if DDU Header is found
0298     if (fDDU_Header) {
0299       ++DDU_WordsSinceLastHeader;
0300     }
0301 
0302     // increment counter of 64-bit words since last DDU Trailer
0303     // this counter is reset if DDU Trailer is found
0304     if (fDDU_Trailer) {
0305       ++DDU_WordsSinceLastTrailer;
0306     }
0307 
0308     /// increment counter of 16-bit words since last DMB*ALCT Header match
0309     /// this counter is reset if ALCT Header is found right after DMB Header
0310     if (fALCT_Header) {
0311       /// decode the actual counting if zero suppression enabled
0312       /// Note: For Run3 the ALCT boards firmware has HMT bits added to ALCTs words, which interferes with ZSE anode rawhits flags
0313       ///       making ALCT words calculation incorrect. Added condition to do not check ZSE flags for ALCT words before rawhits
0314       if (ALCT_ZSE && (ALCT_WordsSinceLastHeaderZeroSuppressed >= ALCT_WordsBeforeRaw)) {
0315         for (int g = 0; g < 4; g++) {
0316           if (buf0[g] == 0x1000) {
0317             ALCT_WordsSinceLastHeader = ALCT_WordsSinceLastHeader + nWG_round_up;
0318           } else if (buf0[g] != 0x3000)
0319             ALCT_WordsSinceLastHeader = ALCT_WordsSinceLastHeader + 1;
0320         }
0321       } else
0322         ALCT_WordsSinceLastHeader = ALCT_WordsSinceLastHeader + 4;
0323       /// increment counter of 16-bit words without zero suppression decoding
0324       ALCT_WordsSinceLastHeaderZeroSuppressed = ALCT_WordsSinceLastHeaderZeroSuppressed + 4;
0325     }
0326 
0327     // increment counter of 16-bit words since last DMB*TMB Header match
0328     // this counter is reset if TMB Header is found right after DMB Header or ALCT Trailer
0329     if (fTMB_Header) {
0330       TMB_WordsSinceLastHeader = TMB_WordsSinceLastHeader + 4;
0331     }
0332 
0333     // increment counter of 16-bit words since last of DMB Header, ALCT Trailer, TMB Trailer,
0334     // CFEB Sample Trailer, CFEB B-word; this counter is reset by all these conditions
0335     if (fDMB_Header) {
0336       CFEB_SampleWordCount = CFEB_SampleWordCount + 4;
0337     }
0338 
0339     // If DDU header is missing we set unphysical 0xFFF value for DDU id
0340     if (!fDDU_Header) {
0341       sourceID = 0xFFF;
0342     }
0343 
0344     if (!modeDDUonly) {
0345       // DCC Header 1 && DCC Header 2
0346       // =VB= Added support for Sep. 2008 CMS DAQ DCC format
0347       if ((((buf0[3] & 0xF000) == 0x5000 && (buf0[0] & 0x00FF) == 0x005F) ||
0348            ((buf0[3] & 0xF000) == 0x5000 && (buf0[0] & 0x000F) == 0x0008)) &&
0349           // =VB= Why 0xD900 signature word if only 0xD part is constant???
0350           // (buf1[3]&0xFF00) == 0xD900 )
0351           (buf1[3] & 0xF000) == 0xD000) {
0352         if (fDCC_Header) {
0353           // == Another DCC Header before encountering DCC Trailer!
0354           fERROR[25] = true;
0355           bERROR |= 0x2000000;
0356           fERROR[0] = true;
0357           bERROR |= 0x1;
0358 #ifdef LOCAL_UNPACK
0359           CERR << "\n\nDCC Header Occurrence ";
0360           CERR << "  ERROR 25    " << sERROR[25] << endl;
0361 #endif
0362           fDDU_Header = false;
0363 
0364           // go backward for 3 DDU words ( buf2, buf1, and buf0 )
0365           buffer -= 12;
0366           buf_1 = &(tmpbuf[0]);  // Just for safety
0367           buf0 = &(tmpbuf[4]);   // Just for safety
0368           buf1 = &(tmpbuf[8]);   // Just for safety
0369           buf2 = &(tmpbuf[12]);  // Just for safety
0370           bzero(tmpbuf, sizeof(uint16_t) * 16);
0371           sync_stats();
0372           return length + 12;
0373         }
0374 
0375         fDCC_Header = true;
0376         clear();
0377       }
0378     }
0379     // == Check for Format Control Words, set proper flags, perform self-consistency checks
0380 
0381     // C-words anywhere besides DDU Header
0382     if (fDDU_Header &&
0383         ((buf0[0] & 0xF000) == 0xC000 || (buf0[1] & 0xF000) == 0xC000 || (buf0[2] & 0xF000) == 0xC000 ||
0384          (buf0[3] & 0xF000) == 0xC000) &&
0385         (/*buf_1[0]!=0x8000 ||*/ buf_1[1] != 0x8000 || buf_1[2] != 0x0001 || buf_1[3] != 0x8000)) {
0386       fERROR[0] = true;
0387       bERROR |= 0x1;
0388       fERROR[20] = true;
0389       bERROR |= 0x100000;
0390       // fCHAMB_ERR[20].insert(currentChamber);
0391       // bCHAMB_ERR[currentChamber] |= 0x100000;
0392 #ifdef LOCAL_UNPACK
0393       CERR << "\nDDU Header Occurrence = " << cntDDU_Headers;
0394       CERR << "  ERROR 20 " << sERROR[20] << endl;
0395 #endif
0396     }
0397 
0398     // == DDU Header found
0399     if (/*buf0[0]==0x8000 &&*/ buf0[1] == 0x8000 && buf0[2] == 0x0001 && buf0[3] == 0x8000) {
0400       // headerDAV_Active = (buf1[1]<<16) | buf1[0]; // Obsolete since 16.09.05
0401       /////////////////////////////////////////////////////////
0402       checkDAVs();
0403       checkTriggerHeadersAndTrailers();
0404       /////////////////////////////////////////////////////////
0405 
0406       if (fDDU_Header) {
0407         // == Another DDU Header before encountering DDU Trailer!
0408         fERROR[1] = true;
0409         bERROR |= 0x2;
0410         fERROR[0] = true;
0411         bERROR |= 0x1;
0412 #ifdef LOCAL_UNPACK
0413         CERR << "\n\nDDU Header Occurrence = " << cntDDU_Headers;
0414         CERR << "  ERROR 1    " << sERROR[1] << endl;
0415 #endif
0416         fDDU_Header = false;
0417 
0418         // Part of work for chambers that hasn't been done in absent trailer
0419         if (fDMB_Header || fDMB_Trailer) {
0420           fERROR[5] = true;
0421           bERROR |= 0x20;
0422           // Since here there are no chances to know what this chamber was, force it to be -2
0423           if (currentChamber == -1)
0424             currentChamber = -2;
0425           fCHAMB_ERR[5].insert(currentChamber);
0426           bCHAMB_ERR[currentChamber] |= 0x20;
0427           fCHAMB_ERR[0].insert(currentChamber);
0428           bCHAMB_ERR[currentChamber] |= 0x1;
0429 #ifdef LOCAL_UNPACK
0430           CERR << "\n\nDDU Header Occurrence = " << cntDDU_Headers;
0431           CERR << "  ERROR 5    " << sERROR[5] << endl;
0432 #endif
0433         }  // One of DMB Trailers is missing ( or both )
0434         fDMB_Header = false;
0435         fDMB_Trailer = false;
0436 
0437         if (DMB_Active != nDMBs) {
0438           fERROR[24] = true;
0439           bERROR |= 0x1000000;
0440         }
0441         DMB_Active = 0;
0442         nDMBs = 0;
0443 
0444         // Unknown chamber denoted as -2
0445         // If it still remains in any of errors - put it in error 0
0446         for (int err = 1; err < nERRORS; ++err)
0447           if (fCHAMB_ERR[err].find(-2) != fCHAMB_ERR[err].end()) {
0448             fCHAMB_ERR[0].insert(-2);
0449             bCHAMB_ERR[-2] |= 0x1;
0450           }
0451 
0452         bDDU_ERR[sourceID] |= bERROR;
0453         bDDU_WRN[sourceID] |= bWARNING;
0454 
0455         // go backward for 3 DDU words ( buf2, buf1, and buf0 )
0456         buffer -= 12;
0457         buf_1 = &(tmpbuf[0]);  // Just for safety
0458         buf0 = &(tmpbuf[4]);   // Just for safety
0459         buf1 = &(tmpbuf[8]);   // Just for safety
0460         buf2 = &(tmpbuf[12]);  // Just for safety
0461         bzero(tmpbuf, sizeof(uint16_t) * 16);
0462         sync_stats();
0463         return length + 12;
0464       }
0465 
0466       currentChamber = -1;  // Unknown yet
0467 
0468       if (fDDU_Trailer && DDU_WordsSinceLastTrailer != 4) {
0469         // == Counted extraneous words between last DDU Trailer and this DDU Header
0470         fWARNING[0] = true;
0471         bWARNING |= 0x1;
0472 #ifdef LOCAL_UNPACK
0473         CERR << "\nDDU Header Occurrence = " << cntDDU_Headers;
0474         CERR << "  WARNING 0 " << sWARNING[0] << " " << DDU_WordsSinceLastTrailer << " extra 64-bit words" << endl;
0475 #endif
0476       }
0477 
0478       sourceID = ((buf_1[1] & 0xF) << 8) | ((buf_1[0] & 0xFF00) >> 8);
0479 
0480       ///* 2013 Data format version check
0481       DDU_Firmware_Revision = (buf_1[0] >> 4) & 0xF;
0482       if (DDU_Firmware_Revision > 6) {
0483         fFormat2013 = true;
0484         modeDDUonly = true;  // =VB= Force to use DDU only mode (no DCC Data)
0485       }
0486 
0487       fDDU_Header = true;
0488       fDDU_Trailer = false;
0489       DDU_WordCount = 0;
0490       fDMB_Header = false;
0491       fDMB_Trailer = false;
0492       fALCT_Header = false;
0493       fALCT_Format2007 = true;
0494       fTMB_Header = false;
0495       fTMB_Format2007 = true;
0496       uniqueALCT = true;
0497       uniqueTMB = true;
0498       zeroCounts();
0499 
0500       if (modeDDUonly) {
0501         fDCC_Header = true;
0502         clear();
0503       }
0504 
0505       dduBuffers[sourceID] = buf_1;
0506       dduOffsets[sourceID] = buf_1 - buffer_start;
0507       dduSize[sourceID] = 0;
0508       dmbBuffers[sourceID].clear();
0509       dmbOffsets[sourceID].clear();
0510       dmbSize[sourceID].clear();
0511 
0512       // Reset all Error and Warning flags to be false
0513       bDDU_ERR[sourceID] = 0;
0514       bDDU_WRN[sourceID] = 0;
0515       bERROR = 0;
0516       bWARNING = 0;
0517       bzero(fERROR, sizeof(bool) * nERRORS);
0518       bzero(fWARNING, sizeof(bool) * nWARNINGS);
0519 
0520       nDMBs = 0;
0521       DMB_Active = buf1[0] & 0xF;
0522       DAV_DMB = buf1[1] & 0x7FFF;
0523 
0524       int nDAV_DMBs = 0;
0525       for (int bit = 0; bit < 15; bit++)
0526         if (DAV_DMB & (1 << bit))
0527           nDAV_DMBs++;
0528       if (DMB_Active != nDAV_DMBs) {
0529         fERROR[27] = true;
0530         bERROR |= 0x8000000;
0531       }
0532 
0533       if ((buf_1[3] & 0xF000) != 0x5000) {
0534         fWARNING[1] = true;
0535         bWARNING |= 0x2;
0536 #ifdef LOCAL_UNPACK
0537         CERR << "\nDDU Header Occurrence = " << cntDDU_Headers;
0538         CERR << "  WARNING 1 " << sWARNING[1] << ". What must have been Header 1: 0x" << std::hex << buf_1[0] << " 0x"
0539              << buf_1[1] << " 0x" << buf_1[2] << " 0x" << buf_1[3] << std::dec << endl;
0540 #endif
0541       }
0542 
0543       ++cntDDU_Headers;
0544       DDU_WordsSinceLastHeader = 0;  // Reset counter of DDU Words since last DDU Header
0545 #ifdef LOCAL_UNPACK
0546       COUT << "\n----------------------------------------------------------" << endl;
0547       COUT << "DDU  Header Occurrence " << cntDDU_Headers
0548            << " L1A = " << (((buf_1[2] & 0xFFFF) + ((buf_1[3] & 0x00FF) << 16))) << endl;
0549 #endif
0550     }
0551 
0552     // == DMB Header found
0553     if ((buf0[0] & 0xF000) == 0xA000 && (buf0[1] & 0xF000) == 0xA000 && (buf0[2] & 0xF000) == 0xA000 &&
0554         (buf0[3] & 0xF000) == 0xA000) {
0555       /////////////////////////////////////////////////////////
0556       checkDAVs();
0557       checkTriggerHeadersAndTrailers();
0558       /////////////////////////////////////////////////////////
0559 
0560       if (DDU_WordsSinceLastHeader > 3 && !fDMB_Header && !fDMB_Trailer && !nDMBs) {
0561         fERROR[28] = true;
0562         bERROR |= 0x10000000;
0563         ;
0564       }
0565 
0566       if (fDMB_Header || fDMB_Trailer)  // F or E  DMB Trailer is missed
0567       {
0568         fERROR[5] = true;
0569         bERROR |= 0x20;
0570         fCHAMB_ERR[5].insert(currentChamber);
0571         bCHAMB_ERR[currentChamber] |= 0x20;
0572         fCHAMB_ERR[0].insert(currentChamber);
0573         bCHAMB_ERR[currentChamber] |= 0x1;
0574       }
0575       fDMB_Header = true;
0576       fDMB_Trailer = false;
0577 
0578       // If previous DMB record was not assigned to any chamber ( it still has -1 indentificator )
0579       // let's free -1 identificator for current use and call undefined chamber from previous record -2
0580       // ( -2 may already exists in this sets but we have nothing to do with it )
0581       for (int err = 0; err < nERRORS; ++err)
0582         if (fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end()) {
0583           fCHAMB_ERR[err].erase(-1);
0584           fCHAMB_ERR[err].insert(-2);
0585         }
0586       // Two lines below are commented out because payloads never get filled if 0xA header is missing
0587       //      bCHAMB_PAYLOAD[-2] |= bCHAMB_PAYLOAD[-1];
0588       //      fCHAMB_PAYLOAD[-1] = 0;
0589       bCHAMB_STATUS[-2] |= bCHAMB_STATUS[-1];
0590       bCHAMB_STATUS[-1] = 0;
0591       bCHAMB_ERR[-2] |= bCHAMB_ERR[-1];
0592       bCHAMB_ERR[-1] = 0;
0593       bCHAMB_WRN[-2] |= bCHAMB_WRN[-1];
0594       bCHAMB_WRN[-1] = 0;
0595 
0596       // Chamber id ( DMB_ID + (DMB_CRATE<<4) ) from header
0597       currentChamber = buf0[1] & 0x0FFF;
0598       ++cntCHAMB_Headers[currentChamber];
0599       bCHAMB_ERR[currentChamber] |= 0;  //Victor's line
0600 
0601       fALCT_Header = false;
0602       fALCT_Format2007 = true;
0603       fTMB_Header = false;
0604       fTMB_Format2007 = true;
0605       uniqueALCT = true;
0606       uniqueTMB = true;
0607 
0608       fTMB_MiniScope_Start = false;
0609       fTMB_RPC_Start = false;
0610       fTMB_GEM_Start = false;
0611       fTMB_BlockedCFEBs_Start = false;
0612 
0613       fTMB_MiniScope = false;
0614       fTMB_RPC = false;
0615       fTMB_GEM = false;
0616       fTMB_BlockedCFEBs = false;
0617 
0618       zeroCounts();
0619       CFEB_CRC = 0;
0620 
0621       nDMBs++;
0622 
0623       dmbBuffers[sourceID][currentChamber] = buf0 - 4;
0624       dmbOffsets[sourceID][currentChamber] = buf0 - 4 - buffer_start;
0625       dmbSize[sourceID][currentChamber] = 4;
0626 
0627 #ifdef LOCAL_UNPACK
0628       // Print DMB_ID from DMB Header
0629       COUT << "Crate=" << setw(3) << setfill('0') << ((buf0[1] >> 4) & 0x00FF) << " DMB=" << setw(2) << setfill('0')
0630            << (buf0[1] & 0x000F) << " ";
0631       // Print ALCT_DAV and TMB_DAV from DMB Header
0632       //COUT<<setw(1)<<((buf0[0]&0x0020)>>5)<<" "<<((buf0[0]&0x0040)>>6)<<" ";
0633       COUT << setw(1) << ((buf0[0] & 0x0200) >> 9) << " " << ((buf0[0] & 0x0800) >> 11)
0634            << " ";  //change of format 16.09.05
0635       // Print CFEB_DAV from DMB Header
0636       COUT << setw(1) << ((buf0[0] & 0x0010) >> 4) << ((buf0[0] & 0x0008) >> 3) << ((buf0[0] & 0x0004) >> 2)
0637            << ((buf0[0] & 0x0002) >> 1) << (buf0[0] & 0x0001);
0638       // Print DMB Header Tag
0639       COUT << " {";
0640 #endif
0641 
0642       if (fFormat2013)  /// 2013 Data format
0643       {
0644         // Set variables if we are waiting ALCT, TMB and CFEB records to be present in event
0645         DAV_ALCT = (buf0[0] & 0x0800) >> 11;
0646         DAV_TMB = (buf0[0] & 0x0400) >> 10;
0647         DAV_CFEB = 0;
0648         if (buf0[0] & 0x0001)
0649           ++DAV_CFEB;
0650         if (buf0[0] & 0x0002)
0651           ++DAV_CFEB;
0652         if (buf0[0] & 0x0004)
0653           ++DAV_CFEB;
0654         if (buf0[0] & 0x0008)
0655           ++DAV_CFEB;
0656         if (buf0[0] & 0x0010)
0657           ++DAV_CFEB;
0658         if (buf0[0] & 0x0020)
0659           ++DAV_CFEB;
0660         if (buf0[0] & 0x0040)
0661           ++DAV_CFEB;
0662         if (DAV_ALCT)
0663           bCHAMB_PAYLOAD[currentChamber] |= 0x20;
0664         if (DAV_TMB)
0665           bCHAMB_PAYLOAD[currentChamber] |= 0x40;
0666 
0667         /// Moved around 7 CFEBs Active and CFEB DAV payload bits to be compatible with 5 CFEBs version
0668         bCHAMB_PAYLOAD[currentChamber] |= (buf0[0] & 0x007f) << 7;           /// CFEBs DAV
0669         bCHAMB_PAYLOAD[currentChamber] |= (buf_1[2] & 0x001f);               /// CFEBs Active 5
0670         bCHAMB_PAYLOAD[currentChamber] |= ((buf_1[2] >> 5) & 0x0003) << 14;  /// CFEBs Active 6,7
0671         bCHAMB_STATUS[currentChamber] |= (buf0[0] & 0x0080) << 14;           /// CLCT-DAV-Mismatch
0672 
0673       } else  /// Pre-2013 DMB Format
0674       {
0675         // Set variables if we are waiting ALCT, TMB and CFEB records to be present in event
0676         DAV_ALCT = (buf0[0] & 0x0200) >> 9;
0677         DAV_TMB = (buf0[0] & 0x0800) >> 11;
0678         DAV_CFEB = 0;
0679         if (buf0[0] & 0x0001)
0680           ++DAV_CFEB;
0681         if (buf0[0] & 0x0002)
0682           ++DAV_CFEB;
0683         if (buf0[0] & 0x0004)
0684           ++DAV_CFEB;
0685         if (buf0[0] & 0x0008)
0686           ++DAV_CFEB;
0687         if (buf0[0] & 0x0010)
0688           ++DAV_CFEB;
0689         if (DAV_ALCT)
0690           bCHAMB_PAYLOAD[currentChamber] |= 0x20;
0691         if (DAV_TMB)
0692           bCHAMB_PAYLOAD[currentChamber] |= 0x40;
0693         bCHAMB_PAYLOAD[currentChamber] |= (buf0[0] & 0x001f) << 7;
0694         bCHAMB_PAYLOAD[currentChamber] |= ((buf_1[2] >> 5) & 0x001f);
0695         bCHAMB_STATUS[currentChamber] |= (buf0[0] & 0x0040) << 15;
0696       }
0697     }
0698 
0699     // New ALCT data format:
0700     if ((buf0[0] == 0xDB0A && (buf0[1] & 0xF000) == 0xD000 && (buf0[2] & 0xF000) == 0xD000 &&
0701          (buf0[3] & 0xF000) == 0xD000) &&
0702         ((buf_1[0] & 0xF000) == 0xA000 && (buf_1[1] & 0xF000) == 0xA000 && (buf_1[2] & 0xF000) == 0xA000 &&
0703          (buf_1[3] & 0xF000) == 0xA000)) {
0704       fALCT_Header = true;
0705       fALCT_Format2007 = true;
0706       ALCT_CRC = 0;
0707       ALCT_WordsSinceLastHeader = 4;
0708       ALCT_WordsSinceLastHeaderZeroSuppressed = 4;
0709 
0710       // Calculate expected number of ALCT words
0711       ALCT_WordsExpected = 12;  // header and trailer always exists
0712 
0713       //  Aauxilary variables
0714       //   number of wire groups per layer:
0715       int nWGs_per_layer = ((buf1[2] & 0x0007) + 1) * 16;
0716       // words in the layer
0717       nWG_round_up = int(nWGs_per_layer / 12) + (nWGs_per_layer % 3 ? 1 : 0);
0718       //   configuration present:
0719       bool config_present = buf1[0] & 0x4000;
0720       //   lct overflow:
0721       bool lct_overflow = buf1[0] & 0x2000;
0722       //   raw overflow:
0723       bool raw_overflow = buf1[0] & 0x1000;
0724       //   l1a_window:
0725       int lct_tbins = (buf1[3] & 0x01E0) >> 5;
0726       //   fifo_tbins:
0727       int raw_tbins = (buf1[3] & 0x001F);
0728 
0729       ///   Check if ALCT zero suppression enable:
0730       ALCT_ZSE = (buf1[1] & 0x1000) >> 12;
0731 
0732 #ifdef LOCAL_UNPACK
0733 /*
0734       COUT << " Number of Wire Groups: " << nWG_round_up << std::endl;
0735       COUT << " ALCT_ZSE: " << ALCT_ZSE << std::endl;
0736       COUT << " raw_tbins: " << std::dec << raw_tbins << std::endl;
0737       COUT << " LCT Tbins: " << lct_tbins << std::endl;
0738 */
0739 #endif
0740 
0741       //  Data block sizes:
0742       //   3 words of Vertex ID register + 5 words of config. register bits:
0743       int config_size = (config_present ? 3 + 5 : 0);
0744       //   collision mask register:
0745       int colreg_size = (config_present ? nWGs_per_layer / 4 : 0);
0746       //   hot channel mask:
0747       int hot_ch_size = (config_present ? nWG_round_up * 6 : 0);
0748       //   ALCT0,1 (best tracks):
0749       int alct_0_1_size = (!lct_overflow ? 2 * lct_tbins : 0);
0750       //   raw hit dump size:
0751       int raw_hit_dump_size = (!raw_overflow ? nWG_round_up * 6 * raw_tbins : 0);
0752 
0753 #ifdef LOCAL_UNPACK
0754       // COUT << " Raw Hit Dump: " << std::dec << raw_hit_dump_size << std::endl;
0755 #endif
0756 
0757       ALCT_WordsExpected += config_size + colreg_size + hot_ch_size + alct_0_1_size + raw_hit_dump_size;
0758       ALCT_WordsBeforeRaw = 8 + config_size + colreg_size + hot_ch_size + alct_0_1_size;
0759 
0760 #ifdef LOCAL_UNPACK
0761       COUT << " <A";
0762 #endif
0763 
0764     } else {
0765       // Old ALCT data format
0766 
0767       // == ALCT Header found right after DMB Header
0768       //   (check for all currently reserved/fixed bits in ALCT first 4 words)
0769       // if( ( (buf0 [0]&0xF800)==0x6000 && (buf0 [1]&0xFF80)==0x0080 && (buf0 [2]&0xF000)==0x0000 && (buf0 [3]&0xc000)==0x0000 )
0770       if (((buf0[0] & 0xF800) == 0x6000 && (buf0[1] & 0x8F80) == 0x0080 && (buf0[2] & 0x8000) == 0x0000 &&
0771            (buf0[3] & 0xc000) == 0x0000) &&
0772           ((buf_1[0] & 0xF000) == 0xA000 && (buf_1[1] & 0xF000) == 0xA000 && (buf_1[2] & 0xF000) == 0xA000 &&
0773            (buf_1[3] & 0xF000) == 0xA000)) {
0774         fALCT_Header = true;
0775         fALCT_Format2007 = false;
0776         ALCT_CRC = 0;
0777         ALCT_WordsSinceLastHeader = 4;
0778 
0779         // Calculate expected number of ALCT words
0780         if ((buf0[3] & 0x0003) == 0) {
0781           ALCT_WordsExpected = 12;  // Short Readout
0782         }
0783 
0784         if ((buf0[1] & 0x0003) == 1)  // Full Readout
0785         {
0786           ALCT_WordsExpected = ((buf0[1] & 0x007c) >> 2) *
0787                                    (((buf0[3] & 0x0001)) + ((buf0[3] & 0x0002) >> 1) + ((buf0[3] & 0x0004) >> 2) +
0788                                     ((buf0[3] & 0x0008) >> 3) + ((buf0[3] & 0x0010) >> 4) + ((buf0[3] & 0x0020) >> 5) +
0789                                     ((buf0[3] & 0x0040) >> 6)) *
0790                                    12 +
0791                                12;
0792         }
0793 #ifdef LOCAL_UNPACK
0794         COUT << " <A";
0795 #endif
0796       }
0797     }
0798 #ifdef LOCAL_UNPACK
0799     //COUT << " ALCT Word Expected: " << ALCT_WordsExpected << std::endl;
0800 #endif
0801 
0802     if ((buf0[0] & 0xFFFF) == 0xDB0C) {
0803       // =VB= Handles one of the OTMB corrupted data cases.
0804       //      Double TMB data block with 2nd TMB Header is found.
0805       //      Set missing TMB Trailer error.
0806       if (fTMB_Header) {
0807         fERROR[12] = true;  // TMB Trailer is missing
0808         bERROR |= 0x1000;
0809         fCHAMB_ERR[12].insert(currentChamber);
0810         bCHAMB_ERR[currentChamber] |= 0x1000;
0811       }
0812 
0813       fTMB_Header = true;
0814       fTMB_Format2007 = true;
0815       TMB_CRC = 0;
0816       TMB_WordsSinceLastHeader = 4;
0817       TMB_WordsExpected = 0;
0818 
0819       // Calculate expected number of TMB words (whether RPC included will be known later)
0820       if ((buf1[1] & 0x3000) == 0x3000) {
0821         TMB_WordsExpected = 12;  // Short Header Only
0822       }
0823       if ((buf1[1] & 0x3000) == 0x0000) {
0824         TMB_WordsExpected = 48;  // Long Header Only
0825       }
0826 
0827 #ifdef LOCAL_UNPACK
0828       COUT << " <T";
0829 #endif
0830     } else {
0831       // == TMB Header found right after DMB Header or right after ALCT Trailer
0832       if ((buf0[0] & 0xFFFF) == 0x6B0C && (((buf_1[0] & 0xF000) == 0xA000 && (buf_1[1] & 0xF000) == 0xA000 &&
0833                                             (buf_1[2] & 0xF000) == 0xA000 && (buf_1[3] & 0xF000) == 0xA000) ||
0834                                            ((buf_1[0] & 0x0800) == 0x0000 && (buf_1[1] & 0xF800) == 0xD000 &&
0835                                             (buf_1[2] & 0xFFFF) == 0xDE0D && (buf_1[3] & 0xF000) == 0xD000)
0836                                            // should've been (buf_1[0]&0xF800)==0xD000 - see comments for sERROR[11]
0837                                            )) {
0838         //if( (buf_1[2]&0xFFFF)==0xDE0D && (buf_1[3]&0xFC00)!=0xD000 && summer2004 ) ???
0839 
0840         fTMB_Header = true;
0841         fTMB_Format2007 = false;
0842         TMB_CRC = 0;
0843         TMB_WordsSinceLastHeader = 4;
0844 
0845         // Calculate expected number of TMB words (whether RPC included will be known later)
0846         if ((buf0[1] & 0x3000) == 0x3000) {
0847           TMB_WordsExpected = 8;  // Short Header Only
0848         }
0849         if ((buf0[1] & 0x3000) == 0x0000) {
0850           TMB_WordsExpected = 32;  // Long Header Only
0851         }
0852 
0853         if ((buf0[1] & 0x3000) == 0x1000) {
0854           // Full Readout   = 28 + (#Tbins * #CFEBs * 6)
0855           TMB_Tbins = (buf0[1] & 0x001F);
0856           TMB_WordsExpected = 28 + TMB_Tbins * ((buf1[0] & 0x00E0) >> 5) * 6;
0857         }
0858 #ifdef LOCAL_UNPACK
0859         COUT << " <T";
0860 #endif
0861       }
0862     }
0863     // New TMB format => very long header Find Firmware revision
0864     if (fTMB_Header && fTMB_Format2007 && TMB_WordsSinceLastHeader == 8) {
0865       TMB_Firmware_Revision = buf0[3];
0866     }
0867 
0868     // New TMB format => very long header
0869     if (fTMB_Header && fTMB_Format2007 && TMB_WordsSinceLastHeader == 20) {
0870       // Full Readout   = 44 + (#Tbins * #CFEBs * 6)
0871       TMB_Tbins = (buf0[3] & 0x00F8) >> 3;
0872       TMB_WordsExpected = 44 + TMB_Tbins * (buf0[3] & 0x0007) * 6;
0873     }
0874 
0875     // == ALCT Trailer found
0876     if (
0877         // New ALCT data format:
0878         (buf0[0] == 0xDE0D && (buf0[1] & 0xF800) == 0xD000 && (buf0[2] & 0xF800) == 0xD000 &&
0879          (buf0[3] & 0xF000) == 0xD000 && fALCT_Format2007) ||
0880         // Old ALCT data format; last check is added to avoid confusion with new TMB header (may not be needed):
0881         ((buf0[0] & 0x0800) == 0x0000 && (buf0[1] & 0xF800) == 0xD000 && (buf0[2] & 0xFFFF) == 0xDE0D &&
0882          (buf0[3] & 0xF000) == 0xD000 && !fALCT_Format2007 && !(fTMB_Header && fTMB_Format2007))) {
0883       // should've been (buf0[0]&0xF800)==0xD000 - see comments for sERROR[11]
0884 
0885       // Second ALCT -> Lost both previous DMB Trailer and current DMB Header
0886       if (!uniqueALCT)
0887         currentChamber = -1;
0888       // Check if this ALCT record have to exist according to DMB Header
0889       if (DAV_ALCT)
0890         DAV_ALCT = false;
0891       else
0892         DAV_ALCT = true;
0893 
0894       if (!fALCT_Header) {
0895         fERROR[8] = true;
0896         bERROR |= 0x100;
0897         fCHAMB_ERR[8].insert(currentChamber);
0898         bCHAMB_ERR[currentChamber] |= 0x100;
0899         fCHAMB_ERR[0].insert(currentChamber);
0900         bCHAMB_ERR[currentChamber] |= 0x1;
0901       }  // ALCT Header is missing
0902 
0903       if (!fALCT_Format2007 && (buf0[0] & 0xF800) != 0xD000) {
0904         fERROR[11] = true;
0905         bERROR |= 0x800;
0906         fCHAMB_ERR[11].insert(currentChamber);
0907         bCHAMB_ERR[currentChamber] |= 0x800;
0908         fCHAMB_ERR[0].insert(currentChamber);
0909         bCHAMB_ERR[currentChamber] |= 0x1;
0910       }  // some bits in 1st D-Trailer are lost
0911 
0912 #ifdef LOCAL_UNPACK
0913       /// Print Out ALCT word counting
0914 /*
0915       COUT << " ALCT Word Since Last Header: " << ALCT_WordsSinceLastHeader << std::endl;
0916       COUT << " ALCT Words Before RawHits : " << ALCT_WordsBeforeRaw << std::endl;
0917       COUT << " ALCT Word Expected: " << ALCT_WordsExpected << std::endl;
0918       COUT << " ALCT Word Since Last Header Zero Supressed: " << ALCT_WordsSinceLastHeaderZeroSuppressed << std::endl;
0919 */
0920 #endif
0921       /// Check calculated CRC sum against reported
0922       if (checkCrcALCT) {
0923         uint32_t crc = (fALCT_Format2007 ? buf0[1] : buf0[0]) & 0x7ff;
0924         crc |= ((uint32_t)((fALCT_Format2007 ? buf0[2] : buf0[1]) & 0x7ff)) << 11;
0925         if (ALCT_CRC != crc) {
0926           fERROR[10] = true;
0927           bERROR |= 0x400;
0928           fCHAMB_ERR[10].insert(currentChamber);
0929           bCHAMB_ERR[currentChamber] |= 0x400;
0930           fCHAMB_ERR[0].insert(currentChamber);
0931           bCHAMB_ERR[currentChamber] |= 0x1;
0932         }
0933       }
0934 
0935       fALCT_Header = false;
0936       uniqueALCT = false;
0937       CFEB_CRC = 0;
0938       //ALCT_WordCount = (buf0[3]&0x03FF);
0939       ALCT_WordCount = (buf0[3] & 0x07FF);
0940       //ALCT_WordCount = (buf0[3]&0x0FFF);
0941       CFEB_SampleWordCount = 0;
0942 #ifdef LOCAL_UNPACK
0943       COUT << "A> ";
0944 #endif
0945     }
0946 
0947     // Calculation of CRC sum ( algorithm is written by Madorsky )
0948     if (fALCT_Header && checkCrcALCT) {
0949       for (uint16_t j = 0, w = 0; j < 4; ++j) {
0950         ///w = buf0[j] & 0x7fff;
0951         w = buf0[j] & (fALCT_Format2007 ? 0xffff : 0x7fff);
0952         for (uint32_t i = 15, t = 0, ncrc = 0; i < 16; i--) {
0953           t = ((w >> i) & 1) ^ ((ALCT_CRC >> 21) & 1);
0954           ncrc = (ALCT_CRC << 1) & 0x3ffffc;
0955           ncrc |= (t ^ (ALCT_CRC & 1)) << 1;
0956           ncrc |= t;
0957           ALCT_CRC = ncrc;
0958         }
0959       }
0960     }
0961 
0962     // == Find Correction for TMB_WordsExpected due to RPC raw hits,
0963     //    should it turn out to be the new RPC-aware format
0964     if (fTMB_Header && ((buf0[2] & 0xFFFF) == 0x6E0B)) {
0965       if (fTMB_Format2007) {
0966         /* Checks for TMB2007 firmware revisions ranges to detect data format
0967                ---------------- 
0968                * rev. code <0x4000 - TMB/OTMB firmware with changed firmware revision format
0969                *     4 bits [12:9] = Data Format Version for the unpacker (can include TMB vs. OTMB etc here)
0970                *     4 bits [8:5]  = Major Version (major features which breaks compatibility, requires changes to other board firmware) 
0971                *     5 bits [4:0]  = Minor version  (minor features, internal fixes, bug fixes, etc). 
0972                * ---------------- 
0973                * rev.0x50c3 - first revision with changed format 
0974                * rev.0x42D5 - oldest known from 06/21/2007
0975                * There is 4-bits year value rollover in revision number (0 in 2016)
0976                */
0977         if ((TMB_Firmware_Revision >= 0x50c3) || (TMB_Firmware_Revision < 0x42D5)) {
0978           bool isGEMfirmware = false;
0979           if ((TMB_Firmware_Revision < 0x4000) &&
0980               (TMB_Firmware_Revision > 0x0)) { /* New TMB firmware revision format */
0981             /* Data Format Version codes 
0982              * 0=TMB
0983              * 1=OTMB standard 
0984              * 2=OTMB+CCLUT+HMT Run3 data format
0985              * 3=OTMB+CCLUT+HMT+GEM Run3 data format
0986              */
0987             if (((TMB_Firmware_Revision >> 9) & 0x3) == 0x3)
0988               isGEMfirmware = true;
0989           }
0990 
0991           if (isGEMfirmware) {
0992             uint16_t Enabled_GEMs = 0;
0993             /* GEM output format, based on the number of enabled fibers, not yet implemented in the firmware */
0994             /*
0995             for (int i = 0; i < 4; i++)
0996               Enabled_GEMs += (buf_1[0] >> i) & 0x1;
0997              */
0998             Enabled_GEMs = 4;  // Currently always assume that all 4 fibers are enabled
0999             // Number of enabled GEM Fibers * nTimebins
1000             TMB_WordsGEM = Enabled_GEMs * ((buf_1[0] >> 5) & 0x1F) * 4;
1001             TMB_WordsGEM += 2;  // add header/trailer for block of GEM raw hits
1002           }
1003           // On/off * nRPCs * nTimebins * 2 words/RPC/bin
1004           TMB_WordsRPC = ((buf_1[0] & 0x0010) >> 4) * ((buf_1[0] & 0x000c) >> 2) * ((buf_1[0] >> 5) & 0x1F) * 2;
1005         } else  // original TMB2007 data format (may not work since TMB_Tbins != RPC_Tbins)
1006         {
1007           TMB_WordsRPC = ((buf_1[0] & 0x0040) >> 6) * ((buf_1[0] & 0x0030) >> 4) * TMB_Tbins * 2;
1008         }
1009       } else  // Old format 2006
1010       {
1011         TMB_WordsRPC = ((buf_1[2] & 0x0040) >> 6) * ((buf_1[2] & 0x0030) >> 4) * TMB_Tbins * 2;
1012       }
1013       TMB_WordsRPC += 2;  // add header/trailer for block of RPC raw hits
1014     }
1015 
1016     // Check for RPC data
1017     if (fTMB_Header && (scanbuf(buf0, 4, 0x6B04) >= 0)) {
1018       fTMB_RPC_Start = true;
1019     }
1020 
1021     // Check for GEM data
1022     if (fTMB_Header && (scanbuf(buf0, 4, 0x6C04) >= 0)) {
1023       fTMB_GEM_Start = true;
1024     }
1025 
1026     // Check for Mini-Scope data
1027     if (fTMB_Header && (scanbuf(buf0, 4, 0x6B07) >= 0)) {
1028       fTMB_MiniScope_Start = true;
1029     }
1030 
1031     // Check for Blocked CFEBs data
1032     if (fTMB_Header && (scanbuf(buf0, 4, 0x6BCB) >= 0)) {
1033       fTMB_BlockedCFEBs_Start = true;
1034     }
1035 
1036     // Check for end of RPC data
1037     if (fTMB_Header && fTMB_RPC_Start && (scanbuf(buf0, 4, 0x6E04) >= 0)) {
1038       fTMB_RPC = true;
1039     }
1040 
1041     // Check for end of GEM data
1042     if (fTMB_Header && fTMB_GEM_Start && (scanbuf(buf0, 4, 0x6D04) >= 0)) {
1043       fTMB_GEM = true;
1044     }
1045 
1046     // Check for end of Mini-Scope data
1047     if (fTMB_Header && fTMB_MiniScope_Start && (scanbuf(buf0, 4, 0x6E07) >= 0)) {
1048       fTMB_MiniScope = true;
1049     }
1050 
1051     // Check for end of Blocked CFEBs data
1052     if (fTMB_Header && fTMB_BlockedCFEBs_Start && (scanbuf(buf0, 4, 0x6ECB) >= 0)) {
1053       fTMB_BlockedCFEBs = true;
1054     }
1055 
1056     // == TMB Trailer found
1057     if (
1058         // Old TMB data format; last condition in needed not to confuse if with new ALCT data header
1059         ((buf0[0] & 0xF000) == 0xD000 && (buf0[1] & 0xF000) == 0xD000 && (buf0[2] & 0xFFFF) == 0xDE0F &&
1060          (buf0[3] & 0xF000) == 0xD000 && !fTMB_Format2007 && !(fALCT_Header && fALCT_Format2007)) ||
1061         // New TMB data format
1062         (buf0[0] == 0xDE0F && (buf0[1] & 0xF000) == 0xD000 && (buf0[2] & 0xF000) == 0xD000 &&
1063          (buf0[3] & 0xF000) == 0xD000 && fTMB_Format2007)) {
1064       // Second TMB -> Lost both previous DMB Trailer and current DMB Header
1065       if (!uniqueTMB)
1066         currentChamber = -1;
1067       // Check if this TMB record have to exist according to DMB Header
1068       if (DAV_TMB)
1069         DAV_TMB = false;
1070       else
1071         DAV_TMB = true;
1072 
1073       if (!fTMB_Header) {
1074         fERROR[13] = true;
1075         bERROR |= 0x2000;
1076         fCHAMB_ERR[13].insert(currentChamber);
1077         bCHAMB_ERR[currentChamber] |= 0x2000;
1078         fCHAMB_ERR[0].insert(currentChamber);
1079         bCHAMB_ERR[currentChamber] |= 0x1;
1080       }  // TMB Header is missing
1081 
1082       // Check calculated CRC sum against reported
1083       if (checkCrcTMB) {
1084         uint32_t crc = (fTMB_Format2007 ? buf0[1] & 0x7ff : buf0[0] & 0x7ff);
1085         crc |= ((uint32_t)((fTMB_Format2007 ? buf0[2] & 0x7ff : buf0[1] & 0x7ff))) << 11;
1086         if (TMB_CRC != crc) {
1087           fERROR[15] = true;
1088           bERROR |= 0x8000;
1089           fCHAMB_ERR[15].insert(currentChamber);
1090           bCHAMB_ERR[currentChamber] |= 0x8000;
1091           fCHAMB_ERR[0].insert(currentChamber);
1092           bCHAMB_ERR[currentChamber] |= 0x1;
1093         }
1094       }
1095 
1096       fTMB_Header = false;
1097       uniqueTMB = false;
1098       CFEB_CRC = 0;
1099       TMB_WordCount = (buf0[3] & 0x07FF);
1100 
1101       // == Correct TMB_WordsExpected
1102       //    1) for 2 optional 0x2AAA and 0x5555 Words in the Trailer
1103       //        2) for extra 4 frames in the new TMB trailer and
1104       //         for RPC raw hit data, if present
1105       //
1106       // If the scope data was enabled in readout, scope data markers (0x6B05
1107       // and 0x6E05) appear before 0x6E0C, and the optional 0x2AAA and 0x5555
1108       // trailer words are suppressed.  So far, we only have data with the
1109       // empty scope content, so more corrections will be needed once
1110       // non-empty scope data is available. -SV, 5 Nov 2008.
1111       //
1112       // If word count is not multiple of 4, add 2 optional words and
1113       // 4 trailer words.
1114 
1115       int pos = scanbuf(buf_1, 4, 0x6E0C);
1116       if (pos == 1) {
1117         TMB_WordsExpected += 6;
1118       }
1119       // If word count is multiple of 4, add 4 trailer words.
1120       else if (pos == 3) {
1121         TMB_WordsExpected += 4;
1122       }
1123 
1124       // Correct expected wordcount by RPC data size
1125       if (fTMB_RPC)
1126         TMB_WordsExpected += TMB_WordsRPC;
1127 
1128       // Correct expected wordcount by GEM data size
1129       if (fTMB_GEM)
1130         TMB_WordsExpected += TMB_WordsGEM;
1131 
1132       // Correct expected wordcount by MiniScope data size (22 words + 2 signature words)
1133       if (fTMB_MiniScope)
1134         TMB_WordsExpected += 24;
1135 
1136       // Correct expected wordcount by BlockedCFEBs data size (20 words + 2 signature words)
1137       if (fTMB_BlockedCFEBs)
1138         TMB_WordsExpected += 22;
1139 
1140       CFEB_SampleWordCount = 0;
1141 #ifdef LOCAL_UNPACK
1142       COUT << "T> ";
1143 #endif
1144     }
1145 
1146     if (fTMB_Header && checkCrcTMB) {
1147       for (uint16_t j = 0, w = 0; j < 4; ++j) {
1148         ///w = buf0[j] & 0x7fff;
1149         w = buf0[j] & (fTMB_Format2007 ? 0xffff : 0x7fff);
1150         for (uint32_t i = 15, t = 0, ncrc = 0; i < 16; i--) {
1151           t = ((w >> i) & 1) ^ ((TMB_CRC >> 21) & 1);
1152           ncrc = (TMB_CRC << 1) & 0x3ffffc;
1153           ncrc |= (t ^ (TMB_CRC & 1)) << 1;
1154           ncrc |= t;
1155           TMB_CRC = ncrc;
1156         }
1157       }
1158     }
1159 
1160     // == CFEB Sample Trailer found
1161 
1162     if (!fTMB_Header && ((buf0[1] & 0xF000) == 0x7000) && ((buf0[2] & 0xF000) == 0x7000) &&
1163         ((buf0[1] != 0x7FFF) || (buf0[2] != 0x7FFF)) &&
1164         (((buf0[3] & 0xFFFF) == 0x7FFF) ||                                 // old format
1165          ((buf0[3] & buf0[0]) == 0x0000 && (buf0[3] + buf0[0]) == 0x7FFF)  // 2007 format
1166          )) {
1167 #ifdef LOCAL_UNPACK
1168       if ((CFEB_SampleCount % 8) == 0) {
1169         COUT << " <";
1170       }
1171       if (CFEB_SampleWordCount == 100) {
1172         COUT << "+";
1173       }
1174 #endif
1175       if (CFEB_SampleWordCount != 100) {
1176 #ifdef LOCAL_UNPACK
1177         COUT << "-";
1178 #endif
1179 
1180         fERROR[16] = true;
1181         bERROR |= 0x10000;
1182         fCHAMB_ERR[16].insert(currentChamber);
1183         bCHAMB_ERR[currentChamber] |= 0x10000;
1184         fCHAMB_ERR[0].insert(currentChamber);
1185         bCHAMB_ERR[currentChamber] |= 0x1;
1186       }
1187 
1188       ++CFEB_SampleCount;
1189 
1190       if ((CFEB_SampleCount % 8) == 0) {
1191 #ifdef LOCAL_UNPACK
1192         COUT << ">";
1193 #endif
1194         CFEB_BSampleCount = 0;
1195         // Count CFEBs
1196         DAV_CFEB--;
1197       }
1198 
1199       // Check calculated CRC sum against reported
1200       if (checkCrcCFEB && CFEB_CRC != buf0[0]) {
1201         fERROR[18] = true;
1202         bERROR |= 0x40000;
1203         fCHAMB_ERR[18].insert(currentChamber);
1204         bCHAMB_ERR[currentChamber] |= 0x40000;
1205         fCHAMB_ERR[0].insert(currentChamber);
1206         bCHAMB_ERR[currentChamber] |= 0x1;
1207       }
1208 
1209       CFEB_CRC = 0;
1210       CFEB_SampleWordCount = 0;
1211     }
1212 
1213     // == CFEB B-word found
1214     if (!fTMB_Header && (buf0[0] & 0xF000) == 0xB000 && (buf0[1] & 0xF000) == 0xB000 && (buf0[2] & 0xF000) == 0xB000 &&
1215         (buf0[3] & 0xF000) == 0xB000) {
1216       bCHAMB_STATUS[currentChamber] |= 0x400000;
1217 
1218 #ifdef LOCAL_UNPACK
1219       if ((CFEB_SampleCount % 8) == 0) {
1220         COUT << " <";
1221       }
1222       COUT << "B";
1223 #endif
1224 
1225       ++CFEB_SampleCount;
1226       ++CFEB_BSampleCount;
1227 
1228       if ((CFEB_SampleCount % 8) == 0) {
1229 #ifdef LOCAL_UNPACK
1230         COUT << ">";
1231 #endif
1232         CFEB_BSampleCount = 0;
1233         DAV_CFEB--;
1234       }
1235 
1236       CFEB_SampleWordCount = 0;
1237     }
1238 
1239     // == If it is neither ALCT record nor TMB - probably it is CFEB record and we try to count CRC sum.
1240     // It very few words of CFEB occasionaly will be misinterpreted as ALCT or TMB header the result
1241     // for the CRC sum will be wrong, but other errors of Trailers counting will appear as well
1242     if (checkCrcCFEB && fDMB_Header && !fTMB_Header && !fALCT_Header && CFEB_SampleWordCount)
1243       for (int pos = 0; pos < 4; ++pos)
1244         CFEB_CRC = (buf0[pos] & 0x1fff) ^ ((buf0[pos] & 0x1fff) << 1) ^
1245                    (((CFEB_CRC & 0x7ffc) >> 2) | ((0x0003 & CFEB_CRC) << 13)) ^ ((CFEB_CRC & 0x7ffc) >> 1);
1246 
1247     // == DMB F-Trailer found
1248     if ((buf0[0] & 0xF000) == 0xF000 && (buf0[1] & 0xF000) == 0xF000 && (buf0[2] & 0xF000) == 0xF000 &&
1249         (buf0[3] & 0xF000) == 0xF000) {
1250       if (!fDMB_Header) {
1251         currentChamber = buf0[3] & 0x0FFF;
1252         fERROR[6] = true;
1253         bERROR |= 0x40;
1254         fCHAMB_ERR[6].insert(currentChamber);
1255         bCHAMB_ERR[currentChamber] |= 0x40;
1256         nDMBs++;
1257         // Set variables if we are waiting ALCT, TMB and CFEB records to be present in event
1258         if (buf0[0] & 0x0400)
1259           bCHAMB_PAYLOAD[currentChamber] |= 0x20;
1260         if (buf0[0] & 0x0800)
1261           bCHAMB_PAYLOAD[currentChamber] |= 0x40;
1262         bCHAMB_PAYLOAD[currentChamber] |= (buf0[0] & 0x001f) << 7;
1263         bCHAMB_PAYLOAD[currentChamber] |= ((buf0[0] >> 5) & 0x1f);
1264 
1265       }  // DMB Header is missing
1266       fDMB_Header = false;
1267       fDMB_Trailer = true;
1268       uniqueALCT = true;
1269       uniqueTMB = true;
1270 
1271       dmbSize[sourceID][currentChamber] = buf0 - dmbBuffers[sourceID][currentChamber];
1272 
1273       // Finally check if DAVs were correct
1274       checkDAVs();
1275 
1276       // If F-Trailer is lost then do necessary work here
1277       if ((buf1[0] & 0xF000) != 0xE000 || (buf1[1] & 0xF000) != 0xE000 || (buf1[2] & 0xF000) != 0xE000 ||
1278           (buf1[3] & 0xF000) != 0xE000) {
1279         for (int err = 1; err < nERRORS; ++err)
1280           if (fCHAMB_ERR[err].find(currentChamber) != fCHAMB_ERR[err].end()) {
1281             fCHAMB_ERR[0].insert(currentChamber);
1282             bCHAMB_ERR[currentChamber] |= 0x1;
1283           }
1284         // Reset chamber id
1285         currentChamber = -1;
1286         /*
1287                 for(int err=0; err<nERRORS; err++)
1288                 if( fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end() )
1289                 fCHAMB_ERR[err].erase(-1);
1290                 bCHAMB_ERR[-1] = 0;
1291                 bCHAMB_WRN[-1] = 0;
1292               */
1293       }
1294 #ifdef LOCAL_UNPACK
1295       // Print DMB F-Trailer marker
1296       COUT << " }";
1297 #endif
1298     }
1299 
1300     // == DMB E-Trailer found
1301     if ((buf0[0] & 0xF000) == 0xE000 && (buf0[1] & 0xF000) == 0xE000 && (buf0[2] & 0xF000) == 0xE000 &&
1302         (buf0[3] & 0xF000) == 0xE000) {
1303       if (!fDMB_Header && !fDMB_Trailer)
1304         nDMBs++;  // both DMB Header and DMB F-Trailer were missing
1305 
1306       if (fFormat2013)  /// 2013 Data format
1307       {
1308         ///!!! Put correct bits positions
1309         bCHAMB_STATUS[currentChamber] |= (buf0[0] & 0x0800) >> 11;  /// ALCT FIFO FULL
1310         bCHAMB_STATUS[currentChamber] |= (buf0[0] & 0x0400) >> 9;   /// TMB FIFO Full
1311         bCHAMB_STATUS[currentChamber] |= (buf0[0] & 0x0080) << 8;   /// TMB End Timeout
1312 
1313         if (fDMB_Trailer)  // F-Trailer exists
1314         {
1315           bCHAMB_STATUS[currentChamber] |= (buf_1[2] & 0x0E00) >> 7;   /// CFEB 1-3 FIFO Full
1316           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x0003) << 3;   /// CFEB 4-5 FIFO Full
1317           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x000C) << 21;  /// CFEB 6-7 FIFO Full
1318           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x0800) >> 4;   /// ALCT Start Timeout
1319           bCHAMB_STATUS[currentChamber] |= (buf_1[2] & 0x0100);        /// TMB Start Timeout
1320           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x01f0) << 5;   /// CFEB 1-5 Start Timeout
1321           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x0600) << 16;  /// CFEB 6-7 Start Timeout
1322           bCHAMB_STATUS[currentChamber] |= (buf_1[0] & 0x0800) << 3;   /// ALCT End Timeout
1323           bCHAMB_STATUS[currentChamber] |= (buf_1[1] & 0x001f) << 16;  /// CFEB 1-5 End Timeout
1324           bCHAMB_STATUS[currentChamber] |= (buf_1[1] & 0x0060) << 21;  /// CFEB 6-7 End Timeout
1325         }
1326 
1327       } else {
1328         bCHAMB_STATUS[currentChamber] |= (buf0[0] & 0x0800) >> 11;  /// ALCT FIFO FULL
1329         bCHAMB_STATUS[currentChamber] |= (buf0[0] & 0x0400) >> 9;   /// TMB FIFO Full
1330         bCHAMB_STATUS[currentChamber] |= (buf0[0] & 0x03E0) >> 3;   /// CFEB 1-5 FIFO Full
1331 
1332         if (fDMB_Trailer)  // F-Trailer exists
1333         {
1334           bCHAMB_STATUS[currentChamber] |= (buf_1[2] & 0x0002) << 6;   /// ALCT Start Timeout
1335           bCHAMB_STATUS[currentChamber] |= (buf_1[2] & 0x0001) << 8;   /// TMB Start Timeout
1336           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x001f) << 9;   /// CFEB 1-5 Start Timeout
1337           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x0040) << 8;   /// ALCT End Timeout
1338           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x0020) << 10;  /// TMB End Timeout
1339           bCHAMB_STATUS[currentChamber] |= (buf_1[3] & 0x0f80) << 9;   /// CFEB 1-5 End Timeout
1340         }
1341       }
1342       fDMB_Header = false;
1343 
1344       // If chamber id is unknown it is time to find it out
1345       if (currentChamber == -1) {
1346         currentChamber = buf0[1] & 0x0FFF;
1347         for (int err = 0; err < nERRORS; ++err)
1348           if (fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end()) {
1349             fCHAMB_ERR[err].insert(currentChamber);
1350             fCHAMB_ERR[err].erase(-1);
1351           }
1352         bCHAMB_STATUS[currentChamber] = bCHAMB_STATUS[-1];
1353         bCHAMB_STATUS[-1] = 0;
1354         bCHAMB_ERR[currentChamber] = bCHAMB_ERR[-1];
1355         bCHAMB_ERR[-1] = 0;
1356         bCHAMB_WRN[currentChamber] = bCHAMB_WRN[-1];
1357         bCHAMB_WRN[-1] = 0;
1358       }
1359       ++cntCHAMB_Trailers[buf0[1] & 0x0FFF];
1360 
1361       dmbSize[sourceID][currentChamber] = buf0 - dmbBuffers[sourceID][currentChamber];
1362 
1363       // Lost DMB F-Trailer before
1364       if (!fDMB_Trailer) {
1365         fERROR[6] = true;
1366         bERROR |= 0x40;
1367         fCHAMB_ERR[6].insert(currentChamber);
1368         bCHAMB_ERR[currentChamber] |= 0x40;
1369         fCHAMB_ERR[0].insert(currentChamber);
1370         bCHAMB_ERR[currentChamber] |= 0x1;
1371         // Check if DAVs were correct here
1372         checkDAVs();
1373       }
1374       fDMB_Trailer = false;
1375 
1376 #ifdef LOCAL_UNPACK
1377       // Print DMB E-Trailer marker
1378       COUT << " DMB=" << (buf0[1] & 0x000F);
1379       COUT << "; " << ALCT_WordsSinceLastHeader << "-" << ALCT_WordCount << "-" << ALCT_WordsExpected << "      "
1380            << TMB_WordsSinceLastHeader << "-" << TMB_WordCount << "-" << TMB_WordsExpected << endl;
1381 #endif
1382 
1383       checkTriggerHeadersAndTrailers();
1384 
1385       //
1386       for (int err = 0; err < nERRORS; ++err)
1387         if (fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end()) {
1388           fCHAMB_ERR[err].erase(-1);
1389           fCHAMB_ERR[err].insert(-2);
1390         }
1391       bCHAMB_STATUS[-2] |= bCHAMB_STATUS[-1];
1392       bCHAMB_STATUS[-1] = 0;
1393       bCHAMB_ERR[-2] |= bCHAMB_ERR[-1];
1394       bCHAMB_ERR[-1] = 0;
1395       bCHAMB_WRN[-2] |= bCHAMB_WRN[-1];
1396       bCHAMB_WRN[-1] = 0;
1397 
1398       if (currentChamber != -1)
1399         for (int err = 1; err < nERRORS; ++err)
1400           if (fCHAMB_ERR[err].find(currentChamber) != fCHAMB_ERR[err].end()) {
1401             fCHAMB_ERR[0].insert(currentChamber);
1402             bCHAMB_ERR[currentChamber] |= 0x1;
1403           }
1404 
1405       currentChamber = -1;
1406 #ifdef LOCAL_UNPACK
1407       /*
1408                 // Print DMB E-Trailer marker
1409                 COUT<<" DMB="<<(buf0[1]&0x000F);
1410                 COUT << "; "
1411                << ALCT_WordsSinceLastHeader << "-"
1412                << ALCT_WordCount << "-"
1413                << ALCT_WordsExpected
1414                << "      "
1415                << TMB_WordsSinceLastHeader << "-"
1416                << TMB_WordCount << "-"
1417                << TMB_WordsExpected
1418                << endl;
1419           */
1420 #endif
1421     }
1422 
1423     // == DDU Trailer found
1424     if (buf0[0] == 0x8000 && buf0[1] == 0x8000 && buf0[2] == 0xFFFF && buf0[3] == 0x8000) {
1425       /////////////////////////////////////////////////////////
1426       checkDAVs();
1427 
1428       checkTriggerHeadersAndTrailers();
1429 
1430       /////////////////////////////////////////////////////////
1431 
1432       if (DDU_WordsSinceLastHeader > 3 && !nDMBs) {
1433         fERROR[28] = true;
1434         bERROR |= 0x10000000;
1435         ;
1436       }
1437 
1438       if (fDDU_Trailer) {
1439         fERROR[2] = true;
1440         bERROR |= 0x4;
1441       }  // DDU Header is missing
1442       fDDU_Trailer = true;
1443       fDDU_Header = false;
1444 
1445       if (fDMB_Header || fDMB_Trailer) {
1446 #ifdef LOCAL_UNPACK
1447         COUT << " Ex-Err: DMB (Header, Trailer) " << std::endl;
1448 #endif
1449         fERROR[5] = true;
1450         bERROR |= 0x20;
1451         fCHAMB_ERR[5].insert(currentChamber);
1452         bCHAMB_ERR[currentChamber] |= 0x20;
1453         fCHAMB_ERR[0].insert(currentChamber);
1454         bCHAMB_ERR[currentChamber] |= 0x20;
1455       }  // DMB Trailer is missing
1456       fDMB_Header = false;
1457       fDMB_Trailer = false;
1458 
1459       currentChamber = -1;
1460 
1461       for (int err = 0; err < nERRORS; ++err)
1462         if (fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end()) {
1463           fCHAMB_ERR[err].erase(-1);
1464           fCHAMB_ERR[err].insert(-2);
1465         }
1466       bCHAMB_STATUS[-2] |= bCHAMB_STATUS[-1];
1467       bCHAMB_STATUS[-1] = 0;
1468       bCHAMB_ERR[-2] |= bCHAMB_ERR[-1];
1469       bCHAMB_ERR[-1] = 0;
1470       bCHAMB_WRN[-2] |= bCHAMB_WRN[-1];
1471       bCHAMB_WRN[-1] = 0;
1472 
1473       for (int err = 1; err < nERRORS; ++err)
1474         if (fCHAMB_ERR[err].find(-2) != fCHAMB_ERR[err].end()) {
1475           fCHAMB_ERR[0].insert(-2);
1476           bCHAMB_ERR[-2] |= 0x1;
1477         }
1478 
1479       dduSize[sourceID] = buf0 - dduBuffers[sourceID];
1480 
1481       ++cntDDU_Trailers;  // Increment DDUTrailer counter
1482 
1483       // == Combining 2 words into 24bit value
1484       DDU_WordCount = buf2[2] | ((buf2[3] & 0xFF) << 16);
1485 
1486       if ((DDU_WordsSinceLastHeader + 4) != DDU_WordCount) {
1487         fERROR[4] = true;
1488         bERROR |= 0x10;
1489       }
1490 
1491       if (DMB_Active != nDMBs) {
1492         fERROR[24] = true;
1493         bERROR |= 0x1000000;
1494       }
1495 
1496 #ifdef LOCAL_UNPACK
1497       COUT << "DDU Trailer Occurrence " << cntDDU_Trailers << endl;
1498       COUT << "----------------------------------------------------------" << endl;
1499       COUT << "DDU 64-bit words = Actual - DDUcounted =" << DDU_WordsSinceLastHeader + 4 << "-" << DDU_WordCount
1500            << endl;
1501 #endif
1502 
1503       // increment statistics Errors and Warnings (i=0 case is handled in DDU Header)
1504       for (int err = 1; err < nERRORS; ++err) {
1505         if (fERROR[err]) {
1506           fERROR[0] = true;
1507           bERROR |= 0x1;
1508 #ifdef LOCAL_UNPACK
1509           CERR << "\nDDU Header Occurrence = " << cntDDU_Headers;
1510           CERR << "  ERROR " << err << "  " << sERROR[err] << endl;
1511 #endif
1512         }
1513       }
1514 
1515 #ifdef LOCAL_UNPACK
1516       for (int wrn = 1; wrn < nWARNINGS; ++wrn) {
1517         if (fWARNING[wrn]) {
1518           COUT << "\nDDU Header Occurrence = " << cntDDU_Headers;
1519           COUT << "  WARNING " << wrn << "  " << sWARNING[wrn] << endl;
1520         }
1521       }
1522 #endif
1523 
1524       bDDU_ERR[sourceID] |= bERROR;
1525       bDDU_WRN[sourceID] |= bWARNING;
1526       sync_stats();
1527 
1528       DDU_WordsSinceLastHeader = 0;
1529       DDU_WordsSinceLastTrailer = 0;
1530       if (modeDDUonly) {
1531         buffer += 4;
1532         buf_1 = &(tmpbuf[0]);  // Just for safety
1533         buf0 = &(tmpbuf[4]);   // Just for safety
1534         buf1 = &(tmpbuf[8]);   // Just for safety
1535         buf2 = &(tmpbuf[12]);  // Just for safety
1536         bzero(tmpbuf, sizeof(uint16_t) * 16);
1537         return length - 4;
1538       }
1539     }
1540 
1541     if (!modeDDUonly) {
1542       // DCC Trailer 1 && DCC Trailer 2
1543       // =VB= Added support for Sep. 2008 CMS DAQ DCC format
1544       // =VB= 04.18.09 Removed (buf2[0]&0x0003) == 0x3 check for old DCC format to satisfy older format of simulated data
1545       if ((buf1[3] & 0xFF00) == 0xEF00 &&
1546           (((buf2[3] & 0xFF00) == 0xAF00) || ((buf2[3] & 0xFF00) == 0xA000 && (buf2[0] & 0x0003) == 0x0))) {
1547         // =VB= Added check that there is no DCCHeader detected to set missing DCC Header error
1548         if (!fDCC_Header || fDCC_Trailer) {
1549           fERROR[26] = true;
1550           bERROR |= 0x4000000;
1551           fERROR[0] = true;
1552           bERROR |= 0x1;
1553         }  // DCC Header is missing
1554         fDCC_Trailer = true;
1555         fDCC_Header = false;
1556 
1557         if (fDDU_Header) {
1558           // == DDU Trailer is missing
1559           fERROR[1] = true;
1560           bERROR |= 0x2;
1561           fERROR[0] = true;
1562           bERROR |= 0x1;
1563         }
1564 
1565         buffer += 4;
1566         buf_1 = &(tmpbuf[0]);  // Just for safety
1567         buf0 = &(tmpbuf[4]);   // Just for safety
1568         buf1 = &(tmpbuf[8]);   // Just for safety
1569         buf2 = &(tmpbuf[12]);  // Just for safety
1570         bzero(tmpbuf, sizeof(uint16_t) * 16);
1571         sync_stats();
1572         return length - 4;
1573       }
1574     }
1575 
1576     length -= 4;
1577     buffer += 4;
1578   }
1579   //Store the tail of the buffer
1580   buf_1 = &(tmpbuf[0]);
1581   buf0 = &(tmpbuf[4]);
1582   buf1 = &(tmpbuf[8]);
1583   buf2 = &(tmpbuf[12]);
1584   memcpy((void*)tmpbuf, (void*)(buffer - 16), sizeof(short) * 16);
1585 
1586   if (!modeDDUonly && !fDCC_Trailer && !fDCC_Header) {
1587     fERROR[26] = true;
1588     bERROR |= 0x4000000;
1589     fERROR[25] = true;
1590     bERROR |= 0x2000000;
1591     fERROR[0] = true;
1592     bERROR |= 0x1;
1593     sync_stats();
1594     return length;
1595   }
1596 
1597   return -2;
1598 }
1599 
1600 void CSCDCCExaminer::clear() {
1601   bzero(fERROR, sizeof(bool) * nERRORS);
1602   bzero(fWARNING, sizeof(bool) * nWARNINGS);
1603   bzero(fSUM_ERROR, sizeof(bool) * nERRORS);
1604   bzero(fSUM_WARNING, sizeof(bool) * nWARNINGS);
1605   bERROR = 0;
1606   bWARNING = 0;
1607   bSUM_ERROR = 0;
1608   bSUM_WARNING = 0;
1609   for (int err = 0; err < nERRORS; ++err)
1610     fCHAMB_ERR[err].clear();
1611   for (int wrn = 0; wrn < nWARNINGS; ++wrn)
1612     fCHAMB_WRN[wrn].clear();
1613   bCHAMB_ERR.clear();
1614   bCHAMB_WRN.clear();
1615   bCHAMB_PAYLOAD.clear();
1616   bCHAMB_STATUS.clear();
1617   bDDU_ERR.clear();
1618   bDDU_WRN.clear();
1619   dduBuffers.clear();
1620   dduOffsets.clear();
1621   dmbBuffers.clear();
1622   dmbOffsets.clear();
1623   dduSize.clear();
1624   dmbSize.clear();
1625 }
1626 
1627 void CSCDCCExaminer::zeroCounts() {
1628   ALCT_WordsSinceLastHeader = 0;
1629   ALCT_WordsSinceLastHeaderZeroSuppressed = 0;
1630   ALCT_WordCount = 0;
1631   ALCT_WordsExpected = 0;
1632   ALCT_WordsBeforeRaw = 0;
1633   ALCT_ZSE = 0;
1634   TMB_WordsSinceLastHeader = 0;
1635   TMB_WordCount = 0;
1636   TMB_WordsExpected = 0;
1637   TMB_Tbins = 0;
1638   CFEB_SampleWordCount = 0;
1639   CFEB_SampleCount = 0;
1640   CFEB_BSampleCount = 0;
1641 }
1642 
1643 void CSCDCCExaminer::checkDAVs() {
1644   if (DAV_ALCT) {
1645     fERROR[21] = true;
1646     bERROR |= 0x200000;
1647     fCHAMB_ERR[21].insert(currentChamber);
1648     bCHAMB_ERR[currentChamber] |= 0x200000;
1649     DAV_ALCT = false;
1650   }
1651   if (DAV_TMB) {
1652     fERROR[22] = true;
1653     bERROR |= 0x400000;
1654     fCHAMB_ERR[22].insert(currentChamber);
1655     bCHAMB_ERR[currentChamber] |= 0x400000;
1656     DAV_TMB = false;
1657   }
1658   if (DAV_CFEB && DAV_CFEB != -16) {
1659     fERROR[23] = true;
1660     bERROR |= 0x800000;
1661     fCHAMB_ERR[23].insert(currentChamber);
1662     bCHAMB_ERR[currentChamber] |= 0x800000;
1663     DAV_CFEB = 0;
1664   }
1665 }
1666 
1667 void CSCDCCExaminer::checkTriggerHeadersAndTrailers() {
1668 #ifdef LOCAL_UNPACK
1669   /*
1670   COUT << " Ex-ALCT-Word-count " << std::endl;
1671   COUT << " ALCT Words Since Last Header: " <<  ALCT_WordsSinceLastHeader << std::endl;
1672   COUT << " ALCT Word Count: " <<  ALCT_WordCount << std::endl;
1673   COUT << " ALCT Words Expected: " << ALCT_WordsExpected << std::endl;
1674   */
1675 #endif
1676   if (!fALCT_Header &&
1677       (ALCT_WordsSinceLastHeader != ALCT_WordCount || ALCT_WordsSinceLastHeader != ALCT_WordsExpected) &&
1678       ALCT_ZSE == 0) {
1679     fERROR[9] = true;
1680     bERROR |= 0x200;
1681     fCHAMB_ERR[9].insert(currentChamber);
1682     bCHAMB_ERR[currentChamber] |= 0x200;
1683     ALCT_WordsSinceLastHeader = 0;
1684     ALCT_WordCount = 0;
1685     ALCT_WordsSinceLastHeader = 0;
1686     ALCT_WordsExpected = 0;
1687     ALCT_WordsBeforeRaw = 0;
1688   }  // ALCT Word Count Error
1689 
1690   if (!fALCT_Header &&
1691       (ALCT_WordsSinceLastHeader != ALCT_WordsExpected || ALCT_WordsSinceLastHeaderZeroSuppressed != ALCT_WordCount) &&
1692       ALCT_ZSE != 0) {
1693     fERROR[9] = true;
1694     bERROR |= 0x200;
1695     fCHAMB_ERR[9].insert(currentChamber);
1696     bCHAMB_ERR[currentChamber] |= 0x200;
1697     ALCT_WordsSinceLastHeaderZeroSuppressed = 0;
1698     ALCT_WordsSinceLastHeader = 0;
1699     ALCT_WordCount = 0;
1700     ALCT_WordsSinceLastHeader = 0;
1701     ALCT_WordsExpected = 0;
1702     ALCT_WordsBeforeRaw = 0;
1703   }  // ALCT Word Count Error With zero suppression
1704 
1705   if (!fTMB_Header && (TMB_WordsSinceLastHeader != TMB_WordCount || TMB_WordsSinceLastHeader != TMB_WordsExpected)) {
1706     fERROR[14] = true;
1707     bERROR |= 0x4000;
1708     fCHAMB_ERR[14].insert(currentChamber);
1709     bCHAMB_ERR[currentChamber] |= 0x4000;
1710     TMB_WordsSinceLastHeader = 0;
1711     TMB_WordCount = 0;
1712     TMB_WordsSinceLastHeader = 0;
1713     TMB_WordsExpected = 0;
1714   }  // TMB Word Count Error
1715 
1716   if ((CFEB_SampleCount % 8) != 0) {
1717     fERROR[17] = true;
1718     bERROR |= 0x20000;
1719     fCHAMB_ERR[17].insert(currentChamber);
1720     bCHAMB_ERR[currentChamber] |= 0x20000;
1721     CFEB_SampleCount = 0;
1722   }  // Number of CFEB samples != 8*n
1723 
1724   if (fALCT_Header) {
1725     fERROR[7] = true;  // ALCT Trailer is missing
1726     bERROR |= 0x80;
1727     fCHAMB_ERR[7].insert(currentChamber);
1728     bCHAMB_ERR[currentChamber] |= 0x80;
1729     ALCT_WordsSinceLastHeaderZeroSuppressed = 0;
1730     ALCT_WordsSinceLastHeader = 0;
1731     ALCT_WordsExpected = 0;
1732     ALCT_WordsBeforeRaw = 0;
1733     fALCT_Header = false;
1734   }
1735 
1736   if (fTMB_Header) {
1737     fERROR[12] = true;  // TMB Trailer is missing
1738     bERROR |= 0x1000;
1739     fCHAMB_ERR[12].insert(currentChamber);
1740     bCHAMB_ERR[currentChamber] |= 0x1000;
1741     TMB_WordsSinceLastHeader = 0;
1742     TMB_WordsExpected = 0;
1743     fTMB_Header = false;
1744   }
1745 }
1746 
1747 inline void CSCDCCExaminer::sync_stats() {
1748   for (int err = 0; err < nERRORS; ++err)
1749     fSUM_ERROR[err] |= fERROR[err];
1750   for (int wrn = 0; wrn < nWARNINGS; ++wrn)
1751     fSUM_WARNING[wrn] |= fWARNING[wrn];
1752   bSUM_ERROR |= bERROR;
1753   bSUM_WARNING |= bWARNING;
1754 }
1755 
1756 inline int CSCDCCExaminer::scanbuf(const uint16_t*& buffer, int32_t length, uint16_t sig, uint16_t mask) {
1757   for (int i = 0; i < length; i++) {
1758     if ((buffer[i] & mask) == sig) {
1759       return i;
1760     }
1761   }
1762   return -1;
1763 }