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