CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCTFEvent.cc
Go to the documentation of this file.
3 #include <string.h>
4 #include <stdexcept>
5 
6 unsigned int CSCTFEvent::unpack(const unsigned short *buf, unsigned int length) throw() {
7  // Clean up
8  nRecords = 0;
9  bzero(sp,sizeof(sp));
10 
11  // Make sure that we are running right platform (can't imagine opposite)
12  if( sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2 )
13  throw std::runtime_error(std::string("Wrong platform: sizeof(unsigned long long)!=8 || sizeof(unsigned short)!=2"));
14 
15  // Type of coruptions
16  unsigned long coruptions=0;
17 
18  // Combine 64-bit ddu word for simlicity and efficiency
19  unsigned long long *dduWord = (unsigned long long*) buf, word_1=0, word_2=0;
20  // 'length' counts ddu words now
21  length /= sizeof(unsigned long long)/sizeof(unsigned short);
22  // Set of markers
23  bool spHeader=false, spTrailer=false;
24  unsigned long spWordCount=0, spWordCountExpected=0;
25 
26  // Run through the buffer and check its structure
27  unsigned int index=0;
28  while( index<length ){
29  word_1 = word_2; // delay by 1 DDU word
30  word_2 = dduWord[index]; // current DDU word
31 
32  if( spHeader && !spTrailer ) spWordCount++;
33 
34  if( (word_1&0xF000F000F000F000LL)==0x9000900090009000LL &&
35  (word_2&0xF000F000F000F000LL)==0xA000A000A000A000LL ){
36  if( spHeader ){
37  coruptions |= MISSING_TRAILER;
38  break;
39  }
40  spHeader=true;
41  spTrailer=false;
42  // number of 64-bit words between header and trailer
43  spWordCount=0;
44  spWordCountExpected=0;
45  // need header to calculate expected word count
46  CSCSPHeader header;
47  const unsigned short *spWord = (unsigned short*) &dduWord[index-1];
48  // we are here because we have a header => we are safe from crash instantiating one
49  header.unpack(spWord);
50 
51  // Counter block exists only in format version 4.3 and higher
52  if( header.format_version() && !header.empty() ){
53  if( length > index+1 ){ spWord += 4; } else { coruptions |= OUT_OF_BUFFER; break; }
54  }
55 
56  // Calculate expected record length (internal variable 'shift' counts 16-bit words)
57  for(unsigned short tbin=0,shift=0; tbin<header.nTBINs() && !header.empty(); tbin++){
58  // check if didn't pass end of event, keep in mind that 'length', 'index', and 'spWordCountExpected' counts 64-bit words
59  if( length <= index+spWordCountExpected+2 ){
60  coruptions |= OUT_OF_BUFFER;
61  break;
62  } else {
63  // In the format version >=5.3 with zero_supression
64  if( header.format_version()>=3 && header.suppression() ){
65  // we seek the loop index untill it matches the current non-empty tbin
66  if( ((spWord[shift+7]>>8) & 0x7) != tbin+1 ) continue;
67  // otherwise there may be no more non-empty tbins and we ran into the trailer
68  if( (spWord[shift+0]&0xF000)==0xF000 && (spWord[shift+1]&0xF000)==0xF000 && (spWord[shift+2]&0xF000)==0xF000 && (spWord[shift+3]&0xF000)==0xF000 &&
69  (spWord[shift+4]&0xF000)==0xE000 && (spWord[shift+5]&0xF000)==0xE000 && (spWord[shift+6]&0xF000)==0xE000 && (spWord[shift+7]&0xF000)==0xE000 ) break;
70  }
71 
72  // Data Block Header always exists if we got so far
73  spWordCountExpected += 2;
74  // 15 ME data blocks
75  for(unsigned int me_block=0; me_block<15; me_block++)
76  if( header.active()&(1<<(me_block/3)) && (!header.suppression() || spWord[shift+0]&(1<<me_block)) )
77  spWordCountExpected += 1;
78  // 2 MB data blocks
79  for(unsigned int mb_block=0; mb_block<2; mb_block++)
80  if( header.active()&0x20 && (!header.suppression() || spWord[shift+1]&(1<<(mb_block+12))) )
81  spWordCountExpected += 1;
82  // 3 SP data blocks
83  for(unsigned int sp_block=0; sp_block<3; sp_block++)
84  if( header.active()&0x40 && (!header.suppression() || spWord[shift+1]&(0xF<<(sp_block*4))) )
85  spWordCountExpected += 1;
86 
87  shift = spWordCountExpected*4; // multiply by 4 because 'shift' is a 16-bit array index and 'spWordCountExpected' conuts 64-bit words
88  }
89  }
90 
91  // Counter block exists only in format version 4.3 and higher
92  if( header.format_version() && !header.empty() ) spWordCountExpected += 1;
93 
94  if( coruptions&OUT_OF_BUFFER ) break;
95  }
96 
97  //if( !spHeader && spTrailer ) coruptions |= NONSENSE; ///???
98 
99  if( (word_1&0xF000F000F000F000LL)==0xF000F000F000F000LL &&
100  (word_2&0xF000F000F000F000LL)==0xE000E000E000E000LL ){
101  if( spTrailer ){
102  coruptions |= MISSING_HEADER;
103  break;
104  }
105  spHeader=false;
106  spTrailer=true;
107 
108  if( spWordCount!=spWordCountExpected+2 ){
109  coruptions |= WORD_COUNT;
110  break;
111  }
112  // main unpacking
113  const unsigned short *spWord = (unsigned short*) &dduWord[index-spWordCount-1];
114  if( nRecords<12 ) {
115  if( sp[nRecords++].unpack(spWord) ) coruptions |= NONSENSE;
116  } else {
117  coruptions |= CONFIGURATION;
118  break;
119  }
120  }
121 
122  index++;
123  }
124 
125  return coruptions;
126 }
unsigned int unpack(const unsigned short *buf, unsigned int length)
Definition: CSCTFEvent.cc:6
bool suppression(void) const
Definition: CSCSPHeader.h:94
int format_version(void) const
Definition: CSCSPHeader.h:101
bool unpack(const unsigned short *&buf)
Definition: CSCSPHeader.h:104
unsigned int nTBINs(void) const
Definition: CSCSPHeader.h:92
#define NONSENSE
static unsigned int const shift
Definition: sp.h:21
bool empty(void) const
Definition: CSCSPHeader.h:99
unsigned int active(void) const
Definition: CSCSPHeader.h:97