CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/EventFilter/CSCRawToDigi/src/CSCTMBData.cc

Go to the documentation of this file.
00001 
00008 #include "EventFilter/CSCRawToDigi/interface/CSCTMBData.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 
00011 #include <iomanip>  // dump for JK
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 // Explicitly-defined copy constructor is needed when the scope data is
00053 // present, to prevent the same pointer from being deleted twice. -SV.
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; // =VB= number of RPC tbins  
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; // =VB= get RPC tbins  
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   //int MaxSizeScope = 5;
00170   int e0bLine =-1;
00171   switch (firmwareVersion) {
00172   case 2007:
00173     e0bLine = 42; //last word of header2007
00174     break;
00175   case 2006:
00176     e0bLine = 26; //last word of header in 2006 format
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   //int i = currentPosition-1;
00201   //printf ( "%04x %04x %04x %04x\n",buf[i+3],buf[i+2],buf[i+1],buf[i] ) ;
00202  
00203 
00204   // look for RPC
00205   int b04Line = currentPosition;
00206   
00207   if(buf[b04Line]==0x6b04) {
00208     // we need an e04 line to calculate the size
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; //see tmb2004 manual (version v2p06) page54.
00228     break;
00229   default:
00230     edm::LogError("CSCTMBData|CSCRawToDigi") << "can't find TotTMBReadout - unknown firmware version!";
00231     break;
00232   }
00233   
00234 //std::cout << " !!!TMB Scope!!! " << std::endl;
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       // The size of the TMB scope data can vary, and I see no good reasons
00243       // not to determine it dynamically.  -SV, 5 Nov 2008.
00244       //currentPosition+=theTMBScope->sizeInWords();
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   //Now for CRC check put this information into bitset
00297 
00298   theB0CLine = b0cLine;
00299   theE0FLine = maxLine;
00300 
00301   // finally, the trailer
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   // Dump of TMB; format proposed by JK.
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   // size, since we count from 0 and have one more trailer word
00328   // there are sometimes multiple "de0f" lines in trailer, so key on "6e0c"
00329   return e0cLine-b0cLine+theTMBTrailer.sizeInWords();
00330 } //UnpackTMB
00331 
00332 bool CSCTMBData::checkSize() const 
00333 {
00334   // sum up all the components and see if they have the size indicated in the TMBTrailer
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 //  theTMBTrailer.setCRC(TMBCRCcalc());
00410 
00411   boost::dynamic_bitset<> tmbTrailer =  bitset_utilities::ushortToBitset( theTMBTrailer.sizeInWords()*16,
00412                                                                           theTMBTrailer.data());
00413   result = bitset_utilities::append(result,tmbTrailer);
00414   
00415   // now convert to a vector<bitset<16>>, so we can calculate the crc
00416   std::vector<std::bitset<16> > wordVector;
00417   // try to tune so it stops before the e0f line
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