Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:27

0001 /** \class CSCTMBData
0002  *
0003  *  \author A. Tumanov - Rice
0004  */
0005 
0006 #include "EventFilter/CSCRawToDigi/interface/CSCTMBData.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 
0009 #include <iomanip>  // dump for JK
0010 #include <iostream>
0011 #include <cstdio>
0012 #include "EventFilter/CSCRawToDigi/interface/bitset_append.h"
0013 #include "EventFilter/CSCRawToDigi/interface/cscPackerCompare.h"
0014 
0015 #ifdef LOCAL_UNPACK
0016 bool CSCTMBData::debug = false;
0017 #else
0018 std::atomic<bool> CSCTMBData::debug{false};
0019 #endif
0020 
0021 CSCTMBData::CSCTMBData()
0022     : theOriginalBuffer(nullptr),
0023       theB0CLine(0),
0024       theE0FLine(0),
0025       theTMBHeader(2007, 0x50c3),
0026       theComparatorData(&theTMBHeader),
0027       theGEMData(),
0028       theTMBScopeIsPresent(false),
0029       theTMBScope(nullptr),
0030       theTMBMiniScopeIsPresent(false),
0031       theTMBMiniScope(nullptr),
0032       theBlockedCFEBIsPresent(false),
0033       theTMBBlockedCFEB(nullptr),
0034       theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), 2007),
0035       size_(0),
0036       cWordCnt(0),
0037       theRPCDataIsPresent(false),
0038       theGEMDataIsPresent(false) {}
0039 
0040 CSCTMBData::CSCTMBData(int firmwareVersion, int firmwareRevision, int cfebs)
0041     : theOriginalBuffer(nullptr),
0042       theB0CLine(0),
0043       theE0FLine(0),
0044       theTMBHeader(firmwareVersion, firmwareRevision),
0045       theComparatorData(&theTMBHeader),
0046       theGEMData(),  // allocate 12 GEM tbins, 0xf - 4 GEM fibers enabled
0047       theTMBScopeIsPresent(false),
0048       theTMBScope(nullptr),
0049       theTMBMiniScopeIsPresent(false),
0050       theTMBMiniScope(nullptr),
0051       theBlockedCFEBIsPresent(false),
0052       theTMBBlockedCFEB(nullptr),
0053       theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), firmwareVersion),
0054       size_(0),
0055       cWordCnt(0),
0056       theRPCDataIsPresent(false),
0057       theGEMDataIsPresent(false) {
0058   theTMBHeader.setNCFEBs(cfebs);
0059   theComparatorData = CSCComparatorData(&theTMBHeader);
0060   int wordCnt = theTMBHeader.sizeInWords() + theComparatorData.sizeInWords();
0061   /// check if this is OTMB GEM fw and adjust expected TMB data word count
0062   if ((firmwareVersion == 2020) && (((firmwareRevision >> 9) & 0x3) == 3)) {
0063     theGEMDataIsPresent = true;
0064     wordCnt += theGEMData.sizeInWords();
0065   }
0066   theTMBTrailer = CSCTMBTrailer(wordCnt, firmwareVersion);
0067 }
0068 
0069 CSCTMBData::CSCTMBData(const uint16_t* buf)
0070     : theOriginalBuffer(buf),
0071       theTMBHeader(2007, 0x50c3),
0072       theComparatorData(&theTMBHeader),
0073       theTMBScopeIsPresent(false),
0074       theTMBScope(nullptr),
0075       theTMBMiniScopeIsPresent(false),
0076       theTMBMiniScope(nullptr),
0077       theBlockedCFEBIsPresent(false),
0078       theTMBBlockedCFEB(nullptr),
0079       theTMBTrailer(theTMBHeader.sizeInWords() + theComparatorData.sizeInWords(), 2007),
0080       theRPCDataIsPresent(false),
0081       theGEMDataIsPresent(false) {
0082   size_ = UnpackTMB(buf);
0083 }
0084 
0085 // Explicitly-defined copy constructor is needed when the scope data is
0086 // present, to prevent the same pointer from being deleted twice. -SV.
0087 CSCTMBData::CSCTMBData(const CSCTMBData& data)
0088     : theOriginalBuffer(data.theOriginalBuffer),
0089       theB0CLine(data.theB0CLine),
0090       theE0FLine(data.theE0FLine),
0091       theTMBHeader(data.theTMBHeader),
0092       theComparatorData(data.theComparatorData),
0093       theRPCData(data.theRPCData),
0094       theGEMData(data.theGEMData),
0095       theTMBScopeIsPresent(data.theTMBScopeIsPresent),
0096       theTMBMiniScopeIsPresent(data.theTMBMiniScopeIsPresent),
0097       theBlockedCFEBIsPresent(data.theBlockedCFEBIsPresent),
0098       theTMBTrailer(data.theTMBTrailer),
0099       size_(data.size_),
0100       cWordCnt(data.cWordCnt),
0101       theRPCDataIsPresent(data.theRPCDataIsPresent),
0102       theGEMDataIsPresent(data.theGEMDataIsPresent) {
0103   if (theTMBScopeIsPresent) {
0104     theTMBScope = new CSCTMBScope(*(data.theTMBScope));
0105   } else {
0106     theTMBScope = nullptr;
0107   }
0108 
0109   if (theTMBMiniScopeIsPresent) {
0110     theTMBMiniScope = new CSCTMBMiniScope(*(data.theTMBMiniScope));
0111   } else {
0112     theTMBMiniScope = nullptr;
0113   }
0114 
0115   if (theBlockedCFEBIsPresent) {
0116     theTMBBlockedCFEB = new CSCTMBBlockedCFEB(*(data.theTMBBlockedCFEB));
0117   } else {
0118     theTMBBlockedCFEB = nullptr;
0119   }
0120 }
0121 
0122 CSCTMBData::~CSCTMBData() {
0123   if (theTMBScopeIsPresent) {
0124     delete theTMBScope;
0125     theTMBScopeIsPresent = false;
0126   }
0127 
0128   if (theTMBMiniScopeIsPresent) {
0129     delete theTMBMiniScope;
0130     theTMBMiniScopeIsPresent = false;
0131   }
0132 
0133   if (theBlockedCFEBIsPresent) {
0134     delete theTMBBlockedCFEB;
0135     theBlockedCFEBIsPresent = false;
0136   }
0137 }
0138 
0139 /// returns -1 if not found
0140 /// obsolete
0141 int findLine(const uint16_t* buf, uint16_t marker, int first, int maxToDo) {
0142   for (int i = first; i < maxToDo; ++i) {
0143     if (buf[i] == marker) {
0144       return i;
0145     }
0146   }
0147   return -1;
0148 }
0149 
0150 int CSCTMBData::TMBCRCcalc() {
0151   std::vector<std::bitset<16> > theTotalTMBData(theE0FLine + 1 - theB0CLine);
0152   unsigned i = 0;
0153   for (unsigned int line = theB0CLine; line < theE0FLine + 1; ++line) {
0154     theTotalTMBData[i] = std::bitset<16>(theOriginalBuffer[line]);
0155     ++i;
0156   }
0157   if (!theTotalTMBData.empty()) {
0158     std::bitset<22> CRC = calCRC22(theTotalTMBData);
0159     LogTrace("CSCTMBData|CSCRawToDigi") << " Test here " << CRC.to_ulong();
0160     return CRC.to_ulong();
0161   } else {
0162     LogTrace("CSCTMBData|CSCRawToDigi") << "theTotalTMBData doesn't exist";
0163     return 0;
0164   }
0165 }
0166 
0167 int CSCTMBData::UnpackTMB(const uint16_t* buf) {
0168   ///determine 2007 or 2006 version
0169   unsigned short int firmwareVersion = 0;
0170   unsigned short int firmwareRevision = 0;
0171   int Ntbins = 0;
0172   int NRPCtbins = 0;    // Number of RPC tbins
0173   int NGEMtbins = 0;    // Number of GEM tbins
0174   int NGEMEnabled = 0;  // Number of Enabled GEM Fibers
0175   int GEMFibersMask = 0;
0176   bool isGEMfirmware = false;
0177 
0178   int b0cLine = 0;  ///assumes that buf starts at the tmb data
0179                     ///this is not true if something is wrong in the data
0180                     ///before TMB - then we skip the whole event
0181 
0182   if (buf[b0cLine] == 0xdb0c) {
0183     firmwareVersion = 2007;
0184     firmwareRevision = buf[b0cLine + 7] & 0x7fff;
0185     Ntbins = buf[b0cLine + 19] & 0xF8;
0186     if ((firmwareRevision < 0x4000) /* New Run3 (O)TMB firmware revision format */
0187         && (((firmwareRevision >> 9) & 0x3) == 0x3))
0188       isGEMfirmware = true;
0189 
0190     if (isGEMfirmware) {
0191       GEMFibersMask = buf[b0cLine + 36] & 0xf;  // GEM enabled fibers 4-bits mask
0192       /// Handling of enabled GEM fibers is not implemented in the firmware
0193       // for (int i = 0; i < 4; i++)
0194       //  NGEMEnabled += (buf[b0cLine + 36] >> i) & 0x1;  // Get number of enabled GEM fibers
0195       NGEMEnabled = 4;                              // Currently always assume that all 4 fibers are enabled
0196       NGEMtbins = (buf[b0cLine + 36] >> 5) & 0x1F;  // Get GEM tbins
0197     }
0198     NRPCtbins = (buf[b0cLine + 36] >> 5) & 0x1F;  // Get RPC tbins
0199   } else if (buf[b0cLine] == 0x6b0c) {
0200     firmwareVersion = 2006;
0201     Ntbins = buf[b0cLine + 1] & 0x1f;
0202     NRPCtbins = Ntbins;
0203   } else {
0204     LogTrace("CSCTMBData|CSCRawToDigi") << "+++ Can't find b0C flag";
0205   }
0206 
0207   if ((firmwareVersion == 2007) &&
0208       (!(((buf[b0cLine] & 0xFFFF) == 0xDB0C) && ((buf[b0cLine + 1] & 0xf000) == 0xD000) &&
0209          ((buf[b0cLine + 2] & 0xf000) == 0xD000) && ((buf[b0cLine + 3] & 0xf000) == 0xD000)))) {
0210     LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: error in header in 2007 format!";
0211   }
0212 
0213   int MaxSizeRPC = 1 + NRPCtbins * 2 * 4 + 1;
0214   int MaxSizeGEM = 1 + NGEMEnabled * NGEMtbins * 4 + 1;
0215   //int MaxSizeScope = 5;
0216   int e0bLine = -1;
0217   switch (firmwareVersion) {
0218     case 2007:
0219       e0bLine = 42;  //last word of header2007
0220       break;
0221     case 2006:
0222       e0bLine = 26;  //last word of header in 2006 format
0223       break;
0224     default:
0225       edm::LogError("CSCTMBData|CSCRawToDigi") << "+++ undetermined firmware format - cant find e0bLine";
0226   }
0227 
0228   theTMBHeader = CSCTMBHeader(buf);
0229 
0230   if (!theTMBHeader.check()) {
0231     LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad TMB header e0bLine=" << std::hex
0232                                         << buf[e0bLine];
0233     return 0;
0234   }
0235 
0236   int currentPosition = theTMBHeader.sizeInWords();
0237   int theFirmwareVersion = theTMBHeader.FirmwareVersion();
0238 
0239   theComparatorData =
0240       CSCComparatorData(theTMBHeader.NCFEBs(), theTMBHeader.NTBins(), buf + e0bLine + 1, theFirmwareVersion);
0241 
0242   if (!theComparatorData.check()) {
0243     LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad CLCT data";
0244   } else {
0245     currentPosition += theComparatorData.sizeInWords();
0246   }
0247 
0248   // look for RPC data
0249   int b04Line = currentPosition;
0250 
0251   if (buf[b04Line] == 0x6b04) {
0252     // we need an e04 line to calculate the size
0253     int e04Line = findLine(buf, 0x6e04, currentPosition, currentPosition + MaxSizeRPC);
0254     if (e04Line != -1) {
0255       theRPCDataIsPresent = true;
0256       theRPCData = CSCRPCData(buf + b04Line, e04Line - b04Line + 1);
0257       currentPosition += theRPCData.sizeInWords();
0258     } else {
0259       LogTrace("CSCTMBData|CSCRawToDigi") << "CSCTMBData::corrupt RPC data! Failed to find end! ";
0260       return 0;
0261     }
0262   }
0263 
0264   // look for GEM data
0265   int c04Line = currentPosition;
0266 
0267   if (buf[c04Line] == 0x6c04) {
0268     // we need an d04 line to calculate the size
0269     int d04Line = findLine(buf, 0x6d04, currentPosition, currentPosition + MaxSizeGEM);
0270     if (d04Line != -1) {
0271       theGEMDataIsPresent = true;
0272       theGEMData = CSCGEMData(buf + c04Line, d04Line - c04Line + 1, GEMFibersMask);
0273       currentPosition += theGEMData.sizeInWords();
0274     } else {
0275       LogTrace("CSCTMBData|CSCRawToDigi") << "CSCTMBData::corrupt GEM data! Failed to find end! ";
0276       return 0;
0277     }
0278   }
0279 
0280   int TotTMBReadout = 0;
0281   switch (firmwareVersion) {
0282     case 2007:
0283       if (theGEMDataIsPresent) {
0284         TotTMBReadout = 43 + Ntbins * 6 * 5 + 1 + NGEMEnabled * NGEMtbins * 4 + 2 + 8 * 256 + 8;
0285       } else {
0286         TotTMBReadout = 43 + Ntbins * 6 * 5 + 1 + NRPCtbins * 2 * 4 + 2 + 8 * 256 + 8;
0287       };
0288       break;
0289     case 2006:
0290       TotTMBReadout =
0291           27 + Ntbins * 6 * 5 + 1 + NRPCtbins * 2 * 4 + 2 + 8 * 256 + 8;  //see tmb2004 manual (version v2p06) page54.
0292       break;
0293     default:
0294       edm::LogError("CSCTMBData|CSCRawToDigi") << "can't find TotTMBReadout - unknown firmware version!";
0295       break;
0296   }
0297 
0298   //std::cout << " !!!TMB Scope!!! " << std::endl;
0299   if (buf[currentPosition] == 0x6b05) {
0300     int b05Line = currentPosition;
0301     LogTrace("CSCTMBData|CSCRawToDigi") << "found scope!";
0302     int e05Line = findLine(buf, 0x6e05, currentPosition, TotTMBReadout - currentPosition);
0303     if (e05Line != -1) {
0304       theTMBScopeIsPresent = true;
0305       theTMBScope = new CSCTMBScope(buf, b05Line, e05Line);
0306       // The size of the TMB scope data can vary, and I see no good reasons
0307       // not to determine it dynamically.  -SV, 5 Nov 2008.
0308       //currentPosition+=theTMBScope->sizeInWords();
0309       currentPosition += (e05Line - b05Line + 1);
0310     } else {
0311       LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: found 0x6b05 line, but not 0x6e05! +++";
0312     }
0313   }
0314 
0315   /// Now Find the miniscope
0316   if (buf[currentPosition] == 0x6b07) {
0317     int Line6b07 = currentPosition;
0318     LogTrace("CSCTMBData") << " TMBData ---> Begin of MiniScope found ";
0319     int Line6E07 = findLine(buf, 0x6E07, currentPosition, TotTMBReadout - currentPosition);
0320     if (Line6E07 != -1) {
0321       LogTrace("CSCTMBData") << " TMBData --> End of MiniScope found " << Line6E07 - Line6b07 + 1 << " words ";
0322       theTMBMiniScopeIsPresent = true;
0323       theTMBMiniScope = new CSCTMBMiniScope(buf, Line6b07, Line6E07);
0324       currentPosition += (Line6E07 - Line6b07 + 1);
0325     } else {
0326       LogTrace("CSCTMBData") << "+++ CSCTMBData warning MiniScope!: found 0x6b07 line, but not 0x6e07! +++";
0327     }
0328   }
0329   /// end for the mini scope
0330 
0331   /// Now Find the blocked CFEB DiStrips List Format
0332   if (buf[currentPosition] == 0x6BCB) {
0333     int Line6BCB = currentPosition;
0334     LogTrace("CSCTMBData") << " TMBData ---> Begin of Blocked CFEB found ";
0335     int Line6ECB = findLine(buf, 0x6ECB, currentPosition, TotTMBReadout - currentPosition);
0336     if (Line6ECB != -1) {
0337       LogTrace("CSCTMBData") << " TMBData --> End of Blocked CFEB found " << Line6ECB - Line6BCB + 1 << " words ";
0338       theBlockedCFEBIsPresent = true;
0339       theTMBBlockedCFEB = new CSCTMBBlockedCFEB(buf, Line6BCB, Line6ECB);
0340       currentPosition += (Line6ECB - Line6BCB + 1);
0341     } else {
0342       LogTrace("CSCTMBData") << "+++ CSCTMBData warning Blocked CFEB!: found 0x6BCB line, but not 0x6ECB! +++";
0343     }
0344   }
0345   /// end for the blocked CFEB DiStrips List Format
0346 
0347   int maxLine = findLine(buf, 0xde0f, currentPosition, TotTMBReadout - currentPosition);
0348   if (maxLine == -1) {
0349     LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0f line!";
0350     return 0;
0351   }
0352 
0353   //Now for CRC check put this information into bitset
0354 
0355   theB0CLine = b0cLine;
0356   theE0FLine = maxLine;
0357 
0358   // finally, the trailer
0359   int e0cLine = findLine(buf, 0x6e0c, currentPosition, maxLine);
0360   if (e0cLine == -1) {
0361     LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0c line!";
0362   } else {
0363     theTMBTrailer = CSCTMBTrailer(buf + e0cLine, firmwareVersion);
0364     LogTrace("CSCTMBData|CSCRawToDigi") << "TMB trailer size: " << theTMBTrailer.sizeInWords();
0365   }
0366 
0367   checkSize();
0368 
0369   // Dump of TMB; format proposed by JK.
0370 #ifdef TMBDUMP
0371   LogTrace("CSCTMBData") << "Dump of TMB data:";
0372   for (int line = b0cLine; line <= maxLine + 3; line++) {
0373     LogTrace("CSCTMBData") << "Adr= " << std::setw(4) << line << " Data= " << std::setfill('0') << std::setw(5)
0374                            << std::uppercase << std::hex << buf[line] << std::dec << std::endl;
0375   }
0376 #endif
0377 
0378   // size, since we count from 0 and have one more trailer word
0379   // there are sometimes multiple "de0f" lines in trailer, so key on "6e0c"
0380   return e0cLine - b0cLine + theTMBTrailer.sizeInWords();
0381 }  //UnpackTMB
0382 
0383 bool CSCTMBData::checkSize() const {
0384   // sum up all the components and see if they have the size indicated in the TMBTrailer
0385   return true;
0386 }
0387 
0388 std::bitset<22> CSCTMBData::calCRC22(const std::vector<std::bitset<16> >& datain) {
0389   std::bitset<22> CRC;
0390   CRC.reset();
0391   for (unsigned int i = 0; i < datain.size() - 3; ++i) {
0392     CRC = nextCRC22_D16(datain[i], CRC);
0393   }
0394   return CRC;
0395 }
0396 
0397 CSCTMBScope& CSCTMBData::tmbScope() const {
0398   if (!theTMBScopeIsPresent)
0399     throw("No TMBScope in this chamber");
0400   return *theTMBScope;
0401 }
0402 
0403 CSCTMBMiniScope& CSCTMBData::tmbMiniScope() const {
0404   if (!theTMBMiniScopeIsPresent)
0405     throw("No TMBScope in this chamber");
0406   return *theTMBMiniScope;
0407 }
0408 
0409 CSCGEMData* CSCTMBData::gemData() {
0410   if (!theGEMDataIsPresent)
0411     throw("No GEM Data in this chamber");
0412   return &theGEMData;
0413 }
0414 
0415 std::bitset<22> CSCTMBData::nextCRC22_D16(const std::bitset<16>& D, const std::bitset<22>& C) {
0416   std::bitset<22> NewCRC;
0417 
0418   NewCRC[0] = D[0] ^ C[6];
0419   NewCRC[1] = D[1] ^ D[0] ^ C[6] ^ C[7];
0420   NewCRC[2] = D[2] ^ D[1] ^ C[7] ^ C[8];
0421   NewCRC[3] = D[3] ^ D[2] ^ C[8] ^ C[9];
0422   NewCRC[4] = D[4] ^ D[3] ^ C[9] ^ C[10];
0423   NewCRC[5] = D[5] ^ D[4] ^ C[10] ^ C[11];
0424   NewCRC[6] = D[6] ^ D[5] ^ C[11] ^ C[12];
0425   NewCRC[7] = D[7] ^ D[6] ^ C[12] ^ C[13];
0426   NewCRC[8] = D[8] ^ D[7] ^ C[13] ^ C[14];
0427   NewCRC[9] = D[9] ^ D[8] ^ C[14] ^ C[15];
0428   NewCRC[10] = D[10] ^ D[9] ^ C[15] ^ C[16];
0429   NewCRC[11] = D[11] ^ D[10] ^ C[16] ^ C[17];
0430   NewCRC[12] = D[12] ^ D[11] ^ C[17] ^ C[18];
0431   NewCRC[13] = D[13] ^ D[12] ^ C[18] ^ C[19];
0432   NewCRC[14] = D[14] ^ D[13] ^ C[19] ^ C[20];
0433   NewCRC[15] = D[15] ^ D[14] ^ C[20] ^ C[21];
0434   NewCRC[16] = D[15] ^ C[0] ^ C[21];
0435   NewCRC[17] = C[1];
0436   NewCRC[18] = C[2];
0437   NewCRC[19] = C[3];
0438   NewCRC[20] = C[4];
0439   NewCRC[21] = C[5];
0440 
0441   return NewCRC;
0442 }
0443 
0444 boost::dynamic_bitset<> CSCTMBData::pack() {
0445   boost::dynamic_bitset<> result =
0446       bitset_utilities::ushortToBitset(theTMBHeader.sizeInWords() * 16, theTMBHeader.data());
0447   boost::dynamic_bitset<> comparatorData =
0448       bitset_utilities::ushortToBitset(theComparatorData.sizeInWords() * 16, theComparatorData.data());
0449   result = bitset_utilities::append(result, comparatorData);
0450 
0451   /// Add packed GEM data to TMB data block
0452   if (theGEMDataIsPresent) {
0453     boost::dynamic_bitset<> gemData =
0454         bitset_utilities::ushortToBitset(theGEMData.sizeInWords() * 16, theGEMData.data());
0455     result = bitset_utilities::append(result, gemData);
0456   }
0457 
0458   boost::dynamic_bitset<> newResult = result;
0459 
0460   boost::dynamic_bitset<> tmbTrailer =
0461       bitset_utilities::ushortToBitset(theTMBTrailer.sizeInWords() * 16, theTMBTrailer.data());
0462   result = bitset_utilities::append(result, tmbTrailer);
0463 
0464   // now convert to a vector<bitset<16>>, so we can calculate the crc
0465   std::vector<std::bitset<16> > wordVector;
0466   // try to tune so it stops before the e0f line
0467   for (unsigned pos = 0; pos < result.size() - 16; pos += 16) {
0468     std::bitset<16> word;
0469     for (int i = 0; i < 16; ++i) {
0470       word[i] = result[pos + i];
0471     }
0472     wordVector.push_back(word);
0473   }
0474   theTMBTrailer.setCRC(calCRC22(wordVector).to_ulong());
0475   tmbTrailer = bitset_utilities::ushortToBitset(theTMBTrailer.sizeInWords() * 16, theTMBTrailer.data());
0476   newResult = bitset_utilities::append(newResult, tmbTrailer);
0477 
0478   return newResult;
0479 }
0480 
0481 void CSCTMBData::selfTest() {
0482   CSCTMBData tmbData;
0483   cscClassPackerCompare(tmbData);
0484 }