00001
00008 #include "EventFilter/CSCRawToDigi/interface/CSCTMBData.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010
00011 #include <iomanip>
00012 #include <iostream>
00013 #include <cstdio>
00014 #include "EventFilter/CSCRawToDigi/src/bitset_append.h"
00015 #include "EventFilter/CSCRawToDigi/src/cscPackerCompare.h"
00016
00017 bool CSCTMBData::debug =false;
00018
00019 CSCTMBData::CSCTMBData()
00020 : theOriginalBuffer(0),
00021 theTMBHeader(2007, 0x50c3),
00022 theCLCTData(&theTMBHeader),
00023 theTMBScopeIsPresent(false),
00024 theTMBScope(0),
00025 theTMBMiniScopeIsPresent(false),
00026 theTMBMiniScope(0),
00027 theBlockedCFEBIsPresent(false),
00028 theTMBBlockedCFEB(0),
00029 theTMBTrailer(theTMBHeader.sizeInWords()+theCLCTData.sizeInWords(), 2007),
00030 theRPCDataIsPresent(false)
00031 {
00032
00033
00034 }
00035
00036
00037 CSCTMBData::CSCTMBData(unsigned short *buf)
00038 : theOriginalBuffer(buf),
00039 theTMBHeader(2007, 0x50c3),
00040 theCLCTData(&theTMBHeader),
00041 theTMBScopeIsPresent(false),
00042 theTMBScope(0),
00043 theTMBMiniScopeIsPresent(false),
00044 theTMBMiniScope(0),
00045 theBlockedCFEBIsPresent(false),
00046 theTMBBlockedCFEB(0),
00047 theTMBTrailer(theTMBHeader.sizeInWords()+theCLCTData.sizeInWords(), 2007),
00048 theRPCDataIsPresent(false){
00049 size_ = UnpackTMB(buf);
00050 }
00051
00052
00053
00054 CSCTMBData::CSCTMBData(const CSCTMBData& data):
00055 theOriginalBuffer(data.theOriginalBuffer),
00056 theB0CLine(data.theB0CLine), theE0FLine(data.theE0FLine),
00057 theTMBHeader(data.theTMBHeader),
00058 theCLCTData(data.theCLCTData), theRPCData(data.theRPCData),
00059 theTMBScopeIsPresent(data.theTMBScopeIsPresent),
00060 theTMBMiniScopeIsPresent(data.theTMBMiniScopeIsPresent),
00061 theBlockedCFEBIsPresent(data.theBlockedCFEBIsPresent),
00062 theTMBTrailer(data.theTMBTrailer),
00063 size_(data.size_), cWordCnt(data.cWordCnt),
00064 theRPCDataIsPresent(data.theRPCDataIsPresent)
00065 {
00066 if (theTMBScopeIsPresent) {
00067 theTMBScope = new CSCTMBScope(*(data.theTMBScope));
00068 }
00069 else {
00070 theTMBScope = 0;
00071 }
00072
00073 if (theTMBMiniScopeIsPresent) {
00074 theTMBMiniScope = new CSCTMBMiniScope(*(data.theTMBMiniScope));
00075 }
00076 else {
00077 theTMBMiniScope = 0;
00078 }
00079
00080 if (theBlockedCFEBIsPresent) {
00081 theTMBBlockedCFEB = new CSCTMBBlockedCFEB(*(data.theTMBBlockedCFEB));
00082 }
00083 else {
00084 theTMBBlockedCFEB = 0;
00085 }
00086
00087 }
00088
00089 CSCTMBData::~CSCTMBData(){
00090 if (theTMBScopeIsPresent) {
00091 delete theTMBScope;
00092 theTMBScopeIsPresent = false;
00093 }
00094
00095 if (theTMBMiniScopeIsPresent) {
00096 delete theTMBMiniScope;
00097 theTMBMiniScopeIsPresent = false;
00098 }
00099
00100 if (theBlockedCFEBIsPresent) {
00101 delete theTMBBlockedCFEB;
00102 theBlockedCFEBIsPresent = false;
00103 }
00104 }
00105
00108 int findLine(unsigned short *buf, unsigned short marker,int first, int maxToDo) {
00109 for(int i = first; i < maxToDo; ++i) {
00110 if(buf[i] == marker) {
00111 return i;
00112 }
00113 }
00114 return -1;
00115 }
00116
00117 int CSCTMBData::TMBCRCcalc() {
00118 std::vector<std::bitset<16> > theTotalTMBData(theE0FLine+1-theB0CLine);
00119 unsigned i = 0;
00120 for (unsigned int line=theB0CLine; line<theE0FLine+1;++line) {
00121 theTotalTMBData[i] = std::bitset<16>(theOriginalBuffer[line]);
00122 ++i;
00123 }
00124 if ( theTotalTMBData.size() > 0 ) {
00125 std::bitset<22> CRC=calCRC22(theTotalTMBData);
00126 LogTrace("CSCTMBData|CSCRawToDigi") << " Test here " << CRC.to_ulong();
00127 return CRC.to_ulong();
00128 }
00129 else {
00130 LogTrace("CSCTMBData|CSCRawToDigi") << "theTotalTMBData doesn't exist";
00131 return 0;
00132 }
00133 }
00134
00135 int CSCTMBData::UnpackTMB(unsigned short *buf) {
00137 unsigned short int firmwareVersion=0;
00138 int Ntbins = 0 ;
00139 int NHeaderFrames = 0;
00140 int NRPCtbins = 0;
00141
00142 int b0cLine=0;
00143
00144
00145
00146
00147 if (buf[b0cLine]==0xdb0c) {
00148 firmwareVersion=2007;
00149 Ntbins = buf[b0cLine+19]&0xF8;
00150 NRPCtbins = (buf[b0cLine+36]>>5)&0x1F;
00151 NHeaderFrames = buf[b0cLine+5]&0x3F;
00152 }
00153 else if (buf[b0cLine]==0x6b0c) {
00154 firmwareVersion=2006;
00155 Ntbins = buf[b0cLine+1]&0x1f ;
00156 NRPCtbins = Ntbins;
00157 NHeaderFrames = buf[b0cLine+4]&0x1f;
00158 }
00159 else {
00160 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ Can't find b0C flag";
00161 }
00162
00163 if ((firmwareVersion==2007)&&(!(((buf[b0cLine]&0xFFFF)==0xDB0C)&&((buf[b0cLine+1]&0xf000)==0xD000)
00164 &&((buf[b0cLine+2]&0xf000)==0xD000)&&((buf[b0cLine+3]&0xf000)==0xD000)))){
00165 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: error in header in 2007 format!";
00166 }
00167
00168 int MaxSizeRPC = 1+NRPCtbins*2*4+1;
00169
00170 int e0bLine =-1;
00171 switch (firmwareVersion) {
00172 case 2007:
00173 e0bLine = 42;
00174 break;
00175 case 2006:
00176 e0bLine = 26;
00177 break;
00178 default:
00179 edm::LogError("CSCTMBData|CSCRawToDigi") << "+++ undetermined firmware format - cant find e0bLine";
00180 }
00181
00182 theTMBHeader=CSCTMBHeader(buf);
00183
00184 if(!theTMBHeader.check()) {
00185 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad TMB header e0bLine=" << std::hex << buf[e0bLine];
00186 return 0;
00187 }
00188
00189 int currentPosition = theTMBHeader.sizeInWords();
00190
00191 theCLCTData = CSCCLCTData(theTMBHeader.NCFEBs(), theTMBHeader.NTBins(), buf+e0bLine+1);
00192
00193 if(!theCLCTData.check()) {
00194 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: Bad CLCT data";
00195 }
00196 else {
00197 currentPosition+=theCLCTData.sizeInWords();
00198 }
00199
00200
00201
00202
00203
00204
00205 int b04Line = currentPosition;
00206
00207 if(buf[b04Line]==0x6b04) {
00208
00209 int e04Line = findLine(buf, 0x6e04, currentPosition, currentPosition+MaxSizeRPC);
00210 if(e04Line != -1) {
00211 theRPCDataIsPresent = true;
00212 theRPCData = CSCRPCData(buf+b04Line, e04Line-b04Line+1);
00213 currentPosition+=theRPCData.sizeInWords();
00214 }
00215 else {
00216 LogTrace("CSCTMBData|CSCRawToDigi") << "CSCTMBData::corrupt RPC data! Failed to find end! ";
00217 return 0;
00218 }
00219 }
00220
00221 int TotTMBReadout=0;
00222 switch (firmwareVersion) {
00223 case 2007:
00224 TotTMBReadout= 43+Ntbins*6*5+1+NRPCtbins*2*4+2+8*256+8;
00225 break;
00226 case 2006:
00227 TotTMBReadout= 27+Ntbins*6*5+1+NRPCtbins*2*4+2+8*256+8;
00228 break;
00229 default:
00230 edm::LogError("CSCTMBData|CSCRawToDigi") << "can't find TotTMBReadout - unknown firmware version!";
00231 break;
00232 }
00233
00234
00235 if (buf[currentPosition]==0x6b05) {
00236 int b05Line = currentPosition;
00237 LogTrace("CSCTMBData|CSCRawToDigi") << "found scope!";
00238 int e05Line = findLine(buf, 0x6e05, currentPosition, TotTMBReadout-currentPosition);
00239 if(e05Line != -1){
00240 theTMBScopeIsPresent = true;
00241 theTMBScope = new CSCTMBScope(buf,b05Line, e05Line);
00242
00243
00244
00245 currentPosition+=(e05Line-b05Line+1);
00246 }
00247 else {
00248 LogTrace("CSCTMBData|CSCRawToDigi")
00249 << "+++ CSCTMBData warning: found 0x6b05 line, but not 0x6e05! +++";
00250 }
00251 }
00252
00254 if (buf[currentPosition]==0x6b07){
00255 int Line6b07 = currentPosition;
00256 LogTrace("CSCTMBData") << " TMBData ---> Begin of MiniScope found " ;
00257 int Line6E07 = findLine(buf, 0x6E07, currentPosition, TotTMBReadout-currentPosition);
00258 if(Line6E07 !=-1){
00259 LogTrace("CSCTMBData") << " TMBData --> End of MiniScope found " << Line6E07-Line6b07+1 << " words ";
00260 theTMBMiniScopeIsPresent = true;
00261 theTMBMiniScope = new CSCTMBMiniScope(buf, Line6b07, Line6E07);
00262 currentPosition += (Line6E07-Line6b07+1);
00263 }
00264 else {
00265 LogTrace("CSCTMBData")
00266 << "+++ CSCTMBData warning MiniScope!: found 0x6b07 line, but not 0x6e07! +++";
00267 }
00268 }
00270
00272 if (buf[currentPosition]==0x6BCB){
00273 int Line6BCB = currentPosition;
00274 LogTrace("CSCTMBData") << " TMBData ---> Begin of Blocked CFEB found " ;
00275 int Line6ECB = findLine(buf, 0x6ECB, currentPosition, TotTMBReadout-currentPosition);
00276 if(Line6ECB !=-1){
00277 LogTrace("CSCTMBData") << " TMBData --> End of Blocked CFEB found " << Line6ECB-Line6BCB+1 << " words ";
00278 theBlockedCFEBIsPresent = true;
00279 theTMBBlockedCFEB = new CSCTMBBlockedCFEB(buf, Line6BCB, Line6ECB);
00280 currentPosition += (Line6ECB-Line6BCB+1);
00281 }
00282 else {
00283 LogTrace("CSCTMBData")
00284 << "+++ CSCTMBData warning Blocked CFEB!: found 0x6BCB line, but not 0x6ECB! +++";
00285 }
00286 }
00288
00289 int maxLine = findLine(buf, 0xde0f, currentPosition, TotTMBReadout-currentPosition);
00290 if(maxLine == -1)
00291 {
00292 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0f line!";
00293 return 0;
00294 }
00295
00296
00297
00298 theB0CLine = b0cLine;
00299 theE0FLine = maxLine;
00300
00301
00302 int e0cLine = findLine(buf, 0x6e0c, currentPosition, maxLine);
00303 if (e0cLine == -1)
00304 {
00305 LogTrace("CSCTMBData|CSCRawToDigi") << "+++ CSCTMBData warning: No e0c line!";
00306 }
00307 else
00308 {
00309 theTMBTrailer = CSCTMBTrailer(buf+e0cLine, firmwareVersion);
00310 LogTrace("CSCTMBData|CSCRawToDigi")
00311 << "TMB trailer size: " << theTMBTrailer.sizeInWords();
00312 }
00313
00314 checkSize();
00315
00316
00317 #ifdef TMBDUMP
00318 LogTrace("CSCTMBData") << "Dump of TMB data:";
00319 for (int line = b0cLine; line <= maxLine+3; line++) {
00320 LogTrace("CSCTMBData")
00321 << "Adr= " << std::setw(4) << line
00322 << " Data= " << std::setfill('0') << std::setw(5)
00323 << std::uppercase << std::hex << buf[line] << std::dec << std::endl;
00324 }
00325 #endif
00326
00327
00328
00329 return e0cLine-b0cLine+theTMBTrailer.sizeInWords();
00330 }
00331
00332 bool CSCTMBData::checkSize() const
00333 {
00334
00335 return true;
00336 }
00337
00338 std::bitset<22> CSCTMBData::calCRC22(const std::vector< std::bitset<16> >& datain)
00339 {
00340 std::bitset<22> CRC;
00341 CRC.reset();
00342 for(unsigned int i=0;i<datain.size()-3;++i)
00343 {
00344 CRC=nextCRC22_D16(datain[i],CRC);
00345 }
00346 return CRC;
00347 }
00348
00349 CSCTMBScope & CSCTMBData::tmbScope() const
00350 {
00351 if (!theTMBScopeIsPresent) throw("No TMBScope in this chamber");
00352 return * theTMBScope;
00353 }
00354
00355 CSCTMBMiniScope & CSCTMBData::tmbMiniScope() const
00356 {
00357 if (!theTMBMiniScopeIsPresent) throw("No TMBScope in this chamber");
00358 return * theTMBMiniScope;
00359 }
00360
00361
00362 CSCTMBBlockedCFEB & CSCTMBData::tmbBlockedCFEB() const
00363 {
00364 if (!theBlockedCFEBIsPresent) throw("No TMB Blocked CFEB in this chamber");
00365 return * theTMBBlockedCFEB;
00366 }
00367
00368
00369 std::bitset<22> CSCTMBData::nextCRC22_D16(const std::bitset<16>& D,
00370 const std::bitset<22>& C)
00371 {
00372 std::bitset<22> NewCRC;
00373
00374 NewCRC[ 0] = D[ 0] ^ C[ 6];
00375 NewCRC[ 1] = D[ 1] ^ D[ 0] ^ C[ 6] ^ C[ 7];
00376 NewCRC[ 2] = D[ 2] ^ D[ 1] ^ C[ 7] ^ C[ 8];
00377 NewCRC[ 3] = D[ 3] ^ D[ 2] ^ C[ 8] ^ C[ 9];
00378 NewCRC[ 4] = D[ 4] ^ D[ 3] ^ C[ 9] ^ C[10];
00379 NewCRC[ 5] = D[ 5] ^ D[ 4] ^ C[10] ^ C[11];
00380 NewCRC[ 6] = D[ 6] ^ D[ 5] ^ C[11] ^ C[12];
00381 NewCRC[ 7] = D[ 7] ^ D[ 6] ^ C[12] ^ C[13];
00382 NewCRC[ 8] = D[ 8] ^ D[ 7] ^ C[13] ^ C[14];
00383 NewCRC[ 9] = D[ 9] ^ D[ 8] ^ C[14] ^ C[15];
00384 NewCRC[10] = D[10] ^ D[ 9] ^ C[15] ^ C[16];
00385 NewCRC[11] = D[11] ^ D[10] ^ C[16] ^ C[17];
00386 NewCRC[12] = D[12] ^ D[11] ^ C[17] ^ C[18];
00387 NewCRC[13] = D[13] ^ D[12] ^ C[18] ^ C[19];
00388 NewCRC[14] = D[14] ^ D[13] ^ C[19] ^ C[20];
00389 NewCRC[15] = D[15] ^ D[14] ^ C[20] ^ C[21];
00390 NewCRC[16] = D[15] ^ C[ 0] ^ C[21];
00391 NewCRC[17] = C[ 1];
00392 NewCRC[18] = C[ 2];
00393 NewCRC[19] = C[ 3];
00394 NewCRC[20] = C[ 4];
00395 NewCRC[21] = C[ 5];
00396
00397 return NewCRC;
00398 }
00399
00400
00401 boost::dynamic_bitset<> CSCTMBData::pack()
00402 {
00403 boost::dynamic_bitset<> result = bitset_utilities::ushortToBitset(theTMBHeader.sizeInWords()*16,
00404 theTMBHeader.data());
00405 boost::dynamic_bitset<> clctData = bitset_utilities::ushortToBitset(theCLCTData.sizeInWords()*16,
00406 theCLCTData.data());
00407 result = bitset_utilities::append(result,clctData);
00408 boost::dynamic_bitset<> newResult = result;
00409
00410
00411 boost::dynamic_bitset<> tmbTrailer = bitset_utilities::ushortToBitset( theTMBTrailer.sizeInWords()*16,
00412 theTMBTrailer.data());
00413 result = bitset_utilities::append(result,tmbTrailer);
00414
00415
00416 std::vector<std::bitset<16> > wordVector;
00417
00418 for(unsigned pos = 0; pos < result.size()-16; pos += 16)
00419 {
00420 std::bitset<16> word;
00421 for(int i = 0; i < 16; ++i)
00422 {
00423 word[i] = result[pos+i];
00424 }
00425 wordVector.push_back(word);
00426 }
00427 theTMBTrailer.setCRC(calCRC22(wordVector).to_ulong());
00428 tmbTrailer = bitset_utilities::ushortToBitset( theTMBTrailer.sizeInWords()*16,
00429 theTMBTrailer.data());
00430 newResult = bitset_utilities::append(newResult, tmbTrailer);
00431
00432 return newResult;
00433 }
00434
00435
00436 void CSCTMBData::selfTest()
00437 {
00438 CSCTMBData tmbData;
00439 cscClassPackerCompare(tmbData);
00440 }
00441