CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/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     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 // Explicitly-defined copy constructor is needed when the scope data is
00057 // present, to prevent the same pointer from being deleted twice. -SV.
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; //WARNING in 5_0_X
00144   int NRPCtbins = 0; // =VB= number of RPC tbins  
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; // =VB= get RPC tbins  
00156     NHeaderFrames = buf[b0cLine+5]&0x3F; //WARNING in 5_0_X
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; //WARNING in 5_0_X
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   //int MaxSizeScope = 5;
00175   int e0bLine =-1;
00176   switch (firmwareVersion) {
00177   case 2007:
00178     e0bLine = 42; //last word of header2007
00179     break;
00180   case 2006:
00181     e0bLine = 26; //last word of header in 2006 format
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   //int i = currentPosition-1;
00206   //printf ( "%04x %04x %04x %04x\n",buf[i+3],buf[i+2],buf[i+1],buf[i] ) ;
00207  
00208 
00209   // look for RPC
00210   int b04Line = currentPosition;
00211   
00212   if(buf[b04Line]==0x6b04) {
00213     // we need an e04 line to calculate the size
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; //see tmb2004 manual (version v2p06) page54.
00233     break;
00234   default:
00235     edm::LogError("CSCTMBData|CSCRawToDigi") << "can't find TotTMBReadout - unknown firmware version!";
00236     break;
00237   }
00238   
00239 //std::cout << " !!!TMB Scope!!! " << std::endl;
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       // The size of the TMB scope data can vary, and I see no good reasons
00248       // not to determine it dynamically.  -SV, 5 Nov 2008.
00249       //currentPosition+=theTMBScope->sizeInWords();
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   //Now for CRC check put this information into bitset
00302 
00303   theB0CLine = b0cLine;
00304   theE0FLine = maxLine;
00305 
00306   // finally, the trailer
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   // Dump of TMB; format proposed by JK.
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   // size, since we count from 0 and have one more trailer word
00333   // there are sometimes multiple "de0f" lines in trailer, so key on "6e0c"
00334   return e0cLine-b0cLine+theTMBTrailer.sizeInWords();
00335 } //UnpackTMB
00336 
00337 bool CSCTMBData::checkSize() const 
00338 {
00339   // sum up all the components and see if they have the size indicated in the TMBTrailer
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 //  theTMBTrailer.setCRC(TMBCRCcalc());
00415 
00416   boost::dynamic_bitset<> tmbTrailer =  bitset_utilities::ushortToBitset( theTMBTrailer.sizeInWords()*16,
00417                                                                           theTMBTrailer.data());
00418   result = bitset_utilities::append(result,tmbTrailer);
00419   
00420   // now convert to a vector<bitset<16>>, so we can calculate the crc
00421   std::vector<std::bitset<16> > wordVector;
00422   // try to tune so it stops before the e0f line
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