CMS 3D CMS Logo

CSCTMBData.cc
Go to the documentation of this file.
1 
8 
9 #include <iomanip> // dump for JK
10 #include <iostream>
11 #include <cstdio>
14 
15 #ifdef LOCAL_UNPACK
16 bool CSCTMBData::debug = false;
17 #else
18 std::atomic<bool> CSCTMBData::debug{false};
19 #endif
20 
22  : theOriginalBuffer(nullptr),
23  theB0CLine(0),
24  theE0FLine(0),
25  theTMBHeader(2007, 0x50c3),
26  theCLCTData(&theTMBHeader),
27  theTMBScopeIsPresent(false),
28  theTMBScope(nullptr),
29  theTMBMiniScopeIsPresent(false),
30  theTMBMiniScope(nullptr),
31  theBlockedCFEBIsPresent(false),
32  theTMBBlockedCFEB(nullptr),
33  theTMBTrailer(theTMBHeader.sizeInWords() + theCLCTData.sizeInWords(), 2007),
34  size_(0),
35  cWordCnt(0),
36  theRPCDataIsPresent(false) {}
37 
38 CSCTMBData::CSCTMBData(int firmwareVersion, int firmwareRevision, int cfebs)
40  theB0CLine(0),
41  theE0FLine(0),
42  theTMBHeader(firmwareVersion, firmwareRevision),
50  theTMBTrailer(theTMBHeader.sizeInWords() + theCLCTData.sizeInWords(), firmwareVersion),
51  size_(0),
52  cWordCnt(0),
54  theTMBHeader.setNCFEBs(cfebs);
57 }
58 
59 CSCTMBData::CSCTMBData(const uint16_t* buf)
60  : theOriginalBuffer(buf),
61  theTMBHeader(2007, 0x50c3),
69  theTMBTrailer(theTMBHeader.sizeInWords() + theCLCTData.sizeInWords(), 2007),
71  size_ = UnpackTMB(buf);
72 }
73 
74 // Explicitly-defined copy constructor is needed when the scope data is
75 // present, to prevent the same pointer from being deleted twice. -SV.
78  theB0CLine(data.theB0CLine),
79  theE0FLine(data.theE0FLine),
82  theRPCData(data.theRPCData),
87  size_(data.size_),
88  cWordCnt(data.cWordCnt),
91  theTMBScope = new CSCTMBScope(*(data.theTMBScope));
92  } else {
93  theTMBScope = nullptr;
94  }
95 
98  } else {
99  theTMBMiniScope = nullptr;
100  }
101 
104  } else {
105  theTMBBlockedCFEB = nullptr;
106  }
107 }
108 
110  if (theTMBScopeIsPresent) {
111  delete theTMBScope;
112  theTMBScopeIsPresent = false;
113  }
114 
116  delete theTMBMiniScope;
117  theTMBMiniScopeIsPresent = false;
118  }
119 
121  delete theTMBBlockedCFEB;
122  theBlockedCFEBIsPresent = false;
123  }
124 }
125 
128 int findLine(const uint16_t* buf, uint16_t marker, int first, int maxToDo) {
129  for (int i = first; i < maxToDo; ++i) {
130  if (buf[i] == marker) {
131  return i;
132  }
133  }
134  return -1;
135 }
136 
138  std::vector<std::bitset<16> > theTotalTMBData(theE0FLine + 1 - theB0CLine);
139  unsigned i = 0;
140  for (unsigned int line = theB0CLine; line < theE0FLine + 1; ++line) {
141  theTotalTMBData[i] = std::bitset<16>(theOriginalBuffer[line]);
142  ++i;
143  }
144  if (!theTotalTMBData.empty()) {
145  std::bitset<22> CRC = calCRC22(theTotalTMBData);
146  LogTrace("CSCTMBData|CSCRawToDigi") << " Test here " << CRC.to_ulong();
147  return CRC.to_ulong();
148  } else {
149  LogTrace("CSCTMBData|CSCRawToDigi") << "theTotalTMBData doesn't exist";
150  return 0;
151  }
152 }
153 
154 int CSCTMBData::UnpackTMB(const uint16_t* buf) {
156  unsigned short int firmwareVersion = 0;
157  int Ntbins = 0;
158  int NRPCtbins = 0; // =VB= number of RPC tbins
159 
160  int b0cLine = 0;
161 
164  if (buf[b0cLine] == 0xdb0c) {
165  firmwareVersion = 2007;
166  Ntbins = buf[b0cLine + 19] & 0xF8;
167  NRPCtbins = (buf[b0cLine + 36] >> 5) & 0x1F; // =VB= get RPC tbins
168  } else if (buf[b0cLine] == 0x6b0c) {
169  firmwareVersion = 2006;
170  Ntbins = buf[b0cLine + 1] & 0x1f;
171  NRPCtbins = Ntbins;
172  } else {
173  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ Can't find b0C flag";
174  }
175 
176  if ((firmwareVersion == 2007) &&
177  (!(((buf[b0cLine] & 0xFFFF) == 0xDB0C) && ((buf[b0cLine + 1] & 0xf000) == 0xD000) &&
178  ((buf[b0cLine + 2] & 0xf000) == 0xD000) && ((buf[b0cLine + 3] & 0xf000) == 0xD000)))) {
179  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: error in header in 2007 format!";
180  }
181 
182  int MaxSizeRPC = 1 + NRPCtbins * 2 * 4 + 1;
183  //int MaxSizeScope = 5;
184  int e0bLine = -1;
185  switch (firmwareVersion) {
186  case 2007:
187  e0bLine = 42; //last word of header2007
188  break;
189  case 2006:
190  e0bLine = 26; //last word of header in 2006 format
191  break;
192  default:
193  edm::LogError("CSCTMBData|CSCRawToDigi") << "+++ undetermined firmware format - cant find e0bLine";
194  }
195 
196  theTMBHeader = CSCTMBHeader(buf);
197 
198  if (!theTMBHeader.check()) {
199  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad TMB header e0bLine=" << std::hex
200  << buf[e0bLine];
201  return 0;
202  }
203 
204  int currentPosition = theTMBHeader.sizeInWords();
205  int theFirmwareVersion = theTMBHeader.FirmwareVersion();
206 
207  theCLCTData = CSCCLCTData(theTMBHeader.NCFEBs(), theTMBHeader.NTBins(), buf + e0bLine + 1, theFirmwareVersion);
208 
209  if (!theCLCTData.check()) {
210  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad CLCT data";
211  } else {
212  currentPosition += theCLCTData.sizeInWords();
213  }
214 
215  //int i = currentPosition-1;
216  //printf ( "%04x %04x %04x %04x\n",buf[i+3],buf[i+2],buf[i+1],buf[i] ) ;
217 
218  // look for RPC
219  int b04Line = currentPosition;
220 
221  if (buf[b04Line] == 0x6b04) {
222  // we need an e04 line to calculate the size
223  int e04Line = findLine(buf, 0x6e04, currentPosition, currentPosition + MaxSizeRPC);
224  if (e04Line != -1) {
225  theRPCDataIsPresent = true;
226  theRPCData = CSCRPCData(buf + b04Line, e04Line - b04Line + 1);
227  currentPosition += theRPCData.sizeInWords();
228  } else {
229  LogTrace("CSCTMBData|CSCRawToDigi") << "CSCTMBData::corrupt RPC data! Failed to find end! ";
230  return 0;
231  }
232  }
233 
234  int TotTMBReadout = 0;
235  switch (firmwareVersion) {
236  case 2007:
237  TotTMBReadout = 43 + Ntbins * 6 * 5 + 1 + NRPCtbins * 2 * 4 + 2 + 8 * 256 + 8;
238  break;
239  case 2006:
240  TotTMBReadout =
241  27 + Ntbins * 6 * 5 + 1 + NRPCtbins * 2 * 4 + 2 + 8 * 256 + 8; //see tmb2004 manual (version v2p06) page54.
242  break;
243  default:
244  edm::LogError("CSCTMBData|CSCRawToDigi") << "can't find TotTMBReadout - unknown firmware version!";
245  break;
246  }
247 
248  //std::cout << " !!!TMB Scope!!! " << std::endl;
249  if (buf[currentPosition] == 0x6b05) {
250  int b05Line = currentPosition;
251  LogTrace("CSCTMBData|CSCRawToDigi") << "found scope!";
252  int e05Line = findLine(buf, 0x6e05, currentPosition, TotTMBReadout - currentPosition);
253  if (e05Line != -1) {
254  theTMBScopeIsPresent = true;
255  theTMBScope = new CSCTMBScope(buf, b05Line, e05Line);
256  // The size of the TMB scope data can vary, and I see no good reasons
257  // not to determine it dynamically. -SV, 5 Nov 2008.
258  //currentPosition+=theTMBScope->sizeInWords();
259  currentPosition += (e05Line - b05Line + 1);
260  } else {
261  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: found 0x6b05 line, but not 0x6e05! +++";
262  }
263  }
264 
266  if (buf[currentPosition] == 0x6b07) {
267  int Line6b07 = currentPosition;
268  LogTrace("CSCTMBData") << " TMBData ---> Begin of MiniScope found ";
269  int Line6E07 = findLine(buf, 0x6E07, currentPosition, TotTMBReadout - currentPosition);
270  if (Line6E07 != -1) {
271  LogTrace("CSCTMBData") << " TMBData --> End of MiniScope found " << Line6E07 - Line6b07 + 1 << " words ";
273  theTMBMiniScope = new CSCTMBMiniScope(buf, Line6b07, Line6E07);
274  currentPosition += (Line6E07 - Line6b07 + 1);
275  } else {
276  LogTrace("CSCTMBData") << "+++ CSCTMBData warning MiniScope!: found 0x6b07 line, but not 0x6e07! +++";
277  }
278  }
280 
282  if (buf[currentPosition] == 0x6BCB) {
283  int Line6BCB = currentPosition;
284  LogTrace("CSCTMBData") << " TMBData ---> Begin of Blocked CFEB found ";
285  int Line6ECB = findLine(buf, 0x6ECB, currentPosition, TotTMBReadout - currentPosition);
286  if (Line6ECB != -1) {
287  LogTrace("CSCTMBData") << " TMBData --> End of Blocked CFEB found " << Line6ECB - Line6BCB + 1 << " words ";
289  theTMBBlockedCFEB = new CSCTMBBlockedCFEB(buf, Line6BCB, Line6ECB);
290  currentPosition += (Line6ECB - Line6BCB + 1);
291  } else {
292  LogTrace("CSCTMBData") << "+++ CSCTMBData warning Blocked CFEB!: found 0x6BCB line, but not 0x6ECB! +++";
293  }
294  }
296 
297  int maxLine = findLine(buf, 0xde0f, currentPosition, TotTMBReadout - currentPosition);
298  if (maxLine == -1) {
299  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0f line!";
300  return 0;
301  }
302 
303  //Now for CRC check put this information into bitset
304 
305  theB0CLine = b0cLine;
306  theE0FLine = maxLine;
307 
308  // finally, the trailer
309  int e0cLine = findLine(buf, 0x6e0c, currentPosition, maxLine);
310  if (e0cLine == -1) {
311  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0c line!";
312  } else {
313  theTMBTrailer = CSCTMBTrailer(buf + e0cLine, firmwareVersion);
314  LogTrace("CSCTMBData|CSCRawToDigi") << "TMB trailer size: " << theTMBTrailer.sizeInWords();
315  }
316 
317  checkSize();
318 
319  // Dump of TMB; format proposed by JK.
320 #ifdef TMBDUMP
321  LogTrace("CSCTMBData") << "Dump of TMB data:";
322  for (int line = b0cLine; line <= maxLine + 3; line++) {
323  LogTrace("CSCTMBData") << "Adr= " << std::setw(4) << line << " Data= " << std::setfill('0') << std::setw(5)
324  << std::uppercase << std::hex << buf[line] << std::dec << std::endl;
325  }
326 #endif
327 
328  // size, since we count from 0 and have one more trailer word
329  // there are sometimes multiple "de0f" lines in trailer, so key on "6e0c"
330  return e0cLine - b0cLine + theTMBTrailer.sizeInWords();
331 } //UnpackTMB
332 
333 bool CSCTMBData::checkSize() const {
334  // sum up all the components and see if they have the size indicated in the TMBTrailer
335  return true;
336 }
337 
338 std::bitset<22> CSCTMBData::calCRC22(const std::vector<std::bitset<16> >& datain) {
339  std::bitset<22> CRC;
340  CRC.reset();
341  for (unsigned int i = 0; i < datain.size() - 3; ++i) {
342  CRC = nextCRC22_D16(datain[i], CRC);
343  }
344  return CRC;
345 }
346 
349  throw("No TMBScope in this chamber");
350  return *theTMBScope;
351 }
352 
355  throw("No TMBScope in this chamber");
356  return *theTMBMiniScope;
357 }
358 
361  throw("No TMB Blocked CFEB in this chamber");
362  return *theTMBBlockedCFEB;
363 }
364 
365 std::bitset<22> CSCTMBData::nextCRC22_D16(const std::bitset<16>& D, const std::bitset<22>& C) {
366  std::bitset<22> NewCRC;
367 
368  NewCRC[0] = D[0] ^ C[6];
369  NewCRC[1] = D[1] ^ D[0] ^ C[6] ^ C[7];
370  NewCRC[2] = D[2] ^ D[1] ^ C[7] ^ C[8];
371  NewCRC[3] = D[3] ^ D[2] ^ C[8] ^ C[9];
372  NewCRC[4] = D[4] ^ D[3] ^ C[9] ^ C[10];
373  NewCRC[5] = D[5] ^ D[4] ^ C[10] ^ C[11];
374  NewCRC[6] = D[6] ^ D[5] ^ C[11] ^ C[12];
375  NewCRC[7] = D[7] ^ D[6] ^ C[12] ^ C[13];
376  NewCRC[8] = D[8] ^ D[7] ^ C[13] ^ C[14];
377  NewCRC[9] = D[9] ^ D[8] ^ C[14] ^ C[15];
378  NewCRC[10] = D[10] ^ D[9] ^ C[15] ^ C[16];
379  NewCRC[11] = D[11] ^ D[10] ^ C[16] ^ C[17];
380  NewCRC[12] = D[12] ^ D[11] ^ C[17] ^ C[18];
381  NewCRC[13] = D[13] ^ D[12] ^ C[18] ^ C[19];
382  NewCRC[14] = D[14] ^ D[13] ^ C[19] ^ C[20];
383  NewCRC[15] = D[15] ^ D[14] ^ C[20] ^ C[21];
384  NewCRC[16] = D[15] ^ C[0] ^ C[21];
385  NewCRC[17] = C[1];
386  NewCRC[18] = C[2];
387  NewCRC[19] = C[3];
388  NewCRC[20] = C[4];
389  NewCRC[21] = C[5];
390 
391  return NewCRC;
392 }
393 
394 boost::dynamic_bitset<> CSCTMBData::pack() {
395  boost::dynamic_bitset<> result =
397  boost::dynamic_bitset<> clctData =
399  result = bitset_utilities::append(result, clctData);
400  boost::dynamic_bitset<> newResult = result;
401  // theTMBTrailer.setCRC(TMBCRCcalc());
402 
403  boost::dynamic_bitset<> tmbTrailer =
405  result = bitset_utilities::append(result, tmbTrailer);
406 
407  // now convert to a vector<bitset<16>>, so we can calculate the crc
408  std::vector<std::bitset<16> > wordVector;
409  // try to tune so it stops before the e0f line
410  for (unsigned pos = 0; pos < result.size() - 16; pos += 16) {
411  std::bitset<16> word;
412  for (int i = 0; i < 16; ++i) {
413  word[i] = result[pos + i];
414  }
415  wordVector.push_back(word);
416  }
417  theTMBTrailer.setCRC(calCRC22(wordVector).to_ulong());
419  newResult = bitset_utilities::append(newResult, tmbTrailer);
420 
421  return newResult;
422 }
423 
425  CSCTMBData tmbData;
426  cscClassPackerCompare(tmbData);
427 }
int sizeInWords() const
in 16-bit words
Definition: CSCCLCTData.h:41
CSCTMBTrailer * tmbTrailer()
Definition: CSCTMBData.h:50
unsigned theE0FLine
Definition: CSCTMBData.h:74
CSCCLCTData * clctData()
Definition: CSCTMBData.h:40
bool theRPCDataIsPresent
Definition: CSCTMBData.h:99
uint16_t NTBins() const
Definition: CSCTMBHeader.h:56
CSCTMBTrailer theTMBTrailer
Definition: CSCTMBData.h:91
static void selfTest()
tests packing
Definition: CSCTMBData.cc:424
int TMBCRCcalc()
Definition: CSCTMBData.cc:137
boost::dynamic_bitset pack()
not const because it sets size int TMBTrailer
Definition: CSCTMBData.cc:394
bool theBlockedCFEBIsPresent
Definition: CSCTMBData.h:88
boost::dynamic_bitset append(const boost::dynamic_bitset<> &bs1, const boost::dynamic_bitset<> &bs2)
this method takes two bitsets bs1 and bs2 and returns result of bs2 appended to the end of bs1 ...
#define nullptr
std::bitset< 22 > nextCRC22_D16(const std::bitset< 16 > &D, const std::bitset< 22 > &C)
Definition: CSCTMBData.cc:365
unsigned short size_
Definition: CSCTMBData.h:97
bool theTMBMiniScopeIsPresent
Definition: CSCTMBData.h:85
int sizeInWords() const
in 16-bit frames
Definition: CSCTMBTrailer.h:42
unsigned theB0CLine
Definition: CSCTMBData.h:73
CSCRPCData theRPCData
Definition: CSCTMBData.h:78
CSCTMBBlockedCFEB & tmbBlockedCFEB() const
Definition: CSCTMBData.cc:359
unsigned short * data()
Definition: CSCTMBTrailer.h:43
bool cscClassPackerCompare(T &t)
uint16_t NCFEBs() const
Definition: CSCTMBHeader.h:57
std::bitset< 22 > calCRC22(const std::vector< std::bitset< 16 > > &datain)
Definition: CSCTMBData.cc:338
void setNCFEBs(uint16_t ncfebs)
Definition: CSCTMBHeader.h:64
uint64_t word
CSCTMBHeader theTMBHeader
Definition: CSCTMBData.h:76
static std::atomic< bool > debug
Definition: CSCTMBData.h:95
CSCTMBBlockedCFEB * theTMBBlockedCFEB
Definition: CSCTMBData.h:89
unsigned short * data()
Definition: CSCCLCTData.h:39
const uint16_t * theOriginalBuffer
Definition: CSCTMBData.h:70
unsigned short * data()
Definition: CSCTMBHeader.h:80
CSCTMBScope & tmbScope() const
Definition: CSCTMBData.cc:347
void setCRC(int crc)
int sizeInWords()
Definition: CSCRPCData.h:21
#define LogTrace(id)
unsigned short cWordCnt
Definition: CSCTMBData.h:98
unsigned short int sizeInWords() const
Definition: CSCTMBHeader.h:76
CSCTMBMiniScope * theTMBMiniScope
Definition: CSCTMBData.h:86
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
bool theTMBScopeIsPresent
The TMB scope is not present in most of data hence its dynamic.
Definition: CSCTMBData.h:80
bool check() const
Definition: CSCCLCTData.cc:296
bool check() const
Definition: CSCTMBHeader.h:85
CSCTMBScope * theTMBScope
Definition: CSCTMBData.h:81
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
int findLine(const uint16_t *buf, uint16_t marker, int first, int maxToDo)
Definition: CSCTMBData.cc:128
int FirmwareVersion() const
Definition: CSCTMBHeader.h:34
bool checkSize() const
sees if the size adds up to the word count
Definition: CSCTMBData.cc:333
boost::dynamic_bitset ushortToBitset(const unsigned int numberOfBits, unsigned short *buf)
this method takes numberOfBits bits from unsigned short * array and returns them in the bitset obj...
int UnpackTMB(const uint16_t *buf)
Definition: CSCTMBData.cc:154
CSCCLCTData theCLCTData
Definition: CSCTMBData.h:77
CSCTMBMiniScope & tmbMiniScope() const
Definition: CSCTMBData.cc:353