CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/EventFilter/ESRawToDigi/src/ESUnpacker.cc

Go to the documentation of this file.
00001 #include "EventFilter/ESRawToDigi/interface/ESUnpacker.h"
00002 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00003 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
00004 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00005 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007 
00008 #include <fstream>
00009 
00010 ESUnpacker::ESUnpacker(const edm::ParameterSet& ps) 
00011   : pset_(ps), fedId_(0), run_number_(0), orbit_number_(0), bx_(0), lv1_(0), trgtype_(0)
00012 {
00013 
00014   debug_ = pset_.getUntrackedParameter<bool>("debugMode", false);
00015   lookup_ = ps.getParameter<edm::FileInPath>("LookupTable");
00016 
00017   m1  = ~(~Word64(0) << 1);
00018   m2  = ~(~Word64(0) << 2);
00019   m4  = ~(~Word64(0) << 4);
00020   m5  = ~(~Word64(0) << 5);
00021   m6  = ~(~Word64(0) << 6);
00022   m8  = ~(~Word64(0) << 8);
00023   m12 = ~(~Word64(0) << 12);
00024   m16 = ~(~Word64(0) << 16);
00025   m32 = ~(~Word64(0) << 32);
00026 
00027   // read in look-up table
00028   int nLines, iz, ip, ix, iy, fed, kchip, pace, bundle, fiber, optorx;
00029   std::ifstream file;
00030   file.open(lookup_.fullPath().c_str());
00031   if( file.is_open() ) {
00032 
00033     file >> nLines;
00034 
00035     for (int i=0; i<nLines; ++i) {
00036       file>> iz >> ip >> ix >> iy >> fed >> kchip >> pace >> bundle >> fiber >> optorx;
00037 
00038       zside_[kchip-1][pace-1] = iz;
00039       pl_[kchip-1][pace-1] = ip;
00040       x_[kchip-1][pace-1] = ix;
00041       y_[kchip-1][pace-1] = iy;      
00042     }
00043     
00044   } else {
00045     std::cout<<"ESUnpacker::ESUnpacker : Look up table file can not be found in "<<lookup_.fullPath().c_str()<<std::endl;
00046   }
00047 
00048 }
00049 
00050 ESUnpacker::~ESUnpacker() {
00051 }
00052 
00053 void ESUnpacker::interpretRawData(int fedId, const FEDRawData & rawData, ESRawDataCollection & dccs, ESLocalRawDataCollection & kchips, ESDigiCollection & digis) {
00054   
00055   int nWords = rawData.size()/sizeof(Word64);
00056   if (nWords==0) return;
00057   int dccWords = 6;
00058   int head, kPACE[4], kFlag1, kFlag2, kBC, kEC, optoBC, optoEC;
00059   int kid = -1;
00060 
00061   ESDCCHeaderBlock ESDCCHeader;
00062   ESDCCHeader.setFedId(fedId);
00063 
00064   // Event header
00065   const Word64* header = reinterpret_cast<const Word64* >(rawData.data()); --header;
00066   bool moreHeaders = true;
00067   while (moreHeaders) {
00068     ++header;
00069     FEDHeader ESHeader( reinterpret_cast<const unsigned char*>(header) );
00070     if ( !ESHeader.check() ) {
00071       if (debug_) edm::LogWarning("Invalid Data")<<"ES : Failed header check !";
00072       return;
00073     }
00074 
00075     fedId_ = ESHeader.sourceID();
00076     lv1_   = ESHeader.lvl1ID();
00077     bx_    = ESHeader.bxID();
00078 
00079     if (debug_) {
00080       std::cout<<"[ESUnpacker]: FED Header candidate. Is header? "<< ESHeader.check();
00081       if (ESHeader.check())
00082         std::cout <<". BXID: "<<bx_<<" SourceID : "<<fedId_<<" L1ID: "<<lv1_<<std::endl;
00083       else std::cout<<" WARNING!, this is not a ES Header"<<std::endl;
00084     }
00085     
00086     moreHeaders = ESHeader.moreHeaders();
00087   }
00088   if ( fedId != fedId_) {
00089     if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data with source id " <<fedId_;
00090     ESDCCHeader.setDCCErrors(1);
00091     dccs.push_back(ESDCCHeader);
00092     return;
00093   }
00094   ESDCCHeader.setLV1(lv1_);
00095   ESDCCHeader.setBX(bx_);
00096 
00097   // Event trailer
00098   int slinkCRC = 1;
00099   const Word64* trailer = reinterpret_cast<const Word64* >(rawData.data())+(nWords-1); ++trailer;
00100   bool moreTrailers = true;
00101   while (moreTrailers) {
00102     --trailer;
00103     FEDTrailer ESTrailer(reinterpret_cast<const unsigned char*>(trailer));
00104     if ( !ESTrailer.check()) { 
00105       ++trailer; 
00106       if (debug_) edm::LogWarning("Invalid Data")<<"ES : Failed trailer check !";
00107       return;
00108     } 
00109     if ( ESTrailer.lenght() != nWords) {
00110       if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : the length is not correct !";
00111       ESDCCHeader.setDCCErrors(2);
00112       dccs.push_back(ESDCCHeader);
00113       return;
00114     }
00115     if ( ESTrailer.lenght() < 8) {
00116       if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : the length is not correct !";
00117       ESDCCHeader.setDCCErrors(3);
00118       dccs.push_back(ESDCCHeader);
00119       return;
00120     }
00121     slinkCRC = (*trailer >> 2 ) & 0x1;
00122     if (debug_)  {
00123       std::cout<<"[ESUnpacker]: FED Trailer candidate. Is trailer? "<<ESTrailer.check();
00124       if (ESTrailer.check())
00125         std::cout<<". Length of the ES event: "<<ESTrailer.lenght()<<std::endl;
00126       else std::cout<<" WARNING!, this is not a ES Trailer"<<std::endl;
00127     }
00128 
00129     moreTrailers = ESTrailer.moreTrailers();
00130   }
00131 
00132   if (slinkCRC != 0) {
00133     ESDCCHeader.setDCCErrors(101);
00134     dccs.push_back(ESDCCHeader);
00135     return;
00136   }
00137 
00138   // DCC data
00139   std::vector<int> FEch_status;
00140   int dccHeaderCount = 0;
00141   int dccLineCount = 0;
00142   int dccHead, dccLine;
00143   int dccCRC1_ = 0;
00144   int dccCRC2_ = 0;
00145   int dccCRC3_ = 0;
00146   for (const Word64* word=(header+1); word!=(header+dccWords+1); ++word) {
00147     if (debug_) std::cout<<"DCC   : "<<print(*word)<<std::endl;
00148     dccHead = (*word >> 60) & m4;
00149     if (dccHead == 3) dccHeaderCount++;
00150     dccLine = (*word >> 56) & m4;
00151     dccLineCount++;
00152     if (dccLine != dccLineCount) {
00153       if (debug_) edm::LogWarning("Invalid Data")<<"Invalid ES data : DCC header order is not correct !";
00154       ESDCCHeader.setDCCErrors(4);
00155       dccs.push_back(ESDCCHeader);
00156       return; 
00157     }
00158     if (dccLineCount == 1) {
00159       dccCRC1_ = (*word >> 24) & m1; 
00160       dccCRC2_ = (*word >> 25) & m1; 
00161       dccCRC3_ = (*word >> 26) & m1; 
00162     } else if (dccLineCount == 2) {
00163       runtype_   = (*word >>  0) & m4;
00164       seqtype_   = (*word >>  4) & m4;
00165       dac_       = (*word >>  8) & m12; 
00166       gain_      = (*word >> 20) & m1;
00167       precision_ = (*word >> 21) & m1;
00168       trgtype_   = (*word >> 34) & m6;
00169 
00170       ESDCCHeader.setRunType(runtype_);
00171       ESDCCHeader.setSeqType(seqtype_);
00172       ESDCCHeader.setTriggerType(trgtype_);
00173       ESDCCHeader.setDAC(dac_);
00174       ESDCCHeader.setGain(gain_);
00175       ESDCCHeader.setPrecision(precision_);
00176     }
00177     if (dccLineCount == 3) {
00178       orbit_number_ = (*word >>  0) & m32;
00179       vminor_       = (*word >> 40) & m8;
00180       vmajor_       = (*word >> 48) & m8;
00181 
00182       ESDCCHeader.setOrbitNumber(orbit_number_);
00183       ESDCCHeader.setMajorVersion(vmajor_);
00184       ESDCCHeader.setMinorVersion(vminor_);
00185     }
00186     if (dccLineCount == 4) optoRX0_  = (*word >> 48) & m8;
00187     if (dccLineCount == 5) optoRX1_  = (*word >> 48) & m8;
00188     if (dccLineCount == 6) optoRX2_  = (*word >> 48) & m8;
00189     if (dccLineCount >=4) {
00190       for (unsigned int j=0; j<12; ++j) {
00191         FEch_[(dccLineCount-4)*12+j] = (*word >> (j*4)) & m4;
00192         FEch_status.push_back(FEch_[(dccLineCount-4)*12+j]);
00193       }
00194     }
00195   }
00196   if (vmajor_ < 4) {
00197     if (debug_) 
00198       edm::LogWarning("Invalid Data")<<"Invalid ES data format : "<<vmajor_<<" "<<vminor_;
00199     return;
00200   }
00201   if (dccHeaderCount != 6) {
00202     edm::LogWarning("Invalid Data")<<"Invalid ES data : DCC header lines are "<<dccHeaderCount;
00203     ESDCCHeader.setDCCErrors(5);
00204     dccs.push_back(ESDCCHeader);
00205     return;
00206   }
00207   ESDCCHeader.setOptoRX0(optoRX0_ + dccCRC1_);
00208   ESDCCHeader.setOptoRX1(optoRX1_ + dccCRC2_);
00209   ESDCCHeader.setOptoRX2(optoRX2_ + dccCRC3_);
00210   ESDCCHeader.setFEChannelStatus(FEch_status);
00211 
00212   // Event data
00213   int opto = 0;
00214   for (const Word64* word=(header+dccWords+1); word!=trailer; ++word) {
00215     if (debug_) std::cout<<"Event : "<<print(*word)<<std::endl;
00216 
00217     head = (*word >> 60) & m4;
00218 
00219     if (head == 12) {
00220       if ((opto==1 && ESDCCHeader.getOptoRX0()==129) || (opto==2 && ESDCCHeader.getOptoRX1()==129) || (opto==3 && ESDCCHeader.getOptoRX2()==129)) 
00221         word2digi(kid, kPACE, *word, digis);
00222     } else if (head == 9) {
00223       kid      = (*word >> 2) & 0x07ff;
00224       kPACE[0] = (*word >> 16) & m1;
00225       kPACE[1] = (*word >> 17) & m1;
00226       kPACE[2] = (*word >> 18) & m1;
00227       kPACE[3] = (*word >> 19) & m1;
00228       kFlag2   = (*word >> 20) & m4;
00229       kFlag1   = (*word >> 24) & m8;
00230       kBC      = (*word >> 32) & m16;
00231       kEC      = (*word >> 48) & m8;
00232 
00233       ESKCHIPBlock ESKCHIP;
00234       ESKCHIP.setId(kid);
00235       ESKCHIP.setBC(kBC);
00236       ESKCHIP.setEC(kEC);
00237       ESKCHIP.setOptoBC(optoBC);
00238       ESKCHIP.setOptoEC(optoEC);
00239       ESKCHIP.setFlag1(kFlag1);
00240       ESKCHIP.setFlag2(kFlag2);
00241       kchips.push_back(ESKCHIP);
00242     } else if (head == 6) {
00243       optoBC = (*word >> 32) & m16;
00244       optoEC = (*word >> 48) & m8;      
00245       if (opto==0) ESDCCHeader.setOptoBC0(optoBC);
00246       else if (opto==1) ESDCCHeader.setOptoBC1(optoBC);
00247       else if (opto==2) ESDCCHeader.setOptoBC2(optoBC);
00248       opto++;
00249     }
00250   }
00251 
00252   dccs.push_back(ESDCCHeader);
00253 }
00254 
00255 void ESUnpacker::word2digi(int kid, int kPACE[4], const Word64 & word, ESDigiCollection & digis) 
00256 {
00257 
00258   int pace  = (word >> 53) & m2;
00259   if (kPACE[pace]==0) return;
00260   if (kid > 1511 || kid < 1) return;
00261   
00262   int adc[3];
00263   adc[0]    = (word >> 0)  & m16;
00264   adc[1]    = (word >> 16) & m16;
00265   adc[2]    = (word >> 32) & m16;
00266   int strip = (word >> 48) & m5;
00267 
00268   if (debug_) std::cout<<kid<<" "<<strip<<" "<<pace<<" "<<adc[0]<<" "<<adc[1]<<" "<<adc[2]<<std::endl;
00269 
00270   int zside, plane, ix, iy;
00271   zside = zside_[kid-1][pace];
00272   plane = pl_[kid-1][pace];
00273   ix    = x_[kid-1][pace];
00274   iy    = y_[kid-1][pace];
00275   
00276   // convert strip number from electronics id to detector id
00277   if (vmajor_ == 4 && (vminor_==2 || vminor_==3)) {
00278     if (zside == 1 && plane == 1 && iy <= 20) strip = 31 - strip;
00279     if (zside == 1 && plane == 2 && ix > 20) strip = 31 - strip;
00280     if (zside == -1 && plane == 1 && iy > 20) strip = 31 - strip;
00281     if (zside == -1 && plane == 2 && ix <= 20) strip = 31 - strip;
00282   }
00283 
00284   if (debug_) std::cout<<"DetId : "<<zside<<" "<<plane<<" "<<ix<<" "<<iy<<" "<<strip+1<<std::endl;
00285   
00286   if (ESDetId::validDetId(strip+1, ix, iy, plane, zside)) {
00287     
00288     ESDetId detId(strip+1, ix, iy, plane, zside);
00289     ESDataFrame df(detId);
00290     df.setSize(3);
00291     
00292     for (int i=0; i<3; i++) df.setSample(i, adc[i]);  
00293     
00294     digis.push_back(df);
00295     
00296     if (debug_) 
00297       std::cout<<"Si : "<<detId.zside()<<" "<<detId.plane()<<" "<<detId.six()<<" "<<detId.siy()<<" "<<detId.strip()<<" ("<<kid<<","<<pace<<") "<<df.sample(0).adc()<<" "<<df.sample(1).adc()<<" "<<df.sample(2).adc()<<std::endl;
00298   }
00299 
00300 }
00301 
00302 std::string ESUnpacker::print(const  Word64 & word) const
00303 {
00304   std::ostringstream str;
00305   str << "Word64:  " << reinterpret_cast<const std::bitset<64>&> (word);
00306   return str.str();
00307 }
00308