CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/EventFilter/CSCRawToDigi/src/CSCDCCExaminer.cc

Go to the documentation of this file.
00001 #include "EventFilter/CSCRawToDigi/interface/CSCDCCExaminer.h"
00002 #include <string.h>
00003 #include <iomanip>
00004 using namespace std;
00005 
00006 void CSCDCCExaminer::crcALCT(bool enable){
00007   checkCrcALCT = enable;
00008   if( checkCrcALCT )
00009     sERROR[10] = "ALCT CRC Error                                   ";
00010   else
00011     sERROR[10] = "ALCT CRC Error ( disabled )                      ";
00012 }
00013 
00014 void CSCDCCExaminer::crcTMB(bool enable){
00015   checkCrcTMB = enable;
00016   if( checkCrcTMB )
00017     sERROR[15] = "TMB CRC Error                                    ";
00018   else
00019     sERROR[15] = "TMB CRC Error ( disabled )                       ";
00020 }
00021 
00022 void CSCDCCExaminer::crcCFEB(bool enable){
00023   checkCrcCFEB = enable;
00024   if( checkCrcCFEB )
00025     sERROR[18] = "CFEB CRC Error                                   ";
00026   else
00027     sERROR[18] = "CFEB CRC Error ( disabled )                      ";
00028 }
00029 
00030 void CSCDCCExaminer::modeDDU(bool enable){
00031   modeDDUonly = enable;
00032   if( modeDDUonly) {
00033     sERROR[25] = "DCC Trailer Missing                              ";
00034     sERROR[26] = "DCC Header Missing                               ";
00035   } else {
00036     sERROR[25] = "DCC Trailer Missing (disabled)                   ";
00037     sERROR[26] = "DCC Header Missing (disabled)                    ";
00038   }
00039 
00040 }
00041 
00042 
00043 CSCDCCExaminer::CSCDCCExaminer(ExaminerMaskType mask):nERRORS(29),nWARNINGS(5),nPAYLOADS(12),nSTATUSES(23),sERROR(nERRORS),sWARNING(nWARNINGS),sERROR_(nERRORS),sWARNING_(nWARNINGS),sDMBExpectedPayload(nPAYLOADS),sDMBEventStaus(nSTATUSES),examinerMask(mask){
00044   cout.redirect(std::cout); cerr.redirect(std::cerr);
00045 
00046   sERROR[0] = " Any errors                                       ";
00047   sERROR[1] = " DDU Trailer Missing                              ";
00048   sERROR[2] = " DDU Header Missing                               ";
00049   sERROR[3] = " DDU CRC Error (not yet implemented)              ";
00050   sERROR[4] = " DDU Word Count Error                             ";
00051   sERROR[5] = " DMB Trailer Missing                              ";
00052   sERROR[6] = " DMB Header Missing                               ";
00053   sERROR[7] = " ALCT Trailer Missing                             ";
00054   sERROR[8] = " ALCT Header Missing                              ";
00055   sERROR[9] = " ALCT Word Count Error                            ";
00056   sERROR[10] = "ALCT CRC Error                                   ";
00057   sERROR[11] = "ALCT Trailer Bit Error                           ";
00058   // ^^^ This is due to seeing many events in ddu293 (also, some in ddu294)
00059   // with some bits in the 1st ALCT D-Header being lost. This causes a chain of errors:
00060   // - TMB Trailer is not identified and TMB word count mismatch occur when Trailer is found
00061   // - CFEB sample count is not reset on ALCT Trailer.
00062   // To merge all these errors in one,
00063   // the D-signature in the 1st ALCT Trailer will not be required for identifying the ALCT Trailer;
00064   // However, if these bits are found to be missing, ERROR[11] will be flagged.
00065   // This is just a temporary patch to make the output look less clattered.
00066   sERROR[12] = "TMB Trailer Missing                              ";
00067   sERROR[13] = "TMB Header Missing                               ";
00068   sERROR[14] = "TMB Word Count Error                             ";
00069   sERROR[15] = "TMB CRC Error                                    ";
00070   sERROR[16] = "CFEB Word Count Per Sample Error                 ";
00071   sERROR[17] = "CFEB Sample Count Error                          ";
00072   sERROR[18] = "CFEB CRC Error                                   ";
00073   sERROR[19] = "DDU Event Size Limit Error                       ";
00074   sERROR[20] = "C-Words                                          ";
00075   sERROR[21] = "ALCT DAV Error                                   ";
00076   sERROR[22] = "TMB DAV Error                                    ";
00077   sERROR[23] = "CFEB DAV Error                                   ";
00078   sERROR[24] = "DMB Active Error                                 ";
00079   sERROR[25] = "DCC Trailer Missing                              ";
00080   sERROR[26] = "DCC Header Missing                               ";
00081   sERROR[27] = "DMB DAV vs. DMB Active mismatch Error            ";
00082   sERROR[28] = "Extra words between DDU Header and first DMB header";
00083 
00084   //    sERROR[21] = "DDU Header vs. Trailer mismatch for DAV or Avtive"; // oboslete since 16.09.05
00085 
00086   sWARNING[0] = " Extra words between DDU Trailer and DDU Header ";
00087   sWARNING[1] = " DDU Header Incomplete                          ";
00088 
00089   sDMBExpectedPayload[0]  = "CFEB1_ACTIVE";
00090   sDMBExpectedPayload[1]  = "CFEB2_ACTIVE";
00091   sDMBExpectedPayload[2]  = "CFEB3_ACTIVE";
00092   sDMBExpectedPayload[3]  = "CFEB4_ACTIVE";
00093   sDMBExpectedPayload[4]  = "CFEB5_ACTIVE";
00094   sDMBExpectedPayload[5]  = "ALCT_DAV";
00095   sDMBExpectedPayload[6]  = "TMB_DAV";
00096   sDMBExpectedPayload[7]  = "CFEB1_DAV";
00097   sDMBExpectedPayload[8]  = "CFEB2_DAV";
00098   sDMBExpectedPayload[9]  = "CFEB3_DAV";
00099   sDMBExpectedPayload[10] = "CFEB4_DAV";
00100   sDMBExpectedPayload[11] = "CFEB5_DAV";
00101 
00102   sDMBEventStaus[0]  = "ALCT_FIFO_FULL";
00103   sDMBEventStaus[1]  = "TMB_FIFO_FULL";
00104   sDMBEventStaus[2]  = "CFEB1_FIFO_FULL";
00105   sDMBEventStaus[3]  = "CFEB2_FIFO_FULL";
00106   sDMBEventStaus[4]  = "CFEB3_FIFO_FULL";
00107   sDMBEventStaus[5]  = "CFEB4_FIFO_FULL";
00108   sDMBEventStaus[6]  = "CFEB5_FIFO_FULL";
00109   sDMBEventStaus[7]  = "ALCT_START_TIMEOUT";
00110   sDMBEventStaus[8]  = "TMB_START_TIMEOUT";
00111   sDMBEventStaus[9]  = "CFEB1_START_TIMEOUT";
00112   sDMBEventStaus[10] = "CFEB2_START_TIMEOUT";
00113   sDMBEventStaus[11] = "CFEB3_START_TIMEOUT";
00114   sDMBEventStaus[12] = "CFEB4_START_TIMEOUT";
00115   sDMBEventStaus[13] = "CFEB5_START_TIMEOUT";
00116   sDMBEventStaus[14] = "ALCT_END_TIMEOUT";
00117   sDMBEventStaus[15] = "TMB_END_TIMEOUT";
00118   sDMBEventStaus[16] = "CFEB1_END_TIMEOUT";
00119   sDMBEventStaus[17] = "CFEB2_END_TIMEOUT";
00120   sDMBEventStaus[18] = "CFEB3_END_TIMEOUT";
00121   sDMBEventStaus[19] = "CFEB4_END_TIMEOUT";
00122   sDMBEventStaus[20] = "CFEB5_END_TIMEOUT";
00123   sDMBEventStaus[21] = "CFEB Active-DAV mismatch";
00124   sDMBEventStaus[22] = "B-words found";
00125 
00126   sERROR_[0] = " Any errors: 00";
00127   sERROR_[1] = " DDU Trailer Missing: 01";
00128   sERROR_[2] = " DDU Header Missing: 02";
00129   sERROR_[3] = " DDU CRC Error (not yet implemented): 03";
00130   sERROR_[4] = " DDU Word Count Error: 04";
00131   sERROR_[5] = " DMB Trailer Missing: 05";
00132   sERROR_[6] = " DMB Header Missing: 06";
00133   sERROR_[7] = " ALCT Trailer Missing: 07";
00134   sERROR_[8] = " ALCT Header Missing: 08";
00135   sERROR_[9] = " ALCT Word Count Error: 09";
00136   sERROR_[10] = "ALCT CRC Error: 10";
00137   sERROR_[11] = "ALCT Trailer Bit Error: 11";
00138   sERROR_[12] = "TMB Trailer Missing: 12";
00139   sERROR_[13] = "TMB Header Missing: 13";
00140   sERROR_[14] = "TMB Word Count Error: 14";
00141   sERROR_[15] = "TMB CRC Error: 15";
00142   sERROR_[16] = "CFEB Word Count Per Sample Error: 16";
00143   sERROR_[17] = "CFEB Sample Count Error: 17";
00144   sERROR_[18] = "CFEB CRC Error: 18";
00145   sERROR_[19] = "DDU Event Size Limit Error: 19";
00146   sERROR_[20] = "C-Words: 20";
00147   sERROR_[21] = "ALCT DAV Error: 21";
00148   sERROR_[22] = "TMB DAV Error: 22";
00149   sERROR_[23] = "CFEB DAV Error: 23";
00150   sERROR_[24] = "DMB Active Error: 24";
00151   sERROR_[25] = "DCC Trailer Missing: 25";
00152   sERROR_[26] = "DCC Header Missing: 26";
00153   sERROR_[27] = "DMB DAV vs. DMB Active mismatch Error: 27";
00154   sERROR_[28] = "Extra words between DDU Header and first DMB header: 28";
00155   //    sERROR_[21] = "DDU Header vs. Trailer mismatch for DAV or Avtive: 21"; // oboslete since 16.09.05
00156 
00157   sWARNING_[0] = " Extra words between DDU Trailer and DDU Header: 00";
00158   sWARNING_[1] = " DDU Header Incomplete: 02";
00159 
00160   fDCC_Header  = false;
00161   fDCC_Trailer = false;
00162   fDDU_Header  = false;
00163   fDDU_Trailer = false;
00164   fDMB_Header  = false;
00165   fDMB_Trailer = false;
00166   fALCT_Header = false;
00167   fTMB_Header  = false;
00168   fALCT_Format2007 = true;
00169   fTMB_Format2007  = true;
00170 
00171   cntDDU_Headers  = 0;
00172   cntDDU_Trailers = 0;
00173   cntCHAMB_Headers.clear();
00174   cntCHAMB_Trailers.clear();
00175 
00176   DAV_ALCT = false;
00177   DAV_TMB  = false;
00178   DAV_CFEB = 0;
00179   DMB_Active  = 0;
00180   nDMBs = 0;
00181   DDU_WordsSinceLastHeader     = 0;
00182   DDU_WordCount                = 0;
00183   DDU_WordMismatch_Occurrences = 0;
00184   DDU_WordsSinceLastTrailer    = 0;
00185   ALCT_ZSE                     = 0;
00186   nWG_round_up                 = 0;
00187 
00188   TMB_WordsRPC  = 0;
00189   TMB_Firmware_Revision = 0;
00190   zeroCounts();
00191 
00192   checkCrcALCT = false; ALCT_CRC=0;
00193   checkCrcTMB  = false; TMB_CRC=0;
00194   checkCrcCFEB = false; CFEB_CRC=0;
00195 
00196   modeDDUonly = false;
00197   sourceID    = 0xFFF;
00198   currentChamber = -1;
00199 
00200   //headerDAV_Active = -1; // Trailer vs. Header check // Obsolete since 16.09.05
00201 
00202   clear();
00203   buf_1 = &(tmpbuf[0]);
00204   buf0  = &(tmpbuf[4]);
00205   buf1  = &(tmpbuf[8]);
00206   buf2  = &(tmpbuf[12]);
00207 
00208   bzero(tmpbuf, sizeof(uint16_t)*16);
00209 }
00210 
00211 int32_t CSCDCCExaminer::check(const uint16_t* &buffer, int32_t length){
00212   if( length<=0 ) return -1;
00213 
00215   buffer_start = buffer;
00216 
00217   
00219   bool fTMB_Scope_Start = false;
00220   bool fTMB_MiniScope_Start = false; 
00221   bool fTMB_RPC_Start = false;
00222   bool fTMB_BlockedCFEBs_Start = false;
00223  
00224   bool fTMB_Scope = false;
00225   bool fTMB_MiniScope = false; 
00226   bool fTMB_RPC = false;
00227   bool fTMB_BlockedCFEBs = false;
00228 
00229   while( length>0 ){
00230     // == Store last 4 read buffers in pipeline-like memory (note that memcpy works quite slower!)
00231     buf_2 = buf_1;         //  This bufer was not needed so far
00232     buf_1 = buf0;
00233     buf0  = buf1;
00234     buf1  = buf2;
00235     buf2  = buffer;
00236 
00237     // check for too long event
00238     if(!fERROR[19] && DDU_WordsSinceLastHeader>100000 ){
00239       fERROR[19] = true;
00240       bERROR    |= 0x80000;
00241     }
00242 
00243     // increment counter of 64-bit words since last DDU Header
00244     // this counter is reset if DDU Header is found
00245     if ( fDDU_Header ) { ++DDU_WordsSinceLastHeader; }
00246 
00247     // increment counter of 64-bit words since last DDU Trailer
00248     // this counter is reset if DDU Trailer is found
00249     if ( fDDU_Trailer ) {++DDU_WordsSinceLastTrailer; }
00250 
00253     if ( fALCT_Header ) {
00255         if(ALCT_ZSE){
00256           for(int g=0; g<4; g++){
00257              if(buf0[g]==0x1000){
00258                ALCT_WordsSinceLastHeader = ALCT_WordsSinceLastHeader + nWG_round_up;
00259           } 
00260           else if(buf0[g]!=0x3000) ALCT_WordsSinceLastHeader = ALCT_WordsSinceLastHeader + 1;
00261          } 
00262         }
00263         else ALCT_WordsSinceLastHeader = ALCT_WordsSinceLastHeader + 4;
00265         ALCT_WordsSinceLastHeaderZeroSuppressed = ALCT_WordsSinceLastHeaderZeroSuppressed + 4;
00266     }
00267 
00268     // increment counter of 16-bit words since last DMB*TMB Header match
00269     // this counter is reset if TMB Header is found right after DMB Header or ALCT Trailer
00270     if ( fTMB_Header ) { TMB_WordsSinceLastHeader = TMB_WordsSinceLastHeader + 4; }
00271 
00272     // increment counter of 16-bit words since last of DMB Header, ALCT Trailer, TMB Trailer,
00273     // CFEB Sample Trailer, CFEB B-word; this counter is reset by all these conditions
00274     if ( fDMB_Header ) { CFEB_SampleWordCount = CFEB_SampleWordCount + 4; }
00275 
00276     // If DDU header is missing we set unphysical 0xFFF value for DDU id
00277     if( !fDDU_Header ){ sourceID=0xFFF; }
00278 
00279 
00280     if (!modeDDUonly) {
00281       // DCC Header 1 && DCC Header 2
00282       // =VB= Added support for Sep. 2008 CMS DAQ DCC format
00283       if ( ( ( (buf0[3]&0xF000) == 0x5000 && (buf0[0]&0x00FF) == 0x005F )
00284         ||
00285            ( (buf0[3]&0xF000) == 0x5000 && (buf0[0]&0x000F) == 0x0008 ) )
00286          &&
00287           (buf1[3]&0xFF00) == 0xD900 ) 
00288         {
00289         if( fDCC_Header ){
00290           // == Another DCC Header before encountering DCC Trailer!
00291           fERROR[25]=true;
00292           bERROR|=0x2000000;
00293           fERROR[0]=true;
00294           bERROR|=0x1;
00295           cerr<<"\n\nDCC Header Occurrence ";
00296           cerr<<"  ERROR 25    "<<sERROR[25]<<endl;
00297           fDDU_Header = false;
00298 
00299           // go backward for 3 DDU words ( buf2, buf1, and buf0 )
00300           buffer-=12;
00301           buf_1 = &(tmpbuf[0]);  // Just for safety
00302           buf0  = &(tmpbuf[4]);  // Just for safety
00303           buf1  = &(tmpbuf[8]);  // Just for safety
00304           buf2  = &(tmpbuf[12]); // Just for safety
00305           bzero(tmpbuf,sizeof(uint16_t)*16);
00306           return length+12;
00307         }
00308 
00309     fDCC_Header  = true;
00310     clear();
00311           }
00312         }
00313     // == Check for Format Control Words, set proper flags, perform self-consistency checks
00314 
00315     // C-words anywhere besides DDU Header
00316     if( fDDU_Header && ( (buf0[0]&0xF000)==0xC000 || (buf0[1]&0xF000)==0xC000 || (buf0[2]&0xF000)==0xC000 || (buf0[3]&0xF000)==0xC000 ) &&
00317         ( /*buf_1[0]!=0x8000 ||*/ buf_1[1]!=0x8000 || buf_1[2]!=0x0001 || buf_1[3]!=0x8000 ) ){
00318       fERROR[0]  = true;
00319       bERROR    |= 0x1;
00320       fERROR[20] = true;
00321       bERROR    |= 0x100000;
00322           // fCHAMB_ERR[20].insert(currentChamber);
00323           // bCHAMB_ERR[currentChamber] |= 0x100000;
00324       cerr<<"\nDDU Header Occurrence = "<<cntDDU_Headers;
00325       cerr<<"  ERROR 20 "<<sERROR[20]<<endl;
00326     }
00327 
00328     // == DDU Header found
00329     if( /*buf0[0]==0x8000 &&*/ buf0[1]==0x8000 && buf0[2]==0x0001 && buf0[3]==0x8000 ){
00330       // headerDAV_Active = (buf1[1]<<16) | buf1[0]; // Obsolete since 16.09.05
00332         checkDAVs();
00333         checkTriggerHeadersAndTrailers();
00335 
00336       if( fDDU_Header ){
00337         // == Another DDU Header before encountering DDU Trailer!
00338         fERROR[1]=true;
00339         bERROR|=0x2;
00340         fERROR[0] = true;
00341         bERROR|=0x1;
00342         cerr<<"\n\nDDU Header Occurrence = "<<cntDDU_Headers;
00343         cerr<<"  ERROR 1    "<<sERROR[1]<<endl;
00344         fDDU_Header = false;
00345 
00346         // Part of work for chambers that hasn't been done in absent trailer
00347         if( fDMB_Header || fDMB_Trailer ){
00348           fERROR[5] = true;
00349           bERROR   |= 0x20;
00350           // Since here there are no chances to know what this chamber was, force it to be -2
00351           if( currentChamber == -1 ) currentChamber = -2;
00352           fCHAMB_ERR[5].insert(currentChamber);
00353           bCHAMB_ERR[currentChamber] |= 0x20;
00354           fCHAMB_ERR[0].insert(currentChamber);
00355           bCHAMB_ERR[currentChamber] |= 0x1;
00356           cerr<<"\n\nDDU Header Occurrence = "<<cntDDU_Headers;
00357           cerr<<"  ERROR 5    "<<sERROR[5]<<endl;
00358         }       // One of DMB Trailers is missing ( or both )
00359         fDMB_Header  = false;
00360         fDMB_Trailer = false;
00361 
00362         if( DMB_Active!=nDMBs ){
00363           fERROR[24] = true;
00364           bERROR    |= 0x1000000;
00365         }
00366         DMB_Active = 0;
00367     nDMBs = 0;
00368 
00369         // Unknown chamber denoted as -2
00370         // If it still remains in any of errors - put it in error 0
00371         for(int err=1; err<nERRORS; ++err)
00372           if( fCHAMB_ERR[err].find(-2) != fCHAMB_ERR[err].end() ){
00373             fCHAMB_ERR[0].insert(-2);
00374             bCHAMB_ERR[-2] |= 0x1;
00375           }
00376 
00377         bDDU_ERR[sourceID] |= bERROR;
00378         bDDU_WRN[sourceID] |= bWARNING;
00379 
00380         // go backward for 3 DDU words ( buf2, buf1, and buf0 )
00381         buffer-=12;
00382         buf_1 = &(tmpbuf[0]);  // Just for safety
00383         buf0  = &(tmpbuf[4]);  // Just for safety
00384         buf1  = &(tmpbuf[8]);  // Just for safety
00385         buf2  = &(tmpbuf[12]); // Just for safety
00386         bzero(tmpbuf,sizeof(uint16_t)*16);
00387         return length+12;
00388       }
00389 
00390       // Reset all Error and Warning flags to be false
00398       currentChamber = -1; // Unknown yet
00399 
00400       if( fDDU_Trailer && DDU_WordsSinceLastTrailer != 4 ){
00401         // == Counted extraneous words between last DDU Trailer and this DDU Header
00402         fWARNING[0]=true;
00403         bWARNING|=0x1;
00404         cerr<<"\nDDU Header Occurrence = "<<cntDDU_Headers;
00405         cerr<<"  WARNING 0 "<<sWARNING[0]<<" "<<DDU_WordsSinceLastTrailer<<" extra 64-bit words"<<endl;
00406       }
00407 
00408       sourceID      = ((buf_1[1]&0xF)<<8) | ((buf_1[0]&0xFF00)>>8);
00409       fDDU_Header   = true;
00410       fDDU_Trailer  = false;
00411       DDU_WordCount = 0;
00412       fDMB_Header   = false;
00413       fDMB_Trailer  = false;
00414       fALCT_Header  = false;
00415       fALCT_Format2007= true;
00416       fTMB_Header   = false;
00417       fTMB_Format2007= true;
00418       uniqueALCT    = true;
00419       uniqueTMB     = true;
00420       zeroCounts();
00421 
00422       if (modeDDUonly) {
00423          fDCC_Header  = true;
00424          clear();
00425       }
00426 
00427           dduBuffers[sourceID] = buf_1;
00428       dduOffsets[sourceID] = buf_1-buffer_start;
00429       dduSize   [sourceID] = 0;
00430       dmbBuffers[sourceID].clear();
00431       dmbOffsets[sourceID].clear();
00432       dmbSize   [sourceID].clear();
00433 
00434           bDDU_ERR[sourceID] = 0;
00435       bDDU_WRN[sourceID] = 0;
00436 
00437       nDMBs      = 0;
00438       DMB_Active = buf1[0]&0xF;
00439       DAV_DMB    = buf1[1]&0x7FFF;
00440 
00441       int nDAV_DMBs=0;
00442       for(int bit=0; bit<15; bit++) if( DAV_DMB&(1<<bit) ) nDAV_DMBs++;
00443       if(DMB_Active!=nDAV_DMBs){
00444           fERROR[27] = true;
00445           bERROR    |= 0x8000000;
00446       }
00447 
00448       if( (buf_1[3]&0xF000)!=0x5000 ){
00449         fWARNING[1]=true;
00450         bWARNING|=0x2;
00451         cerr<<"\nDDU Header Occurrence = "<<cntDDU_Headers;
00452                 cerr<<"  WARNING 1 "<<sWARNING[1]<<". What must have been Header 1: 0x"<<std::hex<<buf_1[0]<<" 0x"<<buf_1[1]<<" 0x"<<buf_1[2]<<" 0x"<<buf_1[3]<<std::dec<<endl;
00453       }
00454 
00455       ++cntDDU_Headers;
00456       DDU_WordsSinceLastHeader=0; // Reset counter of DDU Words since last DDU Header
00457       cout<<"\n----------------------------------------------------------"<<endl;
00458       cout<<"DDU  Header Occurrence "<<cntDDU_Headers<< " L1A = " << ( ((buf_1[2]&0xFFFF) + ((buf_1[3]&0x00FF) << 16)) ) <<endl;
00459     }
00460 
00461     // == DMB Header found
00462     if( (buf0[0]&0xF000)==0xA000 && (buf0[1]&0xF000)==0xA000 && (buf0[2]&0xF000)==0xA000 && (buf0[3]&0xF000)==0xA000 ){
00464       checkDAVs();
00465       checkTriggerHeadersAndTrailers();
00467 
00468       if( DDU_WordsSinceLastHeader>3 && !fDMB_Header && !fDMB_Trailer && !nDMBs ){
00469         fERROR[28]=true;
00470         bERROR|=0x10000000;;
00471       }
00472 
00473       if( fDMB_Header || fDMB_Trailer ){ // F or E  DMB Trailer is missed
00474         fERROR[5]=true;
00475         bERROR|=0x20;
00476         fCHAMB_ERR[5].insert(currentChamber);
00477         bCHAMB_ERR[currentChamber] |= 0x20;
00478         fCHAMB_ERR[0].insert(currentChamber);
00479         bCHAMB_ERR[currentChamber] |= 0x1;
00480       }
00481       fDMB_Header  = true;
00482       fDMB_Trailer = false;
00483 
00484       // If previous DMB record was not assigned to any chamber ( it still has -1 indentificator )
00485       // let's free -1 identificator for current use and call undefined chamber from previous record -2
00486       // ( -2 may already exists in this sets but we have nothing to do with it )
00487       for(int err=0; err<nERRORS; ++err)
00488         if( fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end() ){
00489           fCHAMB_ERR[err].erase(-1);
00490           fCHAMB_ERR[err].insert(-2);
00491         }
00492 // Two lines below are commented out because payloads never get filled if 0xA header is missing
00493 //      bCHAMB_PAYLOAD[-2] |= bCHAMB_PAYLOAD[-1];
00494 //      fCHAMB_PAYLOAD[-1] = 0;
00495       bCHAMB_STATUS[-2] |= bCHAMB_STATUS[-1];
00496       bCHAMB_STATUS[-1] = 0;
00497       bCHAMB_ERR[-2] |= bCHAMB_ERR[-1];
00498       bCHAMB_ERR[-1] = 0;
00499       bCHAMB_WRN[-2] |= bCHAMB_WRN[-1];
00500       bCHAMB_WRN[-1] = 0;
00501 
00502       // Chamber id ( DMB_ID + (DMB_CRATE<<4) ) from header
00503       currentChamber = buf0[1]&0x0FFF;
00504       ++cntCHAMB_Headers[currentChamber];
00505       bCHAMB_ERR[currentChamber] |= 0; //Victor's line
00506 
00507       fALCT_Header = false;
00508       fALCT_Format2007= true;
00509       fTMB_Header  = false;
00510       fTMB_Format2007= true;
00511       uniqueALCT   = true;
00512       uniqueTMB    = true;
00513 
00514       fTMB_Scope_Start = false;
00515       fTMB_MiniScope_Start = false;
00516       fTMB_RPC_Start = false;
00517       fTMB_BlockedCFEBs_Start = false;
00518 
00519       fTMB_Scope = false;
00520       fTMB_MiniScope = false;
00521       fTMB_RPC = false;
00522       fTMB_BlockedCFEBs = false;       
00523 
00524 
00525       zeroCounts();
00526       CFEB_CRC                  = 0;
00527 
00528       nDMBs++;
00529 
00530       dmbBuffers[sourceID][currentChamber] = buf0-4;
00531       dmbOffsets[sourceID][currentChamber] = buf0-4-buffer_start;
00532       dmbSize   [sourceID][currentChamber] = 4;
00533 
00534       // Print DMB_ID from DMB Header
00535       cout<< "Crate=" << setw(3) << setfill('0') << ((buf0[1]>>4)&0x00FF) << " DMB="<<setw(2)<<setfill('0')<<(buf0[1]&0x000F)<<" ";
00536       // Print ALCT_DAV and TMB_DAV from DMB Header
00537       //cout<<setw(1)<<((buf0[0]&0x0020)>>5)<<" "<<((buf0[0]&0x0040)>>6)<<" ";
00538       cout<<setw(1)<<((buf0[0]&0x0200)>>9)<<" "<<((buf0[0]&0x0800)>>11)<<" "; //change of format 16.09.05
00539       // Print CFEB_DAV from DMB Header
00540       cout<<setw(1)<<((buf0[0]&0x0010)>>4)<<((buf0[0]&0x0008)>>3)<<((buf0[0]&0x0004)>>2)<<((buf0[0]&0x0002)>>1)<<(buf0[0]&0x0001);
00541       // Print DMB Header Tag
00542       cout << " {";
00543 
00544       // Set variables if we are waiting ALCT, TMB and CFEB records to be present in event
00545       DAV_ALCT = (buf0[0]&0x0200)>>9;
00546       DAV_TMB  = (buf0[0]&0x0800)>>11;
00547       DAV_CFEB = 0;
00548       if( buf0[0]&0x0001 ) ++DAV_CFEB;
00549       if( buf0[0]&0x0002 ) ++DAV_CFEB;
00550       if( buf0[0]&0x0004 ) ++DAV_CFEB;
00551       if( buf0[0]&0x0008 ) ++DAV_CFEB;
00552       if( buf0[0]&0x0010 ) ++DAV_CFEB;
00553       if( DAV_ALCT ) bCHAMB_PAYLOAD[currentChamber] |= 0x20;
00554       if( DAV_TMB  ) bCHAMB_PAYLOAD[currentChamber] |= 0x40;
00555       bCHAMB_PAYLOAD[currentChamber] |= (buf0[0]&0x001f)<<7;
00556       bCHAMB_PAYLOAD[currentChamber] |=((buf_1[2]>>5)&0x001f);
00557           bCHAMB_STATUS [currentChamber] |= (buf0[0]&0x0040)<<16;
00558     }
00559 
00560 
00561     // New ALCT data format:
00562     if( ( buf0[0]==0xDB0A && (buf0[1]&0xF000)==0xD000 && (buf0[2]&0xF000)==0xD000 && (buf0[3]&0xF000)==0xD000)
00563         &&
00564         ( (buf_1[0]&0xF000)==0xA000 && (buf_1[1]&0xF000)==0xA000 && (buf_1[2]&0xF000)==0xA000 && (buf_1[3]&0xF000)==0xA000 ) ){
00565         fALCT_Header              = true;
00566         fALCT_Format2007          = true;
00567         ALCT_CRC                  = 0;
00568         ALCT_WordsSinceLastHeader = 4;
00569         ALCT_WordsSinceLastHeaderZeroSuppressed = 4;
00570 
00571         // Calculate expected number of ALCT words
00572         ALCT_WordsExpected = 12; // header and trailer always exists
00573 
00574         //  Aauxilary variables
00575         //   number of wire groups per layer:
00576         int  nWGs_per_layer = ( (buf1[2]&0x0007) + 1 ) * 16 ;
00577         // words in the layer
00578         nWG_round_up   = int(nWGs_per_layer/12)+(nWGs_per_layer%3?1:0);
00579         //   configuration present:
00580         bool config_present =  buf1[0]&0x4000;
00581         //   lct overflow:
00582         bool lct_overflow   =  buf1[0]&0x2000;
00583         //   raw overflow:
00584         bool raw_overflow   =  buf1[0]&0x1000;
00585         //   l1a_window:
00586         int  lct_tbins      = (buf1[3]&0x01E0)>>5;
00587         //   fifo_tbins:
00588         int  raw_tbins      = (buf1[3]&0x001F);
00589         
00591         ALCT_ZSE            = (buf1[1]&0x1000)>>12;
00592         
00593         /*
00594         std::cout << " Number of Wire Groups: " << nWG_round_up << std::endl;
00595         std::cout << " ALCT_ZSE: " << ALCT_ZSE << std::endl; 
00596         std::cout << " raw_tbins: " << std::dec << raw_tbins << std::endl;
00597         std::cout << " LCT Tbins: " << lct_tbins << std::endl;
00598          */
00599 
00600         //  Data block sizes:
00601         //   3 words of Vertex ID register + 5 words of config. register bits:
00602         int config_size    = ( config_present ? 3 + 5 : 0 );
00603         //   collision mask register:
00604         int colreg_size    = ( config_present ? nWGs_per_layer/4 : 0 );
00605         //   hot channel mask:
00606         int hot_ch_size    = ( config_present ? nWG_round_up*6 : 0 );
00607         //   ALCT0,1 (best tracks):
00608         int alct_0_1_size  = ( !lct_overflow ? 2*lct_tbins : 0 );
00609         //   raw hit dump size:
00610         int raw_hit_dump_size=(!raw_overflow ? nWG_round_up*6*raw_tbins : 0 );
00611 
00612         //std::cout << " Raw Hit Dump: " << std::dec << raw_hit_dump_size << std::endl;
00613 
00614         ALCT_WordsExpected += config_size + colreg_size + hot_ch_size + alct_0_1_size + raw_hit_dump_size;
00615 
00616         cout<<" <A";
00617     } else {
00618         // Old ALCT data format
00619 
00620         // == ALCT Header found right after DMB Header
00621         //   (check for all currently reserved/fixed bits in ALCT first 4 words)
00622         // if( ( (buf0 [0]&0xF800)==0x6000 && (buf0 [1]&0xFF80)==0x0080 && (buf0 [2]&0xF000)==0x0000 && (buf0 [3]&0xc000)==0x0000 )
00623         if( ( (buf0 [0]&0xF800)==0x6000 && (buf0 [1]&0x8F80)==0x0080 && (buf0 [2]&0x8000)==0x0000 && (buf0 [3]&0xc000)==0x0000 )
00624             &&
00625             ( (buf_1[0]&0xF000)==0xA000 && (buf_1[1]&0xF000)==0xA000 && (buf_1[2]&0xF000)==0xA000 && (buf_1[3]&0xF000)==0xA000 ) ){
00626               fALCT_Header              = true;
00627               fALCT_Format2007          = false;
00628               ALCT_CRC                  = 0;
00629               ALCT_WordsSinceLastHeader = 4;
00630 
00631               // Calculate expected number of ALCT words
00632               if( (buf0[3]&0x0003)==0 ){ ALCT_WordsExpected = 12; }     // Short Readout
00633 
00634               if( (buf0[1]&0x0003)==1 ){                                        // Full Readout
00635                        ALCT_WordsExpected = ((buf0[1]&0x007c) >> 2) *
00636                         ( ((buf0[3]&0x0001)   )+((buf0[3]&0x0002)>>1)+
00637                         ((buf0[3]&0x0004)>>2)+((buf0[3]&0x0008)>>3)+
00638                         ((buf0[3]&0x0010)>>4)+((buf0[3]&0x0020)>>5)+
00639                         ((buf0[3]&0x0040)>>6) ) * 12 + 12;
00640               }
00641               cout<<" <A";
00642         }
00643     }
00644     //std::cout << " ALCT Word Expected: " << ALCT_WordsExpected << std::endl;
00645 
00646     if( (buf0[0]&0xFFFF)==0xDB0C ){
00647         fTMB_Header              = true;
00648         fTMB_Format2007          = true;
00649         TMB_CRC                  = 0;
00650         TMB_WordsSinceLastHeader = 4;
00651         TMB_WordsExpected = 0;
00652 
00653         // Calculate expected number of TMB words (whether RPC included will be known later)
00654         if ( (buf1[1]&0x3000) == 0x3000) { TMB_WordsExpected = 12; }  // Short Header Only
00655         if ( (buf1[1]&0x3000) == 0x0000) { TMB_WordsExpected = 48; }  // Long Header Only
00656 
00657         cout << " <T";
00658     } else {
00659         // == TMB Header found right after DMB Header or right after ALCT Trailer
00660         if(   (buf0 [0]&0xFFFF)==0x6B0C && (
00661                                         ( (buf_1[0]&0xF000)==0xA000 && (buf_1[1]&0xF000)==0xA000 && (buf_1[2]&0xF000)==0xA000 && (buf_1[3]&0xF000)==0xA000 )
00662                                         ||
00663                                         ( (buf_1[0]&0x0800)==0x0000 && (buf_1[1]&0xF800)==0xD000 && (buf_1[2]&0xFFFF)==0xDE0D && (buf_1[3]&0xF000)==0xD000 )
00664                                         // should've been (buf_1[0]&0xF800)==0xD000 - see comments for sERROR[11]
00665                                         ) )
00666         {
00667         //if( (buf_1[2]&0xFFFF)==0xDE0D && (buf_1[3]&0xFC00)!=0xD000 && summer2004 ) ???
00668 
00669             fTMB_Header              = true;
00670             fTMB_Format2007          = false;
00671             TMB_CRC                  = 0;
00672             TMB_WordsSinceLastHeader = 4;
00673 
00674             // Calculate expected number of TMB words (whether RPC included will be known later)
00675             if ( (buf0[1]&0x3000) == 0x3000) { TMB_WordsExpected = 8; }   // Short Header Only
00676             if ( (buf0[1]&0x3000) == 0x0000) { TMB_WordsExpected = 32; }  // Long Header Only
00677 
00678             if ( (buf0[1]&0x3000) == 0x1000) {
00679                 // Full Readout   = 28 + (#Tbins * #CFEBs * 6)
00680                 TMB_Tbins=(buf0[1]&0x001F);
00681                 TMB_WordsExpected = 28 + TMB_Tbins * ((buf1[0]&0x00E0)>>5) * 6;
00682             }
00683 
00684                         cout << " <T";
00685                 }
00686         }
00687     // New TMB format => very long header Find Firmware revision
00688     if ( fTMB_Header && fTMB_Format2007 && TMB_WordsSinceLastHeader==8 ) {
00689         TMB_Firmware_Revision = buf0[3];
00690     }
00691 
00692     // New TMB format => very long header
00693     if ( fTMB_Header && fTMB_Format2007 && TMB_WordsSinceLastHeader==20 ) {
00694         // Full Readout   = 44 + (#Tbins * #CFEBs * 6)
00695         TMB_Tbins=(buf0[3]&0x00F8)>>3;
00696         TMB_WordsExpected = 44 + TMB_Tbins * (buf0[3]&0x0007) * 6;
00697     }
00698 
00699     // == ALCT Trailer found
00700         if(
00701         // New ALCT data format:
00702         ( buf0[0]==0xDE0D && (buf0[1]&0xF800)==0xD000 && (buf0[2]&0xF800)==0xD000 && (buf0[3]&0xF000)==0xD000 && fALCT_Format2007 ) ||
00703         // Old ALCT data format; last check is added to avoid confusion with new TMB header (may not be needed):
00704         ( (buf0[0]&0x0800)==0x0000 && (buf0[1]&0xF800)==0xD000 && (buf0[2]&0xFFFF)==0xDE0D && (buf0[3]&0xF000)==0xD000 && !fALCT_Format2007 && !(fTMB_Header&&fTMB_Format2007) )
00705     ){
00706       // should've been (buf0[0]&0xF800)==0xD000 - see comments for sERROR[11]
00707 
00708       // Second ALCT -> Lost both previous DMB Trailer and current DMB Header
00709       if( !uniqueALCT ) currentChamber = -1;
00710       // Check if this ALCT record have to exist according to DMB Header
00711       if(   DAV_ALCT  ) DAV_ALCT = false; else DAV_ALCT = true;
00712 
00713       if( !fALCT_Header ){
00714         fERROR[8] = true;
00715         bERROR   |= 0x100;
00716         fCHAMB_ERR[8].insert(currentChamber);
00717         bCHAMB_ERR[currentChamber] |= 0x100;
00718         fCHAMB_ERR[0].insert(currentChamber);
00719         bCHAMB_ERR[currentChamber] |= 0x1;
00720       } // ALCT Header is missing
00721 
00722       if( !fALCT_Format2007 && (buf0[0]&0xF800)!=0xD000 ){
00723         fERROR[11] = true;
00724         bERROR    |= 0x800;
00725         fCHAMB_ERR[11].insert(currentChamber);
00726         bCHAMB_ERR[currentChamber] |= 0x800;
00727         fCHAMB_ERR[0].insert(currentChamber);
00728         bCHAMB_ERR[currentChamber] |= 0x1;
00729       } // some bits in 1st D-Trailer are lost
00730 
00732       if( checkCrcALCT ){
00733     uint32_t crc = ( fALCT_Format2007 ? buf0[1] : buf0[0] ) & 0x7ff;
00734     crc |= ((uint32_t)( ( fALCT_Format2007 ? buf0[2] : buf0[1] ) & 0x7ff)) << 11;
00735         if( ALCT_CRC != crc ){
00736           fERROR[10] = true;
00737           bERROR   |= 0x400;
00738           fCHAMB_ERR[10].insert(currentChamber);
00739           bCHAMB_ERR[currentChamber] |= 0x400;
00740           fCHAMB_ERR[0].insert(currentChamber);
00741           bCHAMB_ERR[currentChamber] |= 0x1;
00742         }
00743       }
00744 
00745       fALCT_Header = false;
00746       uniqueALCT   = false;
00747       CFEB_CRC     = 0;
00748       //ALCT_WordCount = (buf0[3]&0x03FF);
00749       ALCT_WordCount = (buf0[3]&0x07FF);
00750       //ALCT_WordCount = (buf0[3]&0x0FFF);
00751       CFEB_SampleWordCount = 0;
00752       cout << "A> ";
00753     }
00754 
00755     // Calculation of CRC sum ( algorithm is written by Madorsky )
00756     if( fALCT_Header && checkCrcALCT ){
00757       for(uint16_t j=0, w=0; j<4; ++j){
00759         w = buf0[j] & (fALCT_Format2007 ? 0xffff : 0x7fff);
00760         for(uint32_t i=15, t=0, ncrc=0; i<16; i--){
00761           t = ((w >> i) & 1) ^ ((ALCT_CRC >> 21) & 1);
00762           ncrc = (ALCT_CRC << 1) & 0x3ffffc;
00763           ncrc |= (t ^ (ALCT_CRC & 1)) << 1;
00764           ncrc |= t;
00765           ALCT_CRC = ncrc;
00766         }
00767       }
00768     }
00769 
00770     // == Find Correction for TMB_WordsExpected due to RPC raw hits,
00771     //    should it turn out to be the new RPC-aware format
00772     if( fTMB_Header && ((buf0[2]&0xFFFF)==0x6E0B) )  {
00773       if (fTMB_Format2007) {
00774         if (TMB_Firmware_Revision >= 0x50c3) { // TMB2007 rev.0x50c3
00775           // On/off * nRPCs * nTimebins * 2 words/RPC/bin
00776           TMB_WordsRPC = ((buf_1[0]&0x0010)>>4) * ((buf_1[0]&0x000c)>>2) * ((buf_1[0]>>5) & 0x1F) * 2;
00777         }
00778         else { // TMB2007 (may not work since TMB_Tbins != RPC_Tbins)
00779           TMB_WordsRPC = ((buf_1[0]&0x0040)>>6) * ((buf_1[0]&0x0030)>>4) * TMB_Tbins * 2;
00780         }
00781       }
00782       else { // Old format
00783         TMB_WordsRPC   = ((buf_1[2]&0x0040)>>6) * ((buf_1[2]&0x0030)>>4) * TMB_Tbins * 2;
00784       }
00785       TMB_WordsRPC += 2; // add header/trailer for block of RPC raw hits
00786     }
00787 
00788 
00789         
00790     // Check for RPC data
00791     if ( fTMB_Header && (scanbuf(buf0,4, 0x6B04)>=0) ) {
00792         fTMB_RPC_Start = true;
00793       }
00794 
00795     // Check for Scope data
00796     if ( fTMB_Header && (scanbuf(buf0,4, 0x6B05)>=0) ) { 
00797         fTMB_Scope_Start = true;
00798       }
00799 
00800     // Check for Mini-Scope data
00801     if ( fTMB_Header && (scanbuf(buf0,4, 0x6B07)>=0) ) { 
00802         fTMB_MiniScope_Start = true;
00803       }
00804     
00805     // Check for Blocked CFEBs data
00806     if ( fTMB_Header && (scanbuf(buf0,4, 0x6BCB)>=0) ) { 
00807         fTMB_BlockedCFEBs_Start = true;
00808       }
00809 
00810     
00811     // Check for end of RPC data
00812     if ( fTMB_Header && fTMB_RPC_Start 
00813         && (scanbuf(buf0,4, 0x6E04)>=0) ) {
00814         fTMB_RPC = true;
00815       }
00816 
00817     // Check for end of Scope data
00818     if ( fTMB_Header && fTMB_Scope_Start 
00819         && (scanbuf(buf0,4, 0x6E05)>=0) ) {
00820         fTMB_Scope = true;
00821       }
00822 
00823     // Check for end of Mini-Scope data
00824     if ( fTMB_Header && fTMB_MiniScope_Start 
00825         && (scanbuf(buf0,4, 0x6E07)>=0) ) {
00826         fTMB_MiniScope = true;
00827       }
00828 
00829     // Check for end of Blocked CFEBs data
00830     if ( fTMB_Header && fTMB_BlockedCFEBs_Start 
00831         && (scanbuf(buf0,4, 0x6ECB)>=0) ) {
00832         fTMB_BlockedCFEBs = true;
00833       }
00834 
00835  /* 
00836     if ( fTMB_Header && (scanbuf(buf0,4, 0x6E04)>=0) ) {
00837           TMB_WordsExpected += TMB_WordsRPC; 
00838       }
00839 */
00840 
00841     // == TMB Trailer found
00842     if(
00843        // Old TMB data format; last condition in needed not to confuse if with new ALCT data header
00844        ((buf0[0]&0xF000)==0xD000 && (buf0[1]&0xF000)==0xD000 && (buf0[2]&0xFFFF)==0xDE0F && (buf0[3]&0xF000)==0xD000 && !fTMB_Format2007 && !(fALCT_Header&&fALCT_Format2007)) ||
00845        // New TMB data format
00846        ( buf0[0]==        0xDE0F && (buf0[1]&0xF000)==0xD000 && (buf0[2]&0xF000)==0xD000 && (buf0[3]&0xF000)==0xD000 &&  fTMB_Format2007 )
00847     ){
00848 
00849       // Second TMB -> Lost both previous DMB Trailer and current DMB Header
00850       if( !uniqueTMB ) currentChamber = -1;
00851       // Check if this TMB record have to exist according to DMB Header
00852       if(   DAV_TMB  ) DAV_TMB = false; else DAV_TMB = true;
00853 
00854       if(!fTMB_Header){
00855         fERROR[13] = true;
00856         bERROR    |= 0x2000;
00857         fCHAMB_ERR[13].insert(currentChamber);
00858         bCHAMB_ERR[currentChamber] |= 0x2000;
00859         fCHAMB_ERR[0].insert(currentChamber);
00860         bCHAMB_ERR[currentChamber] |= 0x1;
00861       }  // TMB Header is missing
00862 
00863       // Check calculated CRC sum against reported
00864       if( checkCrcTMB ){
00865     uint32_t crc = ( fTMB_Format2007 ? buf0[1]&0x7ff : buf0[0]&0x7ff );
00866     crc |= ((uint32_t)( ( fTMB_Format2007 ? buf0[2]&0x7ff : buf0[1] & 0x7ff ) )) << 11;
00867         if( TMB_CRC != crc ){
00868           fERROR[15] = true;
00869           bERROR    |= 0x8000;
00870           fCHAMB_ERR[15].insert(currentChamber);
00871           bCHAMB_ERR[currentChamber] |= 0x8000;
00872           fCHAMB_ERR[0].insert(currentChamber);
00873           bCHAMB_ERR[currentChamber] |= 0x1;
00874         }
00875       }
00876 
00877       fTMB_Header = false;
00878       uniqueTMB   = false;
00879       CFEB_CRC     = 0;
00880       TMB_WordCount = (buf0[3]&0x07FF);
00881 
00882       // == Correct TMB_WordsExpected
00883       //        1) for 2 optional 0x2AAA and 0x5555 Words in the Trailer
00884       //        2) for extra 4 frames in the new TMB trailer and
00885       //         for RPC raw hit data, if present
00886       //
00887       // If the scope data was enabled in readout, scope data markers (0x6B05
00888       // and 0x6E05) appear before 0x6E0C, and the optional 0x2AAA and 0x5555
00889       // trailer words are suppressed.  So far, we only have data with the
00890       // empty scope content, so more corrections will be needed once
00891       // non-empty scope data is available. -SV, 5 Nov 2008.
00892       //
00893       // If word count is not multiple of 4, add 2 optional words and
00894       // 4 trailer words.
00895   
00896       int pos = scanbuf(buf_1,4,0x6E0C);
00897       if (pos==1) {
00898         TMB_WordsExpected += 6;
00899       }
00900       // If word count is multiple of 4, add 4 trailer words.
00901       else if (pos==3) {
00902         TMB_WordsExpected += 4;
00903       }
00904 
00905       // Correct expected wordcount by RPC data size
00906       if (fTMB_RPC) 
00907         TMB_WordsExpected += TMB_WordsRPC;
00908 
00909       // Correct expected wordcount by MiniScope data size (22 words + 2 signature words)
00910       if (fTMB_MiniScope) 
00911         TMB_WordsExpected += 24;
00912 
00913       // Correct expected wordcount by BlockedCFEBs data size (20 words + 2 signature words) 
00914       if (fTMB_BlockedCFEBs) 
00915         TMB_WordsExpected += 22;
00916 
00917       CFEB_SampleWordCount = 0;
00918       cout << "T> ";
00919     }
00920 
00921     if( fTMB_Header && checkCrcTMB ){
00922       for(uint16_t j=0, w=0; j<4; ++j){
00924         w = buf0[j] & (fTMB_Format2007 ? 0xffff : 0x7fff);
00925         for(uint32_t i=15, t=0, ncrc=0; i<16; i--){
00926           t = ((w >> i) & 1) ^ ((TMB_CRC >> 21) & 1);
00927           ncrc = (TMB_CRC << 1) & 0x3ffffc;
00928           ncrc |= (t ^ (TMB_CRC & 1)) << 1;
00929           ncrc |= t;
00930           TMB_CRC = ncrc;
00931         }
00932       }
00933     }
00934 
00935 
00936     // == CFEB Sample Trailer found
00937 
00938         if( ((buf0[1]&0xF000)==0x7000) &&
00939                 ((buf0[2]&0xF000)==0x7000) &&
00940                 ((buf0[1]!=0x7FFF) || (buf0[2]!=0x7FFF)) &&
00941                 ( ((buf0[3]&0xFFFF)==0x7FFF) ||   // old format
00942               ( (buf0[3]&buf0[0])==0x0000 && (buf0[3]+buf0[0])==0x7FFF ) // 2007 format
00943               ) ){
00944 
00945       if((CFEB_SampleCount%8)  == 0   ){ cout<<" <"; }
00946       if( CFEB_SampleWordCount == 100 ){ cout<<"+";  }
00947       if( CFEB_SampleWordCount != 100 ){ cout<<"-";
00948       fERROR[16] = true;
00949       bERROR    |= 0x10000;
00950       fCHAMB_ERR[16].insert(currentChamber);
00951       bCHAMB_ERR[currentChamber] |= 0x10000;
00952       fCHAMB_ERR[0].insert(currentChamber);
00953       bCHAMB_ERR[currentChamber] |= 0x1;
00954       }
00955 
00956       ++CFEB_SampleCount;
00957 
00958       if( (CFEB_SampleCount%8)==0 ){
00959         cout<<">";
00960         CFEB_BSampleCount=0;
00961         // Count CFEBs
00962         DAV_CFEB--;
00963       }
00964 
00965       // Check calculated CRC sum against reported
00966       if( checkCrcCFEB && CFEB_CRC!=buf0[0] ){
00967         fERROR[18] = true;
00968         bERROR    |= 0x40000;
00969         fCHAMB_ERR[18].insert(currentChamber);
00970         bCHAMB_ERR[currentChamber] |= 0x40000;
00971         fCHAMB_ERR[0].insert(currentChamber);
00972         bCHAMB_ERR[currentChamber] |= 0x1;
00973       }
00974 
00975       CFEB_CRC = 0;
00976       CFEB_SampleWordCount=0;
00977     }
00978 
00979 
00980     // == CFEB B-word found
00981     if( (buf0[0]&0xF000)==0xB000 && (buf0[1]&0xF000)==0xB000 && (buf0[2]&0xF000)==0xB000 && (buf0[3]&0xF000)==0xB000 ){
00982       bCHAMB_STATUS[currentChamber] |= 0x400000;
00983 
00984       if( (CFEB_SampleCount%8)==0 ){ cout<<" <"; }
00985       cout<<"B";
00986 
00987       ++CFEB_SampleCount;
00988       ++CFEB_BSampleCount;
00989 
00990       if( (CFEB_SampleCount%8)==0 ){
00991         cout << ">";
00992         CFEB_BSampleCount=0;
00993         DAV_CFEB--;
00994       }
00995 
00996       CFEB_SampleWordCount=0;
00997     }
00998 
00999      // == If it is nither ALCT record nor TMB - probably it is CFEB record and we try to count CRC sum.
01000     // It very few words of CFEB occasionaly will be misinterpreted as ALCT or TMB header the result
01001     // for the CRC sum will be wrong, but other errors of Trailers counting will appear as well
01002     if( checkCrcCFEB && fDMB_Header && !fTMB_Header && !fALCT_Header && CFEB_SampleWordCount )
01003       for(int pos=0; pos<4; ++pos)
01004         CFEB_CRC=(buf0[pos]&0x1fff)^((buf0[pos]&0x1fff)<<1)^(((CFEB_CRC&0x7ffc)>>2)|((0x0003&CFEB_CRC)<<13))^((CFEB_CRC&0x7ffc)>>1);
01005 
01006 
01007     // == DMB F-Trailer found
01008     if( (buf0[0]&0xF000)==0xF000 && (buf0[1]&0xF000)==0xF000 && (buf0[2]&0xF000)==0xF000 && (buf0[3]&0xF000)==0xF000 ){
01009       if(!fDMB_Header){
01010         currentChamber = buf0[3]&0x0FFF;
01011         fERROR[6] = true;
01012         bERROR   |= 0x40;
01013         fCHAMB_ERR[6].insert(currentChamber);
01014         bCHAMB_ERR[currentChamber] |= 0x40;
01015         nDMBs++;
01016         // Set variables if we are waiting ALCT, TMB and CFEB records to be present in event
01017         if( buf0[0]&0x0400 ) bCHAMB_PAYLOAD[currentChamber] |= 0x20;
01018         if( buf0[0]&0x0800 ) bCHAMB_PAYLOAD[currentChamber] |= 0x40;
01019         bCHAMB_PAYLOAD[currentChamber] |= (buf0[0]&0x001f)<<7;
01020         bCHAMB_PAYLOAD[currentChamber] |=((buf0[0]>>5)&0x1f);
01021 
01022       } // DMB Header is missing
01023       fDMB_Header  = false;
01024       fDMB_Trailer = true;
01025       uniqueALCT   = true;
01026       uniqueTMB    = true;
01027 
01028       dmbSize[sourceID][currentChamber] = buf0 - dmbBuffers[sourceID][currentChamber];
01029 
01030       // Finally check if DAVs were correct
01031       checkDAVs();
01032 
01033       // If F-Trailer is lost then do necessary work here
01034       if( (buf1[0]&0xF000)!=0xE000 || (buf1[1]&0xF000)!=0xE000 || (buf1[2]&0xF000)!=0xE000 || (buf1[3]&0xF000)!=0xE000 ){
01035         for(int err=1; err<nERRORS; ++err)
01036           if( fCHAMB_ERR[err].find(currentChamber) != fCHAMB_ERR[err].end() ){
01037             fCHAMB_ERR[0].insert(currentChamber);
01038             bCHAMB_ERR[currentChamber] |= 0x1;
01039           }
01040         // Reset chamber id
01041         currentChamber=-1;
01042         /*
01043           for(int err=0; err<nERRORS; err++)
01044           if( fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end() )
01045           fCHAMB_ERR[err].erase(-1);
01046           bCHAMB_ERR[-1] = 0;
01047           bCHAMB_WRN[-1] = 0;
01048         */
01049       }
01050 
01051       // Print DMB F-Trailer marker
01052       cout << " }";
01053     }
01054 
01055     // == DMB E-Trailer found
01056     if( (buf0[0]&0xF000)==0xE000 && (buf0[1]&0xF000)==0xE000 && (buf0[2]&0xF000)==0xE000 && (buf0[3]&0xF000)==0xE000 ){
01057       if( !fDMB_Header && !fDMB_Trailer ) nDMBs++; // both DMB Header and DMB F-Trailer were missing
01058 
01059       bCHAMB_STATUS[currentChamber] |= (buf0[0]&0x0800)>>11;
01060       bCHAMB_STATUS[currentChamber] |= (buf0[0]&0x0400)>>9;
01061       bCHAMB_STATUS[currentChamber] |= (buf0[0]&0x03E0)>>3;
01062       if( fDMB_Trailer ){ // F-Trailer exists
01063         bCHAMB_STATUS[currentChamber] |= (buf_1[2]&0x0002)<<6;
01064         bCHAMB_STATUS[currentChamber] |= (buf_1[2]&0x0001)<<8;
01065         bCHAMB_STATUS[currentChamber] |= (buf_1[3]&0x001f)<<9;
01066         bCHAMB_STATUS[currentChamber] |= (buf_1[3]&0x0040)<<8;
01067         bCHAMB_STATUS[currentChamber] |= (buf_1[3]&0x0020)<<10;
01068                 bCHAMB_STATUS[currentChamber] |= (buf_1[3]&0x0f80)<<9;
01069       }
01070       fDMB_Header  = false;
01071 
01072       // If chamber id is unknown it is time to find it out
01073       if( currentChamber==-1 ){
01074         currentChamber = buf0[1]&0x0FFF;
01075         for(int err=0; err<nERRORS; ++err)
01076           if( fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end() ){
01077             fCHAMB_ERR[err].insert(currentChamber);
01078             fCHAMB_ERR[err].erase(-1);
01079           }
01080     bCHAMB_STATUS[currentChamber] = bCHAMB_STATUS[-1];
01081     bCHAMB_STATUS[-1] = 0;
01082         bCHAMB_ERR[currentChamber] = bCHAMB_ERR[-1];
01083         bCHAMB_ERR[-1] = 0;
01084         bCHAMB_WRN[currentChamber] = bCHAMB_WRN[-1];
01085         bCHAMB_WRN[-1] = 0;
01086       }
01087       ++cntCHAMB_Trailers[buf0[1]&0x0FFF];
01088 
01089       dmbSize[sourceID][currentChamber] = buf0 - dmbBuffers[sourceID][currentChamber];
01090 
01091       // Lost DMB F-Trailer before
01092       if( !fDMB_Trailer ){
01093         fERROR[6] = true;
01094         bERROR   |= 0x40;
01095         fCHAMB_ERR[6].insert(currentChamber);
01096         bCHAMB_ERR[currentChamber] |= 0x40;
01097         fCHAMB_ERR[0].insert(currentChamber);
01098         bCHAMB_ERR[currentChamber] |= 0x1;
01099         // Check if DAVs were correct here
01100         checkDAVs();
01101       }
01102       fDMB_Trailer = false;
01103 
01104      // Print DMB E-Trailer marker
01105       cout<<" DMB="<<(buf0[1]&0x000F);
01106       cout << "; "
01107            << ALCT_WordsSinceLastHeader << "-"
01108            << ALCT_WordCount << "-"
01109            << ALCT_WordsExpected
01110            << "      "
01111            << TMB_WordsSinceLastHeader << "-"
01112            << TMB_WordCount << "-"
01113            << TMB_WordsExpected
01114            << endl;
01115 
01116      checkTriggerHeadersAndTrailers();
01117 
01118       //
01119       for(int err=0; err<nERRORS; ++err)
01120         if( fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end() ){
01121           fCHAMB_ERR[err].erase(-1);
01122           fCHAMB_ERR[err].insert(-2);
01123         }
01124       bCHAMB_STATUS[-2] |= bCHAMB_STATUS[-1];
01125       bCHAMB_STATUS[-1] = 0;
01126       bCHAMB_ERR[-2] |= bCHAMB_ERR[-1];
01127       bCHAMB_ERR[-1] = 0;
01128       bCHAMB_WRN[-2] |= bCHAMB_WRN[-1];
01129       bCHAMB_WRN[-1] = 0;
01130 
01131       if( currentChamber != -1 )
01132         for(int err=1; err<nERRORS; ++err)
01133           if( fCHAMB_ERR[err].find(currentChamber) != fCHAMB_ERR[err].end() ){
01134             fCHAMB_ERR[0].insert(currentChamber);
01135             bCHAMB_ERR[currentChamber] |= 0x1;
01136           }
01137 
01138       currentChamber=-1;
01139 /*
01140       // Print DMB E-Trailer marker
01141       cout<<" DMB="<<(buf0[1]&0x000F);
01142       cout << "; "
01143            << ALCT_WordsSinceLastHeader << "-"
01144            << ALCT_WordCount << "-"
01145            << ALCT_WordsExpected
01146            << "      "
01147            << TMB_WordsSinceLastHeader << "-"
01148            << TMB_WordCount << "-"
01149            << TMB_WordsExpected
01150            << endl;
01151 */
01152 
01153     }
01154 
01155     // == DDU Trailer found
01156     if( buf0[0]==0x8000 && buf0[1]==0x8000 && buf0[2]==0xFFFF && buf0[3]==0x8000 ){
01157       // Obsolete since 16.09.05
01158       //                        if( headerDAV_Active != ((buf1[1]<<16) | buf1[0]) ){
01159       //                                fERROR[0]  = true;
01160       //                                fERROR[21] = true;
01161       //                                bERROR|=0x200000;
01162       //                                //cerr<<"  ERROR 21   "<<sERROR[21]<<endl;
01163       //                        }
01164       //                        headerDAV_Active = -1;
01166       checkDAVs();
01167 
01168       checkTriggerHeadersAndTrailers();
01169 
01171 
01172       if( DDU_WordsSinceLastHeader>3 && !nDMBs ){
01173         fERROR[28]=true;
01174         bERROR|=0x10000000;;
01175       }
01176 
01177       if(fDDU_Trailer){
01178         fERROR[2] = true;
01179         bERROR   |= 0x4;
01180       } // DDU Header is missing
01181       fDDU_Trailer=true;
01182       fDDU_Header=false;
01183 
01184       if( fDMB_Header || fDMB_Trailer ){
01185        // std::cout << " Ex-Err: DMB (Header, Trailer) " << std::endl;
01186         fERROR[5] = true;
01187         bERROR   |= 0x20;
01188         fCHAMB_ERR[5].insert(currentChamber);
01189         bCHAMB_ERR[currentChamber] |= 0x20;
01190         fCHAMB_ERR[0].insert(currentChamber);
01191         bCHAMB_ERR[currentChamber] |= 0x20;
01192       } // DMB Trailer is missing
01193       fDMB_Header  = false;
01194       fDMB_Trailer = false;
01195 
01196       currentChamber=-1;
01197 
01198       for(int err=0; err<nERRORS; ++err)
01199         if( fCHAMB_ERR[err].find(-1) != fCHAMB_ERR[err].end() ){
01200           fCHAMB_ERR[err].erase(-1);
01201           fCHAMB_ERR[err].insert(-2);
01202         }
01203       bCHAMB_STATUS[-2] |= bCHAMB_STATUS[-1];
01204       bCHAMB_STATUS[-1] = 0;
01205       bCHAMB_ERR[-2] |= bCHAMB_ERR[-1];
01206       bCHAMB_ERR[-1] = 0;
01207       bCHAMB_WRN[-2] |= bCHAMB_WRN[-1];
01208       bCHAMB_WRN[-1] = 0;
01209 
01210       for(int err=1; err<nERRORS; ++err)
01211         if( fCHAMB_ERR[err].find(-2) != fCHAMB_ERR[err].end() ){
01212           fCHAMB_ERR[0].insert(-2);
01213           bCHAMB_ERR[-2] |= 0x1;
01214         }
01215 
01216       dduSize[sourceID] = buf0-dduBuffers[sourceID];
01217 
01218       ++cntDDU_Trailers; // Increment DDUTrailer counter
01219 
01220       // == Combining 2 words into 24bit value
01221       DDU_WordCount = buf2[2] | ((buf2[3] & 0xFF) <<16) ;
01222 
01223       if( (DDU_WordsSinceLastHeader+4) != DDU_WordCount ){
01224         fERROR[4] = true;
01225         bERROR   |= 0x10;
01226       }
01227 
01228       if( DMB_Active!=nDMBs ){
01229         fERROR[24] = true;
01230         bERROR    |= 0x1000000;
01231       }
01232 
01233       cout<<"DDU Trailer Occurrence "<<cntDDU_Trailers<<endl;
01234       cout<<"----------------------------------------------------------"<<endl;
01235       cout<<"DDU 64-bit words = Actual - DDUcounted ="<<DDU_WordsSinceLastHeader+4<<"-"<<DDU_WordCount<<endl;
01236 
01237       // increment statistics Errors and Warnings (i=0 case is handled in DDU Header)
01238       for(int err=1; err<nERRORS; ++err){
01239         if( fERROR[err] ){
01240           fERROR[0] = true;
01241           bERROR |= 0x1;
01242           cerr<<"\nDDU Header Occurrence = "<<cntDDU_Headers;
01243           cerr<<"  ERROR "<<err<<"  " <<sERROR[err]<<endl;
01244         }
01245       }
01246       for(int wrn=1; wrn<nWARNINGS; ++wrn){
01247         if( fWARNING[wrn] ){
01248           cout<<"\nDDU Header Occurrence = "<<cntDDU_Headers;
01249           cout<<"  WARNING "<<wrn<<"  "<<sWARNING[wrn]<<endl;
01250         }
01251       }
01252 
01253       bDDU_ERR[sourceID] |= bERROR;
01254       bDDU_WRN[sourceID] |= bWARNING;
01255 
01256       DDU_WordsSinceLastHeader=0;
01257       DDU_WordsSinceLastTrailer=0;
01258       if (modeDDUonly) {
01259         buffer+=4;
01260         buf_1 = &(tmpbuf[0]);  // Just for safety
01261         buf0  = &(tmpbuf[4]);  // Just for safety
01262         buf1  = &(tmpbuf[8]);  // Just for safety
01263         buf2  = &(tmpbuf[12]); // Just for safety
01264         bzero(tmpbuf, sizeof(uint16_t)*16);
01265         return length-4;
01266       }
01267     }
01268 
01269     if (!modeDDUonly) {
01270       // DCC Trailer 1 && DCC Trailer 2
01271       // =VB= Added support for Sep. 2008 CMS DAQ DCC format
01272       // =VB= 04.18.09 Removed (buf2[0]&0x0003) == 0x3 check for old DCC format to satisfy older format of simulated data
01273       if( (buf1[3]&0xFF00) == 0xEF00 &&
01274           ( ((buf2[3]&0xFF00) == 0xAF00 ) 
01275           || 
01276      (( buf2[3]&0xFF00) == 0xA000 && (buf2[0]&0x0003) == 0x0) ) ){
01277         // =VB= Added check that there is no DCCHeader detected to set missing DCC Header error
01278         if(!fDCC_Header || fDCC_Trailer){
01279           fERROR[26] = true;
01280           bERROR|=0x4000000;
01281           fERROR[0] = true;
01282           bERROR|=0x1;
01283         } // DCC Header is missing
01284         fDCC_Trailer=true;
01285         fDCC_Header=false;
01286 
01287         if( fDDU_Header ){
01288           // == DDU Trailer is missing
01289           fERROR[1]=true;
01290           bERROR|=0x2;
01291           fERROR[0] = true;
01292           bERROR|=0x1;
01293         }
01294 
01295         buffer+=4;
01296         buf_1 = &(tmpbuf[0]);  // Just for safety
01297         buf0  = &(tmpbuf[4]);  // Just for safety
01298         buf1  = &(tmpbuf[8]);  // Just for safety
01299         buf2  = &(tmpbuf[12]); // Just for safety
01300         bzero(tmpbuf, sizeof(uint16_t)*16);
01301         return length-4;
01302       }
01303     }
01304 
01305     length-=4;
01306     buffer+=4;
01307   }
01308   //Store the tail of the buffer
01309   buf_1 = &(tmpbuf[0]);
01310   buf0  = &(tmpbuf[4]);
01311   buf1  = &(tmpbuf[8]);
01312   buf2  = &(tmpbuf[12]);
01313   memcpy((void*)tmpbuf,(void*)(buffer-16),sizeof(short)*16);
01314 
01315   if (!modeDDUonly && !fDCC_Trailer && !fDCC_Header) {
01316         fERROR[26] = true;
01317         bERROR|=0x4000000;
01318         fERROR[25] = true;
01319         bERROR|=0x2000000;
01320         fERROR[0]=true;
01321         bERROR|=0x1;
01322         return length;
01323         
01324   }
01325  
01326   return -2;
01327 }
01328 
01329 
01330 void CSCDCCExaminer::clear()
01331 {
01332   bzero(fERROR,   sizeof(bool)*nERRORS);
01333   bzero(fWARNING, sizeof(bool)*nWARNINGS);
01334   bERROR = 0; bWARNING = 0;
01335   for(int err=0; err<nERRORS;   ++err) fCHAMB_ERR[err].clear();
01336   for(int wrn=0; wrn<nWARNINGS; ++wrn) fCHAMB_WRN[wrn].clear();
01337   bCHAMB_ERR.clear();
01338   bCHAMB_WRN.clear();
01339   bCHAMB_PAYLOAD.clear();
01340   bCHAMB_STATUS.clear();
01341   bDDU_ERR.clear();
01342   bDDU_WRN.clear();
01343   dduBuffers.clear();
01344   dduOffsets.clear();
01345   dmbBuffers.clear();
01346   dmbOffsets.clear();
01347   dduSize.clear();
01348   dmbSize.clear();
01349 }
01350 
01351 
01352 void CSCDCCExaminer::zeroCounts()
01353 {
01354   ALCT_WordsSinceLastHeader = 0;
01355   ALCT_WordsSinceLastHeaderZeroSuppressed =0;
01356   ALCT_WordCount            = 0;
01357   ALCT_WordsExpected        = 0;
01358   ALCT_ZSE                  = 0;
01359   TMB_WordsSinceLastHeader  = 0;
01360   TMB_WordCount             = 0;
01361   TMB_WordsExpected         = 0;
01362   TMB_Tbins                 = 0;
01363   CFEB_SampleWordCount      = 0;
01364   CFEB_SampleCount          = 0;
01365   CFEB_BSampleCount         = 0;
01366 }
01367 
01368 
01369 void CSCDCCExaminer::checkDAVs() 
01370 {
01371   if( DAV_ALCT ){ 
01372     fERROR[21] = true;
01373     bERROR   |= 0x200000;
01374     fCHAMB_ERR[21].insert(currentChamber);
01375     bCHAMB_ERR[currentChamber] |= 0x200000;
01376     DAV_ALCT = false;
01377   }
01378   if( DAV_TMB  ){
01379     fERROR[22] = true;
01380     bERROR   |= 0x400000;
01381     fCHAMB_ERR[22].insert(currentChamber);
01382     bCHAMB_ERR[currentChamber] |= 0x400000;
01383     DAV_TMB = false;
01384   }
01385   if( DAV_CFEB && DAV_CFEB!=-16){
01386     fERROR[23] = true;
01387     bERROR   |= 0x800000;
01388     fCHAMB_ERR[23].insert(currentChamber);
01389     bCHAMB_ERR[currentChamber] |= 0x800000;
01390     DAV_CFEB = 0;
01391   }
01392 }
01393 
01394 
01395 void CSCDCCExaminer::checkTriggerHeadersAndTrailers()
01396 {   /*
01397     std::cout << " Ex-ALCT-Word-count " << std::endl;
01398     std::cout << " ALCT Words Since Last Header: " <<  ALCT_WordsSinceLastHeader << std::endl;
01399     std::cout << " ALCT Word Count: " <<  ALCT_WordCount << std::endl;
01400     std::cout << " ALCT Words Expected: " << ALCT_WordsExpected << std::endl;
01401     */
01402   if( !fALCT_Header && ( ALCT_WordsSinceLastHeader!=ALCT_WordCount || ALCT_WordsSinceLastHeader!=ALCT_WordsExpected )
01403     && ALCT_ZSE==0 ){
01404     fERROR[9] = true;
01405     bERROR   |= 0x200;
01406     fCHAMB_ERR[9].insert(currentChamber);
01407     bCHAMB_ERR[currentChamber] |= 0x200;
01408     ALCT_WordsSinceLastHeader = 0;
01409     ALCT_WordCount            = 0;
01410     ALCT_WordsSinceLastHeader = 0;
01411     ALCT_WordsExpected        = 0;
01412   } // ALCT Word Count Error
01413 
01414 if( !fALCT_Header && (ALCT_WordsSinceLastHeader!=ALCT_WordsExpected 
01415     || ALCT_WordsSinceLastHeaderZeroSuppressed!=ALCT_WordCount) && ALCT_ZSE!=0 ){
01416     fERROR[9] = true;
01417     bERROR   |= 0x200;
01418     fCHAMB_ERR[9].insert(currentChamber);
01419     bCHAMB_ERR[currentChamber] |= 0x200;
01420     ALCT_WordsSinceLastHeaderZeroSuppressed =0;
01421     ALCT_WordsSinceLastHeader = 0;
01422     ALCT_WordCount            = 0;
01423     ALCT_WordsSinceLastHeader = 0;
01424     ALCT_WordsExpected        = 0;
01425   } // ALCT Word Count Error With zero suppression
01426 
01427   if( !fTMB_Header && ( TMB_WordsSinceLastHeader!=TMB_WordCount || TMB_WordsSinceLastHeader!=TMB_WordsExpected ) ){
01428     fERROR[14] = true;
01429     bERROR    |= 0x4000;
01430     fCHAMB_ERR[14].insert(currentChamber);
01431     bCHAMB_ERR[currentChamber] |= 0x4000;
01432     TMB_WordsSinceLastHeader = 0;
01433     TMB_WordCount            = 0;
01434     TMB_WordsSinceLastHeader = 0;
01435     TMB_WordsExpected        = 0;
01436   } // TMB Word Count Error
01437 
01438   if( (CFEB_SampleCount%8)!=0 ){
01439     fERROR[17] = true;
01440     bERROR    |= 0x20000;
01441     fCHAMB_ERR[17].insert(currentChamber);
01442     bCHAMB_ERR[currentChamber] |= 0x20000;
01443     CFEB_SampleCount = 0;
01444   } // Number of CFEB samples != 8*n
01445 
01446   if(fALCT_Header) {
01447     fERROR[7] = true;  // ALCT Trailer is missing
01448     bERROR   |= 0x80;
01449     fCHAMB_ERR[7].insert(currentChamber);
01450     bCHAMB_ERR[currentChamber] |= 0x80;
01451     ALCT_WordsSinceLastHeaderZeroSuppressed =0;
01452     ALCT_WordsSinceLastHeader = 0;
01453     ALCT_WordsExpected        = 0;
01454     fALCT_Header = 0;
01455   }
01456 
01457   if(fTMB_Header) {
01458     fERROR[12]=true;        // TMB Trailer is missing
01459     bERROR   |= 0x1000;
01460     fCHAMB_ERR[12].insert(currentChamber);
01461     bCHAMB_ERR[currentChamber] |= 0x1000;
01462     TMB_WordsSinceLastHeader = 0;
01463     TMB_WordsExpected        = 0;
01464     fTMB_Header = false;
01465   }
01466 }
01467 
01468 inline int CSCDCCExaminer::scanbuf(const uint16_t* &buffer, int32_t length, uint16_t sig, uint16_t mask)
01469 {
01470         for (int i=0; i<length; i++)
01471         {
01472            if ( (buffer[i]&mask) == sig) { 
01473                 return i;
01474            }
01475         }
01476         return -1;
01477 }