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