File indexing completed on 2024-04-06 12:10:39
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
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
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
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
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
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
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 }