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