CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/CSCTFRawToDigi/src/CSCTFEvent.cc

Go to the documentation of this file.
00001 #include "EventFilter/CSCTFRawToDigi/src/CSCTFEvent.h"
00002 #include "EventFilter/CSCTFRawToDigi/src/CSCSPHeader.h"
00003 #include <string.h>
00004 #include <stdexcept>
00005 
00006 unsigned int CSCTFEvent::unpack(const unsigned short *buf, unsigned int length) throw() {
00007         // Clean up
00008         nRecords = 0;
00009         bzero(sp,sizeof(sp));
00010 
00011         // Make sure that we are running right platform (can't imagine opposite)
00012         if( sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2 )
00013                 throw std::runtime_error(std::string("Wrong platform: sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2"));
00014 
00015         // Type of coruptions
00016         unsigned long coruptions=0;
00017 
00018         // Combine 64-bit ddu word for simlicity and efficiency
00019         unsigned long long *dduWord = (unsigned long long*) buf, word_1=0, word_2=0;
00020         // 'length' counts ddu words now
00021         length /= sizeof(unsigned long long)/sizeof(unsigned short);
00022         // Set of markers
00023         bool spHeader=false, spTrailer=false;
00024         unsigned long spWordCount=0, spWordCountExpected=0;
00025 
00026         // Run through the buffer and check its structure
00027         unsigned int index=0;
00028         while( index<length ){
00029                 word_1 = word_2;          // delay by 1 DDU word
00030                 word_2 = dduWord[index];  // current DDU word
00031 
00032                 if( spHeader && !spTrailer ) spWordCount++;
00033 
00034                 if( (word_1&0xF000F000F000F000LL)==0x9000900090009000LL &&
00035                         (word_2&0xF000F000F000F000LL)==0xA000A000A000A000LL ){
00036                         if( spHeader ){
00037                                 coruptions |= MISSING_TRAILER;
00038                                 break;
00039                         }
00040                         spHeader=true;
00041                         spTrailer=false;
00042                         // number of 64-bit words between header and trailer
00043                         spWordCount=0;
00044                         spWordCountExpected=0;
00045                         // need header to calculate expected word count
00046                         CSCSPHeader header;
00047                         const unsigned short *spWord = (unsigned short*) &dduWord[index-1];
00048                         // we are here because we have a header => we are safe from crash instantiating one
00049                         header.unpack(spWord);
00050 
00051                         // Counter block exists only in format version 4.3 and higher
00052                         if( header.format_version() && !header.empty() ){
00053                                 if( length > index+1 ){ spWord += 4; } else { coruptions |= OUT_OF_BUFFER; break; }
00054                         }
00055 
00056                         // Calculate expected record length (internal variable 'shift' counts 16-bit words)
00057                         for(unsigned short tbin=0,shift=0; tbin<header.nTBINs() && !header.empty(); tbin++){
00058                                 // check if didn't pass end of event, keep in mind that 'length', 'index', and 'spWordCountExpected' counts 64-bit words
00059                                 if( length <= index+spWordCountExpected+2 ){
00060                                         coruptions |= OUT_OF_BUFFER;
00061                                         break;
00062                                 } else {
00063                                         // In the format version >=5.3 with zero_supression
00064                                         if( header.format_version()>=3 && header.suppression() ){
00065                                                 //  we seek the loop index untill it matches the current non-empty tbin
00066                                                 if( ((spWord[shift+7]>>8) & 0x7) != tbin+1 ) continue;
00067                                                 //  otherwise there may be no more non-empty tbins and we ran into the trailer
00068                                                 if( (spWord[shift+0]&0xF000)==0xF000 && (spWord[shift+1]&0xF000)==0xF000 && (spWord[shift+2]&0xF000)==0xF000 && (spWord[shift+3]&0xF000)==0xF000 &&
00069                                                         (spWord[shift+4]&0xF000)==0xE000 && (spWord[shift+5]&0xF000)==0xE000 && (spWord[shift+6]&0xF000)==0xE000 && (spWord[shift+7]&0xF000)==0xE000 ) break;
00070                                         }
00071 
00072                                         // Data Block Header always exists if we got so far
00073                                         spWordCountExpected += 2;
00074                                         // 15 ME data blocks
00075                                         for(unsigned int me_block=0; me_block<15; me_block++)
00076                                                 if( header.active()&(1<<(me_block/3)) && (!header.suppression() || spWord[shift+0]&(1<<me_block)) )
00077                                                         spWordCountExpected += 1;
00078                                         // 2 MB data blocks
00079                                         for(unsigned int mb_block=0; mb_block<2; mb_block++)
00080                                                 if( header.active()&0x20 && (!header.suppression() || spWord[shift+1]&(1<<(mb_block+12))) )
00081                                                         spWordCountExpected += 1;
00082                                         // 3 SP data blocks
00083                                         for(unsigned int sp_block=0; sp_block<3; sp_block++)
00084                                                 if( header.active()&0x40 && (!header.suppression() || spWord[shift+1]&(0xF<<(sp_block*4))) )
00085                                                         spWordCountExpected += 1;
00086 
00087                                         shift = spWordCountExpected*4; // multiply by 4 because 'shift' is a 16-bit array index and 'spWordCountExpected' conuts 64-bit words
00088                                 }
00089                         }
00090 
00091                         // Counter block exists only in format version 4.3 and higher
00092                         if( header.format_version() && !header.empty() ) spWordCountExpected += 1;
00093 
00094                         if( coruptions&OUT_OF_BUFFER ) break;
00095                 }
00096 
00097                 //if( !spHeader && spTrailer ) coruptions |= NONSENSE; ///???
00098 
00099                 if( (word_1&0xF000F000F000F000LL)==0xF000F000F000F000LL &&
00100                         (word_2&0xF000F000F000F000LL)==0xE000E000E000E000LL ){
00101                         if( spTrailer ){
00102                                 coruptions |= MISSING_HEADER;
00103                                 break;
00104                         }
00105                         spHeader=false;
00106                         spTrailer=true;
00107 
00108                         if( spWordCount!=spWordCountExpected+2 ){
00109                                 coruptions |= WORD_COUNT;
00110                                 break;
00111                         }
00112                         // main unpacking
00113                         const unsigned short *spWord = (unsigned short*) &dduWord[index-spWordCount-1];
00114                         if( nRecords<12 ) {
00115                                 if( sp[nRecords++].unpack(spWord) ) coruptions |= NONSENSE;
00116                         } else {
00117                                 coruptions |= CONFIGURATION;
00118                                 break;
00119                         }
00120                 }
00121 
00122                 index++;
00123         }
00124 
00125         return coruptions;
00126 }