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  theComparatorData(&theTMBHeader),
27  theGEMData(),
28  theTMBScopeIsPresent(false),
29  theTMBScope(nullptr),
30  theTMBMiniScopeIsPresent(false),
31  theTMBMiniScope(nullptr),
32  theBlockedCFEBIsPresent(false),
33  theTMBBlockedCFEB(nullptr),
34  theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), 2007),
35  size_(0),
36  cWordCnt(0),
37  theRPCDataIsPresent(false),
38  theGEMDataIsPresent(false) {}
39 
40 CSCTMBData::CSCTMBData(int firmwareVersion, int firmwareRevision, int cfebs)
41  : theOriginalBuffer(nullptr),
42  theB0CLine(0),
43  theE0FLine(0),
44  theTMBHeader(firmwareVersion, firmwareRevision),
45  theComparatorData(&theTMBHeader),
46  theGEMData(), // allocate 12 GEM tbins, 0xf - 4 GEM fibers enabled
47  theTMBScopeIsPresent(false),
48  theTMBScope(nullptr),
49  theTMBMiniScopeIsPresent(false),
50  theTMBMiniScope(nullptr),
51  theBlockedCFEBIsPresent(false),
52  theTMBBlockedCFEB(nullptr),
53  theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), firmwareVersion),
54  size_(0),
55  cWordCnt(0),
56  theRPCDataIsPresent(false),
57  theGEMDataIsPresent(false) {
58  theTMBHeader.setNCFEBs(cfebs);
62  if ((firmwareVersion == 2020) && (((firmwareRevision >> 9) & 0x3) == 3)) {
63  theGEMDataIsPresent = true;
64  wordCnt += theGEMData.sizeInWords();
65  }
67 }
68 
69 CSCTMBData::CSCTMBData(const uint16_t* buf)
70  : theOriginalBuffer(buf),
71  theTMBHeader(2007, 0x50c3),
72  theComparatorData(&theTMBHeader),
73  theTMBScopeIsPresent(false),
74  theTMBScope(nullptr),
75  theTMBMiniScopeIsPresent(false),
76  theTMBMiniScope(nullptr),
77  theBlockedCFEBIsPresent(false),
78  theTMBBlockedCFEB(nullptr),
79  theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), 2007),
80  theRPCDataIsPresent(false),
81  theGEMDataIsPresent(false) {
82  size_ = UnpackTMB(buf);
83 }
84 
85 // Explicitly-defined copy constructor is needed when the scope data is
86 // present, to prevent the same pointer from being deleted twice. -SV.
88  : theOriginalBuffer(data.theOriginalBuffer),
89  theB0CLine(data.theB0CLine),
90  theE0FLine(data.theE0FLine),
91  theTMBHeader(data.theTMBHeader),
92  theComparatorData(data.theComparatorData),
93  theRPCData(data.theRPCData),
94  theGEMData(data.theGEMData),
95  theTMBScopeIsPresent(data.theTMBScopeIsPresent),
96  theTMBMiniScopeIsPresent(data.theTMBMiniScopeIsPresent),
97  theBlockedCFEBIsPresent(data.theBlockedCFEBIsPresent),
98  theTMBTrailer(data.theTMBTrailer),
99  size_(data.size_),
100  cWordCnt(data.cWordCnt),
101  theRPCDataIsPresent(data.theRPCDataIsPresent),
102  theGEMDataIsPresent(data.theGEMDataIsPresent) {
103  if (theTMBScopeIsPresent) {
104  theTMBScope = new CSCTMBScope(*(data.theTMBScope));
105  } else {
106  theTMBScope = nullptr;
107  }
108 
110  theTMBMiniScope = new CSCTMBMiniScope(*(data.theTMBMiniScope));
111  } else {
112  theTMBMiniScope = nullptr;
113  }
114 
116  theTMBBlockedCFEB = new CSCTMBBlockedCFEB(*(data.theTMBBlockedCFEB));
117  } else {
118  theTMBBlockedCFEB = nullptr;
119  }
120 }
121 
123  if (theTMBScopeIsPresent) {
124  delete theTMBScope;
125  theTMBScopeIsPresent = false;
126  }
127 
129  delete theTMBMiniScope;
130  theTMBMiniScopeIsPresent = false;
131  }
132 
134  delete theTMBBlockedCFEB;
135  theBlockedCFEBIsPresent = false;
136  }
137 }
138 
141 int findLine(const uint16_t* buf, uint16_t marker, int first, int maxToDo) {
142  for (int i = first; i < maxToDo; ++i) {
143  if (buf[i] == marker) {
144  return i;
145  }
146  }
147  return -1;
148 }
149 
151  std::vector<std::bitset<16> > theTotalTMBData(theE0FLine + 1 - theB0CLine);
152  unsigned i = 0;
153  for (unsigned int line = theB0CLine; line < theE0FLine + 1; ++line) {
154  theTotalTMBData[i] = std::bitset<16>(theOriginalBuffer[line]);
155  ++i;
156  }
157  if (!theTotalTMBData.empty()) {
158  std::bitset<22> CRC = calCRC22(theTotalTMBData);
159  LogTrace("CSCTMBData|CSCRawToDigi") << " Test here " << CRC.to_ulong();
160  return CRC.to_ulong();
161  } else {
162  LogTrace("CSCTMBData|CSCRawToDigi") << "theTotalTMBData doesn't exist";
163  return 0;
164  }
165 }
166 
167 int CSCTMBData::UnpackTMB(const uint16_t* buf) {
169  unsigned short int firmwareVersion = 0;
170  unsigned short int firmwareRevision = 0;
171  int Ntbins = 0;
172  int NRPCtbins = 0; // Number of RPC tbins
173  int NGEMtbins = 0; // Number of GEM tbins
174  int NGEMEnabled = 0; // Number of Enabled GEM Fibers
175  int GEMFibersMask = 0;
176  bool isGEMfirmware = false;
177 
178  int b0cLine = 0;
179 
182  if (buf[b0cLine] == 0xdb0c) {
183  firmwareVersion = 2007;
184  firmwareRevision = buf[b0cLine + 7] & 0x7fff;
185  Ntbins = buf[b0cLine + 19] & 0xF8;
186  if ((firmwareRevision < 0x4000) /* New Run3 (O)TMB firmware revision format */
187  && (((firmwareRevision >> 9) & 0x3) == 0x3))
188  isGEMfirmware = true;
189 
190  if (isGEMfirmware) {
191  GEMFibersMask = buf[b0cLine + 36] & 0xf; // GEM enabled fibers 4-bits mask
193  // for (int i = 0; i < 4; i++)
194  // NGEMEnabled += (buf[b0cLine + 36] >> i) & 0x1; // Get number of enabled GEM fibers
195  NGEMEnabled = 4; // Currently always assume that all 4 fibers are enabled
196  NGEMtbins = (buf[b0cLine + 36] >> 5) & 0x1F; // Get GEM tbins
197  }
198  NRPCtbins = (buf[b0cLine + 36] >> 5) & 0x1F; // Get RPC tbins
199  } else if (buf[b0cLine] == 0x6b0c) {
200  firmwareVersion = 2006;
201  Ntbins = buf[b0cLine + 1] & 0x1f;
202  NRPCtbins = Ntbins;
203  } else {
204  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ Can't find b0C flag";
205  }
206 
207  if ((firmwareVersion == 2007) &&
208  (!(((buf[b0cLine] & 0xFFFF) == 0xDB0C) && ((buf[b0cLine + 1] & 0xf000) == 0xD000) &&
209  ((buf[b0cLine + 2] & 0xf000) == 0xD000) && ((buf[b0cLine + 3] & 0xf000) == 0xD000)))) {
210  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: error in header in 2007 format!";
211  }
212 
213  int MaxSizeRPC = 1 + NRPCtbins * 2 * 4 + 1;
214  int MaxSizeGEM = 1 + NGEMEnabled * NGEMtbins * 4 + 1;
215  //int MaxSizeScope = 5;
216  int e0bLine = -1;
217  switch (firmwareVersion) {
218  case 2007:
219  e0bLine = 42; //last word of header2007
220  break;
221  case 2006:
222  e0bLine = 26; //last word of header in 2006 format
223  break;
224  default:
225  edm::LogError("CSCTMBData|CSCRawToDigi") << "+++ undetermined firmware format - cant find e0bLine";
226  }
227 
229 
230  if (!theTMBHeader.check()) {
231  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad TMB header e0bLine=" << std::hex
232  << buf[e0bLine];
233  return 0;
234  }
235 
236  int currentPosition = theTMBHeader.sizeInWords();
237  int theFirmwareVersion = theTMBHeader.FirmwareVersion();
238 
240  CSCComparatorData(theTMBHeader.NCFEBs(), theTMBHeader.NTBins(), buf + e0bLine + 1, theFirmwareVersion);
241 
242  if (!theComparatorData.check()) {
243  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad CLCT data";
244  } else {
245  currentPosition += theComparatorData.sizeInWords();
246  }
247 
248  // look for RPC data
249  int b04Line = currentPosition;
250 
251  if (buf[b04Line] == 0x6b04) {
252  // we need an e04 line to calculate the size
253  int e04Line = findLine(buf, 0x6e04, currentPosition, currentPosition + MaxSizeRPC);
254  if (e04Line != -1) {
255  theRPCDataIsPresent = true;
256  theRPCData = CSCRPCData(buf + b04Line, e04Line - b04Line + 1);
257  currentPosition += theRPCData.sizeInWords();
258  } else {
259  LogTrace("CSCTMBData|CSCRawToDigi") << "CSCTMBData::corrupt RPC data! Failed to find end! ";
260  return 0;
261  }
262  }
263 
264  // look for GEM data
265  int c04Line = currentPosition;
266 
267  if (buf[c04Line] == 0x6c04) {
268  // we need an d04 line to calculate the size
269  int d04Line = findLine(buf, 0x6d04, currentPosition, currentPosition + MaxSizeGEM);
270  if (d04Line != -1) {
271  theGEMDataIsPresent = true;
272  theGEMData = CSCGEMData(buf + c04Line, d04Line - c04Line + 1, GEMFibersMask);
273  currentPosition += theGEMData.sizeInWords();
274  } else {
275  LogTrace("CSCTMBData|CSCRawToDigi") << "CSCTMBData::corrupt GEM data! Failed to find end! ";
276  return 0;
277  }
278  }
279 
280  int TotTMBReadout = 0;
281  switch (firmwareVersion) {
282  case 2007:
283  if (theGEMDataIsPresent) {
284  TotTMBReadout = 43 + Ntbins * 6 * 5 + 1 + NGEMEnabled * NGEMtbins * 4 + 2 + 8 * 256 + 8;
285  } else {
286  TotTMBReadout = 43 + Ntbins * 6 * 5 + 1 + NRPCtbins * 2 * 4 + 2 + 8 * 256 + 8;
287  };
288  break;
289  case 2006:
290  TotTMBReadout =
291  27 + Ntbins * 6 * 5 + 1 + NRPCtbins * 2 * 4 + 2 + 8 * 256 + 8; //see tmb2004 manual (version v2p06) page54.
292  break;
293  default:
294  edm::LogError("CSCTMBData|CSCRawToDigi") << "can't find TotTMBReadout - unknown firmware version!";
295  break;
296  }
297 
298  //std::cout << " !!!TMB Scope!!! " << std::endl;
299  if (buf[currentPosition] == 0x6b05) {
300  int b05Line = currentPosition;
301  LogTrace("CSCTMBData|CSCRawToDigi") << "found scope!";
302  int e05Line = findLine(buf, 0x6e05, currentPosition, TotTMBReadout - currentPosition);
303  if (e05Line != -1) {
304  theTMBScopeIsPresent = true;
305  theTMBScope = new CSCTMBScope(buf, b05Line, e05Line);
306  // The size of the TMB scope data can vary, and I see no good reasons
307  // not to determine it dynamically. -SV, 5 Nov 2008.
308  //currentPosition+=theTMBScope->sizeInWords();
309  currentPosition += (e05Line - b05Line + 1);
310  } else {
311  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: found 0x6b05 line, but not 0x6e05! +++";
312  }
313  }
314 
316  if (buf[currentPosition] == 0x6b07) {
317  int Line6b07 = currentPosition;
318  LogTrace("CSCTMBData") << " TMBData ---> Begin of MiniScope found ";
319  int Line6E07 = findLine(buf, 0x6E07, currentPosition, TotTMBReadout - currentPosition);
320  if (Line6E07 != -1) {
321  LogTrace("CSCTMBData") << " TMBData --> End of MiniScope found " << Line6E07 - Line6b07 + 1 << " words ";
323  theTMBMiniScope = new CSCTMBMiniScope(buf, Line6b07, Line6E07);
324  currentPosition += (Line6E07 - Line6b07 + 1);
325  } else {
326  LogTrace("CSCTMBData") << "+++ CSCTMBData warning MiniScope!: found 0x6b07 line, but not 0x6e07! +++";
327  }
328  }
330 
332  if (buf[currentPosition] == 0x6BCB) {
333  int Line6BCB = currentPosition;
334  LogTrace("CSCTMBData") << " TMBData ---> Begin of Blocked CFEB found ";
335  int Line6ECB = findLine(buf, 0x6ECB, currentPosition, TotTMBReadout - currentPosition);
336  if (Line6ECB != -1) {
337  LogTrace("CSCTMBData") << " TMBData --> End of Blocked CFEB found " << Line6ECB - Line6BCB + 1 << " words ";
339  theTMBBlockedCFEB = new CSCTMBBlockedCFEB(buf, Line6BCB, Line6ECB);
340  currentPosition += (Line6ECB - Line6BCB + 1);
341  } else {
342  LogTrace("CSCTMBData") << "+++ CSCTMBData warning Blocked CFEB!: found 0x6BCB line, but not 0x6ECB! +++";
343  }
344  }
346 
347  int maxLine = findLine(buf, 0xde0f, currentPosition, TotTMBReadout - currentPosition);
348  if (maxLine == -1) {
349  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0f line!";
350  return 0;
351  }
352 
353  //Now for CRC check put this information into bitset
354 
355  theB0CLine = b0cLine;
356  theE0FLine = maxLine;
357 
358  // finally, the trailer
359  int e0cLine = findLine(buf, 0x6e0c, currentPosition, maxLine);
360  if (e0cLine == -1) {
361  LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0c line!";
362  } else {
364  LogTrace("CSCTMBData|CSCRawToDigi") << "TMB trailer size: " << theTMBTrailer.sizeInWords();
365  }
366 
367  checkSize();
368 
369  // Dump of TMB; format proposed by JK.
370 #ifdef TMBDUMP
371  LogTrace("CSCTMBData") << "Dump of TMB data:";
372  for (int line = b0cLine; line <= maxLine + 3; line++) {
373  LogTrace("CSCTMBData") << "Adr= " << std::setw(4) << line << " Data= " << std::setfill('0') << std::setw(5)
374  << std::uppercase << std::hex << buf[line] << std::dec << std::endl;
375  }
376 #endif
377 
378  // size, since we count from 0 and have one more trailer word
379  // there are sometimes multiple "de0f" lines in trailer, so key on "6e0c"
380  return e0cLine - b0cLine + theTMBTrailer.sizeInWords();
381 } //UnpackTMB
382 
383 bool CSCTMBData::checkSize() const {
384  // sum up all the components and see if they have the size indicated in the TMBTrailer
385  return true;
386 }
387 
388 std::bitset<22> CSCTMBData::calCRC22(const std::vector<std::bitset<16> >& datain) {
389  std::bitset<22> CRC;
390  CRC.reset();
391  for (unsigned int i = 0; i < datain.size() - 3; ++i) {
392  CRC = nextCRC22_D16(datain[i], CRC);
393  }
394  return CRC;
395 }
396 
399  throw("No TMBScope in this chamber");
400  return *theTMBScope;
401 }
402 
405  throw("No TMBScope in this chamber");
406  return *theTMBMiniScope;
407 }
408 
410  if (!theGEMDataIsPresent)
411  throw("No GEM Data in this chamber");
412  return &theGEMData;
413 }
414 
415 std::bitset<22> CSCTMBData::nextCRC22_D16(const std::bitset<16>& D, const std::bitset<22>& C) {
416  std::bitset<22> NewCRC;
417 
418  NewCRC[0] = D[0] ^ C[6];
419  NewCRC[1] = D[1] ^ D[0] ^ C[6] ^ C[7];
420  NewCRC[2] = D[2] ^ D[1] ^ C[7] ^ C[8];
421  NewCRC[3] = D[3] ^ D[2] ^ C[8] ^ C[9];
422  NewCRC[4] = D[4] ^ D[3] ^ C[9] ^ C[10];
423  NewCRC[5] = D[5] ^ D[4] ^ C[10] ^ C[11];
424  NewCRC[6] = D[6] ^ D[5] ^ C[11] ^ C[12];
425  NewCRC[7] = D[7] ^ D[6] ^ C[12] ^ C[13];
426  NewCRC[8] = D[8] ^ D[7] ^ C[13] ^ C[14];
427  NewCRC[9] = D[9] ^ D[8] ^ C[14] ^ C[15];
428  NewCRC[10] = D[10] ^ D[9] ^ C[15] ^ C[16];
429  NewCRC[11] = D[11] ^ D[10] ^ C[16] ^ C[17];
430  NewCRC[12] = D[12] ^ D[11] ^ C[17] ^ C[18];
431  NewCRC[13] = D[13] ^ D[12] ^ C[18] ^ C[19];
432  NewCRC[14] = D[14] ^ D[13] ^ C[19] ^ C[20];
433  NewCRC[15] = D[15] ^ D[14] ^ C[20] ^ C[21];
434  NewCRC[16] = D[15] ^ C[0] ^ C[21];
435  NewCRC[17] = C[1];
436  NewCRC[18] = C[2];
437  NewCRC[19] = C[3];
438  NewCRC[20] = C[4];
439  NewCRC[21] = C[5];
440 
441  return NewCRC;
442 }
443 
444 boost::dynamic_bitset<> CSCTMBData::pack() {
445  boost::dynamic_bitset<> result =
447  boost::dynamic_bitset<> comparatorData =
450 
452  if (theGEMDataIsPresent) {
453  boost::dynamic_bitset<> gemData =
456  }
457 
458  boost::dynamic_bitset<> newResult = result;
459 
460  boost::dynamic_bitset<> tmbTrailer =
463 
464  // now convert to a vector<bitset<16>>, so we can calculate the crc
465  std::vector<std::bitset<16> > wordVector;
466  // try to tune so it stops before the e0f line
467  for (unsigned pos = 0; pos < result.size() - 16; pos += 16) {
468  std::bitset<16> word;
469  for (int i = 0; i < 16; ++i) {
470  word[i] = result[pos + i];
471  }
472  wordVector.push_back(word);
473  }
474  theTMBTrailer.setCRC(calCRC22(wordVector).to_ulong());
476  newResult = bitset_utilities::append(newResult, tmbTrailer);
477 
478  return newResult;
479 }
480 
482  CSCTMBData tmbData;
483  cscClassPackerCompare(tmbData);
484 }
CSCTMBMiniScope & tmbMiniScope() const
Definition: CSCTMBData.cc:403
CSCTMBTrailer * tmbTrailer()
Definition: CSCTMBData.h:51
unsigned theE0FLine
Definition: CSCTMBData.h:77
bool theRPCDataIsPresent
Definition: CSCTMBData.h:103
CSCTMBTrailer theTMBTrailer
Definition: CSCTMBData.h:95
CSCGEMData * gemData()
Definition: CSCTMBData.cc:409
static void selfTest()
tests packing
Definition: CSCTMBData.cc:481
int TMBCRCcalc()
Definition: CSCTMBData.cc:150
CSCTMBScope & tmbScope() const
Definition: CSCTMBData.cc:397
boost::dynamic_bitset pack()
not const because it sets size int TMBTrailer
Definition: CSCTMBData.cc:444
int sizeInWords() const
in 16-bit words
bool theBlockedCFEBIsPresent
Definition: CSCTMBData.h:92
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 ...
std::bitset< 22 > nextCRC22_D16(const std::bitset< 16 > &D, const std::bitset< 22 > &C)
Definition: CSCTMBData.cc:415
unsigned short size_
Definition: CSCTMBData.h:101
bool theTMBMiniScopeIsPresent
Definition: CSCTMBData.h:89
unsigned theB0CLine
Definition: CSCTMBData.h:76
CSCRPCData theRPCData
Definition: CSCTMBData.h:81
uint16_t NTBins() const
Definition: CSCTMBHeader.h:67
unsigned short * data()
Definition: CSCTMBTrailer.h:43
Log< level::Error, false > LogError
bool cscClassPackerCompare(T &t)
bool theGEMDataIsPresent
Definition: CSCTMBData.h:104
#define LogTrace(id)
std::bitset< 22 > calCRC22(const std::vector< std::bitset< 16 > > &datain)
Definition: CSCTMBData.cc:388
void setNCFEBs(uint16_t ncfebs)
Definition: CSCTMBHeader.h:75
uint64_t word
CSCTMBHeader theTMBHeader
Definition: CSCTMBData.h:79
static std::atomic< bool > debug
Definition: CSCTMBData.h:99
CSCTMBBlockedCFEB * theTMBBlockedCFEB
Definition: CSCTMBData.h:93
bool check() const
Definition: CSCTMBHeader.h:119
const uint16_t * theOriginalBuffer
Definition: CSCTMBData.h:73
unsigned short int sizeInWords() const
Definition: CSCTMBHeader.h:110
unsigned short * data()
Definition: CSCGEMData.h:37
unsigned short * data()
Definition: CSCTMBHeader.h:114
bool checkSize() const
sees if the size adds up to the word count
Definition: CSCTMBData.cc:383
void setCRC(int crc)
int sizeInWords()
Definition: CSCRPCData.h:21
int sizeInWords() const
Definition: CSCGEMData.h:21
int FirmwareVersion() const
Definition: CSCTMBHeader.h:40
CSCGEMData theGEMData
Definition: CSCTMBData.h:82
CSCComparatorData theComparatorData
Definition: CSCTMBData.h:80
CSCTMBMiniScope * theTMBMiniScope
Definition: CSCTMBData.h:90
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
CSCComparatorData * comparatorData()
Definition: CSCTMBData.h:41
bool theTMBScopeIsPresent
The TMB scope is not present in most of data hence its dynamic.
Definition: CSCTMBData.h:84
int sizeInWords() const
in 16-bit frames
Definition: CSCTMBTrailer.h:42
uint16_t NCFEBs() const
Definition: CSCTMBHeader.h:68
CSCTMBScope * theTMBScope
Definition: CSCTMBData.h:85
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:141
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:167
unsigned short * data()