CMS 3D CMS Logo

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     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 // Explicitly-defined copy constructor is needed when the scope data is
00045 // present, to prevent the same pointer from being deleted twice. -SV.
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; // =VB= number of RPC tbins  
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; // =VB= get RPC tbins  
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   //int MaxSizeScope = 5;
00135   int e0bLine =-1;
00136   switch (firmwareVersion) {
00137   case 2007:
00138     e0bLine = 42; //last word of header2007
00139     break;
00140   case 2006:
00141     e0bLine = 26; //last word of header in 2006 format
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   //int i = currentPosition-1;
00166   //printf ( "%04x %04x %04x %04x\n",buf[i+3],buf[i+2],buf[i+1],buf[i] ) ;
00167  
00168 
00169   // look for RPC
00170   int b04Line = currentPosition;
00171   
00172   if(buf[b04Line]==0x6b04) {
00173     // we need an e04 line to calculate the size
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; //see tmb2004 manual (version v2p06) page54.
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       // The size of the TMB scope data can vary, and I see no good reasons
00208       // not to determine it dynamically.  -SV, 5 Nov 2008.
00209       //currentPosition+=theTMBScope->sizeInWords();
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   //Now for CRC check put this information into bitset
00226 
00227   theB0CLine = b0cLine;
00228   theE0FLine = maxLine;
00229 
00230   // finally, the trailer
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   // Dump of TMB; format proposed by JK.
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   // size, since we count from 0 and have one more trailer word
00257   // there are sometimes multiple "de0f" lines in trailer, so key on "6e0c"
00258   return e0cLine-b0cLine+theTMBTrailer.sizeInWords();
00259 } //UnpackTMB
00260 
00261 bool CSCTMBData::checkSize() const 
00262 {
00263   // sum up all the components and see if they have the size indicated in the TMBTrailer
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 //  theTMBTrailer.setCRC(TMBCRCcalc());
00326 
00327   boost::dynamic_bitset<> tmbTrailer =  bitset_utilities::ushortToBitset( theTMBTrailer.sizeInWords()*16,
00328                                                                           theTMBTrailer.data());
00329   result = bitset_utilities::append(result,tmbTrailer);
00330   
00331   // now convert to a vector<bitset<16>>, so we can calculate the crc
00332   std::vector<std::bitset<16> > wordVector;
00333   // try to tune so it stops before the e0f line
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 

Generated on Tue Jun 9 17:34:24 2009 for CMSSW by  doxygen 1.5.4