CMS 3D CMS Logo

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