Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:14:59

0001 #include "EventFilter/ESRawToDigi/interface/ESUnpacker.h"
0002 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0003 #include "DataFormats/EcalDetId/interface/EcalDetIdCollections.h"
0004 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0005 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 
0008 #include <fstream>
0009 
0010 ESUnpacker::ESUnpacker(const edm::ParameterSet& ps)
0011     : pset_(ps), fedId_(0), run_number_(0), orbit_number_(0), bx_(0), lv1_(0), trgtype_(0) {
0012   debug_ = pset_.getUntrackedParameter<bool>("debugMode", false);
0013   lookup_ = ps.getParameter<edm::FileInPath>("LookupTable");
0014 
0015   m1 = ~(~Word64(0) << 1);
0016   m2 = ~(~Word64(0) << 2);
0017   m4 = ~(~Word64(0) << 4);
0018   m5 = ~(~Word64(0) << 5);
0019   m6 = ~(~Word64(0) << 6);
0020   m8 = ~(~Word64(0) << 8);
0021   m12 = ~(~Word64(0) << 12);
0022   m16 = ~(~Word64(0) << 16);
0023   m32 = ~(~Word64(0) << 32);
0024 
0025   // read in look-up table
0026   int nLines, iz, ip, ix, iy, fed, kchip, pace, bundle, fiber, optorx;
0027   std::ifstream file;
0028   file.open(lookup_.fullPath().c_str());
0029   if (file.is_open()) {
0030     file >> nLines;
0031 
0032     for (int i = 0; i < nLines; ++i) {
0033       file >> iz >> ip >> ix >> iy >> fed >> kchip >> pace >> bundle >> fiber >> optorx;
0034 
0035       zside_[kchip - 1][pace - 1] = iz;
0036       pl_[kchip - 1][pace - 1] = ip;
0037       x_[kchip - 1][pace - 1] = ix;
0038       y_[kchip - 1][pace - 1] = iy;
0039     }
0040 
0041   } else {
0042     edm::LogWarning("Invalid Data") << "ESUnpacker::ESUnpacker : Look up table file can not be found in "
0043                                     << lookup_.fullPath().c_str();
0044   }
0045 }
0046 
0047 ESUnpacker::~ESUnpacker() {}
0048 
0049 void ESUnpacker::interpretRawData(int fedId,
0050                                   const FEDRawData& rawData,
0051                                   ESRawDataCollection& dccs,
0052                                   ESLocalRawDataCollection& kchips,
0053                                   ESDigiCollection& digis) {
0054   unsigned int nWords = rawData.size() / sizeof(Word64);
0055   if (nWords == 0)
0056     return;
0057   int dccWords = 6;
0058   int head, kPACE[4], kFlag1, kFlag2, kBC, kEC, optoBC, optoEC;
0059   int kid = -1;
0060 
0061   ESDCCHeaderBlock ESDCCHeader;
0062   ESDCCHeader.setFedId(fedId);
0063 
0064   // Event header
0065   const Word64* header = reinterpret_cast<const Word64*>(rawData.data());
0066   --header;
0067   bool moreHeaders = true;
0068   while (moreHeaders) {
0069     ++header;
0070     FEDHeader ESHeader(reinterpret_cast<const unsigned char*>(header));
0071     if (!ESHeader.check()) {
0072       if (debug_)
0073         edm::LogWarning("Invalid Data") << "ES : Failed header check !";
0074       return;
0075     }
0076 
0077     fedId_ = ESHeader.sourceID();
0078     lv1_ = ESHeader.lvl1ID();
0079     bx_ = ESHeader.bxID();
0080 
0081     if (debug_) {
0082       LogDebug("ESUnpacker") << "[ESUnpacker]: FED Header candidate. Is header? " << ESHeader.check();
0083       if (ESHeader.check())
0084         LogDebug("ESUnpacker") << ". BXID: " << bx_ << " SourceID : " << fedId_ << " L1ID: " << lv1_;
0085       else
0086         LogDebug("ESUnpacker") << " WARNING!, this is not a ES Header";
0087     }
0088 
0089     moreHeaders = ESHeader.moreHeaders();
0090   }
0091   if (fedId != fedId_) {
0092     if (debug_)
0093       edm::LogWarning("Invalid Data") << "Invalid ES data with source id " << fedId_;
0094     ESDCCHeader.setDCCErrors(1);
0095     dccs.push_back(ESDCCHeader);
0096     return;
0097   }
0098   ESDCCHeader.setLV1(lv1_);
0099   ESDCCHeader.setBX(bx_);
0100 
0101   // Event trailer
0102   int slinkCRC = 1;
0103   const Word64* trailer = reinterpret_cast<const Word64*>(rawData.data()) + (nWords - 1);
0104   ++trailer;
0105   bool moreTrailers = true;
0106   while (moreTrailers) {
0107     --trailer;
0108     FEDTrailer ESTrailer(reinterpret_cast<const unsigned char*>(trailer));
0109     if (!ESTrailer.check()) {
0110       ++trailer;
0111       if (debug_)
0112         edm::LogWarning("Invalid Data") << "ES : Failed trailer check !";
0113       return;
0114     }
0115     if (ESTrailer.fragmentLength() != nWords) {
0116       if (debug_)
0117         edm::LogWarning("Invalid Data") << "Invalid ES data : the length is not correct !";
0118       ESDCCHeader.setDCCErrors(2);
0119       dccs.push_back(ESDCCHeader);
0120       return;
0121     }
0122     if (ESTrailer.fragmentLength() < 8) {
0123       if (debug_)
0124         edm::LogWarning("Invalid Data") << "Invalid ES data : the length is not correct !";
0125       ESDCCHeader.setDCCErrors(3);
0126       dccs.push_back(ESDCCHeader);
0127       return;
0128     }
0129     slinkCRC = (*trailer >> 2) & 0x1;
0130     if (debug_) {
0131       LogDebug("ESUnpacker") << "[ESUnpacker]: FED Trailer candidate. Is trailer? " << ESTrailer.check();
0132       if (ESTrailer.check())
0133         LogDebug("ESUnpacker") << ". Length of the ES event: " << ESTrailer.fragmentLength();
0134       else
0135         LogDebug("ESUnpacker") << " WARNING!, this is not a ES Trailer";
0136     }
0137 
0138     moreTrailers = ESTrailer.moreTrailers();
0139   }
0140 
0141   if (slinkCRC != 0) {
0142     ESDCCHeader.setDCCErrors(101);
0143     dccs.push_back(ESDCCHeader);
0144     return;
0145   }
0146 
0147   // DCC data
0148   std::vector<int> FEch_status;
0149   int dccHeaderCount = 0;
0150   int dccLineCount = 0;
0151   int dccHead, dccLine;
0152   int dccCRC1_ = 0;
0153   int dccCRC2_ = 0;
0154   int dccCRC3_ = 0;
0155   for (const Word64* word = (header + 1); word != (header + dccWords + 1); ++word) {
0156     if (debug_)
0157       LogDebug("ESUnpacker") << "DCC   : " << print(*word);
0158     dccHead = (*word >> 60) & m4;
0159     if (dccHead == 3)
0160       dccHeaderCount++;
0161     dccLine = (*word >> 56) & m4;
0162     dccLineCount++;
0163     if (dccLine != dccLineCount) {
0164       if (debug_)
0165         edm::LogWarning("Invalid Data") << "Invalid ES data : DCC header order is not correct !";
0166       ESDCCHeader.setDCCErrors(4);
0167       dccs.push_back(ESDCCHeader);
0168       return;
0169     }
0170     if (dccLineCount == 1) {
0171       dccCRC1_ = (*word >> 24) & m1;
0172       dccCRC2_ = (*word >> 25) & m1;
0173       dccCRC3_ = (*word >> 26) & m1;
0174     } else if (dccLineCount == 2) {
0175       runtype_ = (*word >> 0) & m4;
0176       seqtype_ = (*word >> 4) & m4;
0177       dac_ = (*word >> 8) & m12;
0178       gain_ = (*word >> 20) & m1;
0179       precision_ = (*word >> 21) & m1;
0180       trgtype_ = (*word >> 34) & m6;
0181 
0182       ESDCCHeader.setRunType(runtype_);
0183       ESDCCHeader.setSeqType(seqtype_);
0184       ESDCCHeader.setTriggerType(trgtype_);
0185       ESDCCHeader.setDAC(dac_);
0186       ESDCCHeader.setGain(gain_);
0187       ESDCCHeader.setPrecision(precision_);
0188     }
0189     if (dccLineCount == 3) {
0190       orbit_number_ = (*word >> 0) & m32;
0191       vminor_ = (*word >> 40) & m8;
0192       vmajor_ = (*word >> 48) & m8;
0193 
0194       ESDCCHeader.setOrbitNumber(orbit_number_);
0195       ESDCCHeader.setMajorVersion(vmajor_);
0196       ESDCCHeader.setMinorVersion(vminor_);
0197     }
0198     if (dccLineCount == 4)
0199       optoRX0_ = (*word >> 48) & m8;
0200     if (dccLineCount == 5)
0201       optoRX1_ = (*word >> 48) & m8;
0202     if (dccLineCount == 6)
0203       optoRX2_ = (*word >> 48) & m8;
0204     if (dccLineCount >= 4) {
0205       for (unsigned int j = 0; j < 12; ++j) {
0206         FEch_[(dccLineCount - 4) * 12 + j] = (*word >> (j * 4)) & m4;
0207         FEch_status.push_back(FEch_[(dccLineCount - 4) * 12 + j]);
0208       }
0209     }
0210   }
0211   if (vmajor_ < 4) {
0212     if (debug_)
0213       edm::LogWarning("Invalid Data") << "Invalid ES data format : " << vmajor_ << " " << vminor_;
0214     return;
0215   }
0216   if (dccHeaderCount != 6) {
0217     edm::LogWarning("Invalid Data") << "Invalid ES data : DCC header lines are " << dccHeaderCount;
0218     ESDCCHeader.setDCCErrors(5);
0219     dccs.push_back(ESDCCHeader);
0220     return;
0221   }
0222   ESDCCHeader.setOptoRX0(optoRX0_ + dccCRC1_);
0223   ESDCCHeader.setOptoRX1(optoRX1_ + dccCRC2_);
0224   ESDCCHeader.setOptoRX2(optoRX2_ + dccCRC3_);
0225   ESDCCHeader.setFEChannelStatus(FEch_status);
0226   int enableOptoRX[3] = {-1, -1, -1};
0227   int NenableOptoRX = 0;
0228   if (optoRX0_ == 128) {
0229     enableOptoRX[NenableOptoRX] = 0;
0230     NenableOptoRX++;
0231   }
0232   if (optoRX1_ == 128) {
0233     enableOptoRX[NenableOptoRX] = 1;
0234     NenableOptoRX++;
0235   }
0236   if (optoRX2_ == 128) {
0237     enableOptoRX[NenableOptoRX] = 2;
0238   }
0239 
0240   // Event data
0241   int iopto = 0;
0242   int opto = -1;
0243   for (const Word64* word = (header + dccWords + 1); word != trailer; ++word) {
0244     if (debug_)
0245       LogDebug("ESUnpacker") << "Event : " << print(*word);
0246 
0247     head = (*word >> 60) & m4;
0248 
0249     if (head == 12) {
0250       if ((opto == 0 && ESDCCHeader.getOptoRX0() == 129) || (opto == 1 && ESDCCHeader.getOptoRX1() == 129) ||
0251           (opto == 2 && ESDCCHeader.getOptoRX2() == 129))
0252         word2digi(kid, kPACE, *word, digis);
0253     } else if (head == 9) {
0254       kid = (*word >> 2) & 0x07ff;
0255       kPACE[0] = (*word >> 16) & m1;
0256       kPACE[1] = (*word >> 17) & m1;
0257       kPACE[2] = (*word >> 18) & m1;
0258       kPACE[3] = (*word >> 19) & m1;
0259       kFlag2 = (*word >> 20) & m4;
0260       kFlag1 = (*word >> 24) & m8;
0261       kBC = (*word >> 32) & m16;
0262       kEC = (*word >> 48) & m8;
0263 
0264       ESKCHIPBlock ESKCHIP;
0265       ESKCHIP.setId(kid);
0266       ESKCHIP.setBC(kBC);
0267       ESKCHIP.setEC(kEC);
0268       ESKCHIP.setOptoBC(optoBC);
0269       ESKCHIP.setOptoEC(optoEC);
0270       ESKCHIP.setFlag1(kFlag1);
0271       ESKCHIP.setFlag2(kFlag2);
0272       kchips.push_back(ESKCHIP);
0273     } else if (head == 6) {
0274       optoBC = (*word >> 32) & m16;
0275       optoEC = (*word >> 48) & m8;
0276 
0277       opto = enableOptoRX[iopto];
0278       if (opto == 0)
0279         ESDCCHeader.setOptoBC0(optoBC);
0280       else if (opto == 1)
0281         ESDCCHeader.setOptoBC1(optoBC);
0282       else if (opto == 2)
0283         ESDCCHeader.setOptoBC2(optoBC);
0284       if (iopto < 2)
0285         ++iopto;
0286     }
0287   }
0288 
0289   dccs.push_back(ESDCCHeader);
0290 }
0291 
0292 void ESUnpacker::word2digi(int kid, int kPACE[4], const Word64& word, ESDigiCollection& digis) {
0293   int pace = (word >> 53) & m2;
0294   if (kPACE[pace] == 0)
0295     return;
0296   if (kid > 1511 || kid < 1)
0297     return;
0298 
0299   int adc[3];
0300   adc[0] = (word >> 0) & m16;
0301   adc[1] = (word >> 16) & m16;
0302   adc[2] = (word >> 32) & m16;
0303   int strip = (word >> 48) & m5;
0304 
0305   if (debug_)
0306     LogDebug("ESUnpacker") << kid << " " << strip << " " << pace << " " << adc[0] << " " << adc[1] << " " << adc[2];
0307 
0308   int zside, plane, ix, iy;
0309   zside = zside_[kid - 1][pace];
0310   plane = pl_[kid - 1][pace];
0311   ix = x_[kid - 1][pace];
0312   iy = y_[kid - 1][pace];
0313 
0314   // convert strip number from electronics id to detector id
0315   if (vmajor_ == 4 && (vminor_ == 2 || vminor_ == 3)) {
0316     if (zside == 1 && plane == 1 && iy <= 20)
0317       strip = 31 - strip;
0318     if (zside == 1 && plane == 2 && ix > 20)
0319       strip = 31 - strip;
0320     if (zside == -1 && plane == 1 && iy > 20)
0321       strip = 31 - strip;
0322     if (zside == -1 && plane == 2 && ix <= 20)
0323       strip = 31 - strip;
0324   }
0325 
0326   if (debug_)
0327     LogDebug("ESUnpacker") << "DetId : " << zside << " " << plane << " " << ix << " " << iy << " " << strip + 1;
0328 
0329   if (ESDetId::validDetId(strip + 1, ix, iy, plane, zside)) {
0330     ESDetId detId(strip + 1, ix, iy, plane, zside);
0331     ESDataFrame df(detId);
0332     df.setSize(3);
0333 
0334     for (int i = 0; i < 3; i++)
0335       df.setSample(i, adc[i]);
0336 
0337     digis.push_back(df);
0338 
0339     if (debug_)
0340       LogDebug("ESUnpacker") << "Si : " << detId.zside() << " " << detId.plane() << " " << detId.six() << " "
0341                              << detId.siy() << " " << detId.strip() << " (" << kid << "," << pace << ") "
0342                              << df.sample(0).adc() << " " << df.sample(1).adc() << " " << df.sample(2).adc();
0343   }
0344 }
0345 
0346 std::string ESUnpacker::print(const Word64& word) const {
0347   std::ostringstream str;
0348   str << "Word64:  " << reinterpret_cast<const std::bitset<64>&>(word);
0349   return str.str();
0350 }