File indexing completed on 2024-04-06 12:10:21
0001 #include "EventFilter/CastorRawToDigi/interface/CastorUnpacker.h"
0002 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
0003 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
0004 #include "EventFilter/HcalRawToDigi/interface/HcalTTPUnpacker.h"
0005 #include "DataFormats/HcalDetId/interface/HcalOtherDetId.h"
0006 #include "DataFormats/HcalDigi/interface/HcalQIESample.h"
0007 #include "DataFormats/HcalDigi/interface/CastorDataFrame.h"
0008 #include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveSample.h"
0009 #include <iostream>
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011
0012 namespace CastorUnpacker_impl {
0013 template <class DigiClass>
0014 const HcalQIESample* unpack(const HcalQIESample* startPoint,
0015 const HcalQIESample* limit,
0016 DigiClass& digi,
0017 int presamples,
0018 const CastorElectronicsId& eid,
0019 int startSample,
0020 int endSample,
0021 int expectedTime,
0022 const HcalHTRData& hhd) {
0023
0024 digi.setPresamples(presamples);
0025 int fiber = startPoint->fiber();
0026 int fiberchan = startPoint->fiberChan();
0027 uint32_t zsmask = hhd.zsBunchMask() >> startSample;
0028 digi.setZSInfo(hhd.isUnsuppressed(), hhd.wasMarkAndPassZS(fiber, fiberchan), zsmask);
0029
0030
0031
0032 if (expectedTime >= 0 && !hhd.isUnsuppressed()) {
0033
0034 digi.setFiberIdleOffset(hhd.getFibOrbMsgBCN(fiber) - expectedTime);
0035 }
0036
0037 int myFiberChan = startPoint->fiberAndChan();
0038 int ncurr = 0, ntaken = 0;
0039 const HcalQIESample* qie_work = startPoint;
0040 while (qie_work != limit && qie_work->fiberAndChan() == myFiberChan) {
0041 if (ncurr >= startSample && ncurr <= endSample) {
0042 digi.setSample(ntaken, *qie_work);
0043 ++ntaken;
0044 }
0045 ncurr++;
0046 qie_work++;
0047 }
0048 digi.setSize(ntaken);
0049 return qie_work;
0050 }
0051 }
0052
0053 namespace {
0054 inline bool isTPGSOI(const HcalTriggerPrimitiveSample& s) { return (s.raw() & 0x200) != 0; }
0055 }
0056
0057 CastorUnpacker::CastorUnpacker(int sourceIdOffset, int beg, int end)
0058 : sourceIdOffset_(sourceIdOffset), expectedOrbitMessageTime_(-1) {
0059 if (beg >= 0 && beg <= CastorDataFrame::MAXSAMPLES - 1) {
0060 startSample_ = beg;
0061 } else {
0062 startSample_ = 0;
0063 }
0064 if (end >= 0 && end <= CastorDataFrame::MAXSAMPLES - 1 && end >= beg) {
0065 endSample_ = end;
0066 } else {
0067 endSample_ = CastorDataFrame::MAXSAMPLES - 1;
0068 }
0069 }
0070
0071 static int slb(const HcalTriggerPrimitiveSample& theSample) { return ((theSample.raw() >> 13) & 0x7); }
0072 static int slbChan(const HcalTriggerPrimitiveSample& theSample) { return (theSample.raw() >> 11) & 0x3; }
0073 static int slbAndChan(const HcalTriggerPrimitiveSample& theSample) { return (theSample.raw() >> 11) & 0x1F; }
0074
0075 void CastorUnpacker::unpack(const FEDRawData& raw,
0076 const CastorElectronicsMap& emap,
0077 CastorRawCollections& colls,
0078 HcalUnpackerReport& report,
0079 bool silent) {
0080 if (raw.size() < 16) {
0081 if (!silent)
0082 edm::LogWarning("Invalid Data") << "Empty/invalid DCC data, size = " << raw.size();
0083 return;
0084 }
0085
0086
0087 const HcalDCCHeader* dccHeader = (const HcalDCCHeader*)(raw.data());
0088 int dccid = dccHeader->getSourceId() - sourceIdOffset_;
0089
0090
0091
0092
0093 HcalHTRData htr;
0094 const unsigned short *daq_first, *daq_last, *tp_first, *tp_last;
0095 const HcalQIESample *qie_begin, *qie_end, *qie_work;
0096 const HcalTriggerPrimitiveSample *tp_begin, *tp_end, *tp_work;
0097 for (int spigot = 0; spigot < HcalDCCHeader::SPIGOT_COUNT; spigot++) {
0098 if (!dccHeader->getSpigotPresent(spigot))
0099 continue;
0100
0101 int retval = dccHeader->getSpigotData(spigot, htr, raw.size());
0102 if (retval != 0) {
0103 if (retval == -1) {
0104 if (!silent)
0105 edm::LogWarning("Invalid Data") << "Invalid HTR data (data beyond payload size) observed on spigot " << spigot
0106 << " of DCC with source id " << dccHeader->getSourceId();
0107 report.countSpigotFormatError();
0108 }
0109 continue;
0110 }
0111
0112 if (dccHeader->getSpigotCRCError(spigot)) {
0113 if (!silent)
0114 edm::LogWarning("Invalid Data") << "CRC Error on HTR data observed on spigot " << spigot
0115 << " of DCC with source id " << dccHeader->getSourceId();
0116 report.countSpigotFormatError();
0117 continue;
0118 }
0119 if (!htr.check()) {
0120 if (!silent)
0121 edm::LogWarning("Invalid Data") << "Invalid HTR data observed on spigot " << spigot << " of DCC with source id "
0122 << dccHeader->getSourceId();
0123 report.countSpigotFormatError();
0124 continue;
0125 }
0126 if (htr.isHistogramEvent()) {
0127 if (!silent)
0128 edm::LogWarning("Invalid Data") << "Histogram data passed to non-histogram unpacker on spigot " << spigot
0129 << " of DCC with source id " << dccHeader->getSourceId();
0130 continue;
0131 }
0132 if ((htr.getFirmwareFlavor() & 0xE0) == 0x80) {
0133 if (colls.ttp != nullptr) {
0134 HcalTTPUnpacker ttpUnpack;
0135 colls.ttp->push_back(HcalTTPDigi());
0136 ttpUnpack.unpack(htr, colls.ttp->back());
0137 } else {
0138 LogDebug("CastorUnpackerHcalTechTrigProcessor")
0139 << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
0140 << " which is from the TechTrigProcessor (use separate unpacker!)";
0141 }
0142 continue;
0143 }
0144 if (htr.getFirmwareFlavor() >= 0x80) {
0145 if (!silent)
0146 edm::LogWarning("CastorUnpacker")
0147 << "Skipping data on spigot " << spigot << " of DCC with source id " << dccHeader->getSourceId()
0148 << " which is of unknown flavor " << htr.getFirmwareFlavor();
0149 continue;
0150 }
0151
0152 int nps = htr.getNPS() - startSample_;
0153
0154
0155 htr.dataPointers(&daq_first, &daq_last, &tp_first, &tp_last);
0156 unsigned int smid = htr.getSubmodule();
0157 int htr_tb = smid & 0x1;
0158 int htr_slot = (smid >> 1) & 0x1F;
0159 int htr_cr = (smid >> 6) & 0x1F;
0160
0161 tp_begin = (const HcalTriggerPrimitiveSample*)tp_first;
0162 tp_end = (const HcalTriggerPrimitiveSample*)(tp_last + 1);
0163
0164
0165 int currFiberChan = 0x3F;
0166 int ncurr = 0;
0167 bool valid = false;
0168
0169 bool tpgSOIbitInUse = htr.getFormatVersion() >= 3;
0170
0171
0172
0173
0174
0175 bool dotp = true;
0176 CastorElectronicsId eid(0, 1, spigot, dccid);
0177 eid.setHTR(htr_cr, htr_slot, htr_tb);
0178 DetId did = emap.lookup(eid);
0179 if (did.null())
0180 dotp = false;
0181 HcalCastorDetId id1(did);
0182 HcalCastorDetId id((id1.zside() == 0), id1.sector(), 1);
0183 if (id1.module() > 12)
0184 dotp = false;
0185 if (dotp) {
0186
0187
0188 for (tp_work = tp_begin; tp_work != tp_end; tp_work++) {
0189
0190 if (tp_work->raw() == 0xFFFF)
0191 continue;
0192 if (slbAndChan(*tp_work) != currFiberChan) {
0193 currFiberChan = slbAndChan(*tp_work);
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 colls.tpCont->push_back(CastorTriggerPrimitiveDigi(id));
0214
0215 if (!tpgSOIbitInUse)
0216 colls.tpCont->back().setPresamples(nps);
0217 colls.tpCont->back().setZSInfo(htr.isUnsuppressed(),
0218 htr.wasMarkAndPassZSTP(slb(*tp_work), slbChan(*tp_work)));
0219
0220
0221 ncurr = 0;
0222 valid = true;
0223 }
0224
0225 if (valid && ((tpgSOIbitInUse && ncurr < 10) || (ncurr >= startSample_ && ncurr <= endSample_))) {
0226 colls.tpCont->back().setSample(colls.tpCont->back().size(), *tp_work);
0227 colls.tpCont->back().setSize(colls.tpCont->back().size() + 1);
0228 }
0229
0230 if (valid && tpgSOIbitInUse && isTPGSOI(*tp_work)) {
0231 colls.tpCont->back().setPresamples(ncurr);
0232 }
0233 ncurr++;
0234 }
0235 }
0236
0237
0238 qie_begin = (const HcalQIESample*)daq_first;
0239 qie_end = (const HcalQIESample*)(daq_last + 1);
0240
0241
0242
0243 for (qie_work = qie_begin; qie_work != qie_end;) {
0244 if (qie_work->raw() == 0xFFFF) {
0245 qie_work++;
0246 continue;
0247 }
0248
0249
0250 CastorElectronicsId eid(qie_work->fiberChan(), qie_work->fiber(), spigot, dccid);
0251 eid.setHTR(htr_cr, htr_slot, htr_tb);
0252 DetId did = emap.lookup(eid);
0253
0254 if (!did.null()) {
0255 colls.castorCont->push_back(CastorDataFrame(HcalCastorDetId(did)));
0256 qie_work = CastorUnpacker_impl::unpack<CastorDataFrame>(qie_work,
0257 qie_end,
0258 colls.castorCont->back(),
0259 nps,
0260 eid,
0261 startSample_,
0262 endSample_,
0263 expectedOrbitMessageTime_,
0264 htr);
0265 } else {
0266 report.countUnmappedDigi();
0267 if (unknownIds_.find(eid) == unknownIds_.end()) {
0268 if (!silent)
0269 edm::LogWarning("CASTOR") << "CastorUnpacker: No match found for electronics id :" << eid;
0270 unknownIds_.insert(eid);
0271 }
0272 for (int fiberC = qie_work->fiberAndChan(); qie_work != qie_end && qie_work->fiberAndChan() == fiberC;
0273 qie_work++)
0274 ;
0275 }
0276 }
0277 }
0278 }