File indexing completed on 2023-05-08 23:18:48
0001 #include "EventFilter/HcalRawToDigi/interface/HcalPacker.h"
0002 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
0003 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
0004 #include "DataFormats/HcalDetId/interface/HcalGenericDetId.h"
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0007 #include "FWCore/Utilities/interface/CRC16.h"
0008
0009 HcalPacker::Collections::Collections() {
0010 hbhe = nullptr;
0011 hoCont = nullptr;
0012 hfCont = nullptr;
0013 tpCont = nullptr;
0014 zdcCont = nullptr;
0015 calibCont = nullptr;
0016 }
0017
0018 template <class Coll, class DetIdClass>
0019 int process(const Coll* pt, const DetId& did, unsigned short* buffer, int& presamples, bool& isUS, bool& isMP) {
0020 isUS = false;
0021 isMP = false;
0022 if (pt == nullptr) {
0023 return 0;
0024 }
0025 int size = 0;
0026 typename Coll::const_iterator i = pt->find(DetIdClass(did));
0027 if (i != pt->end()) {
0028 isUS = i->zsUnsuppressed();
0029 isMP = i->zsMarkAndPass();
0030 presamples = i->presamples();
0031 size = i->size();
0032 for (int j = 0; j < size; j++) {
0033 buffer[j] = (*i)[j].raw();
0034 }
0035 }
0036 return size;
0037 }
0038
0039 static unsigned char processTrig(const HcalTrigPrimDigiCollection* pt,
0040 const HcalTrigTowerDetId& tid,
0041 unsigned short* buffer) {
0042 if (pt == nullptr) {
0043 return 0;
0044 }
0045 int size = 0;
0046 HcalTrigPrimDigiCollection::const_iterator i = pt->find(tid);
0047 bool any_nonzero = false;
0048 if (i != pt->end()) {
0049 int presamples = i->presamples();
0050 size = i->size();
0051
0052 for (int j = 0; j < size; j++) {
0053 buffer[j] = (*i)[j].raw();
0054 if ((buffer[j] & 0x1FF) != 0)
0055 any_nonzero = true;
0056 if (j == presamples) {
0057 buffer[j] |= 0x0200;
0058 }
0059 }
0060 }
0061 return (any_nonzero) ? (size) : (0);
0062 }
0063
0064 int HcalPacker::findSamples(const DetId& did,
0065 const Collections& inputs,
0066 unsigned short* buffer,
0067 int& presamples,
0068 bool& isUS,
0069 bool& isMP) const {
0070 if (!(did.det() == DetId::Hcal || (did.det() == DetId::Calo && did.subdetId() == HcalZDCDetId::SubdetectorId))) {
0071 return 0;
0072 }
0073 int size = 0;
0074 HcalGenericDetId genId(did);
0075
0076 switch (genId.genericSubdet()) {
0077 case (HcalGenericDetId::HcalGenBarrel):
0078 case (HcalGenericDetId::HcalGenEndcap):
0079 size = process<HBHEDigiCollection, HcalDetId>(inputs.hbhe, did, buffer, presamples, isUS, isMP);
0080 break;
0081 case (HcalGenericDetId::HcalGenOuter):
0082 size = process<HODigiCollection, HcalDetId>(inputs.hoCont, did, buffer, presamples, isUS, isMP);
0083 break;
0084 case (HcalGenericDetId::HcalGenForward):
0085 size = process<HFDigiCollection, HcalDetId>(inputs.hfCont, did, buffer, presamples, isUS, isMP);
0086 break;
0087 case (HcalGenericDetId::HcalGenZDC):
0088 size = process<ZDCDigiCollection, HcalZDCDetId>(inputs.zdcCont, did, buffer, presamples, isUS, isMP);
0089 break;
0090 case (HcalGenericDetId::HcalGenCalibration):
0091 size = process<HcalCalibDigiCollection, HcalCalibDetId>(inputs.calibCont, did, buffer, presamples, isUS, isMP);
0092 break;
0093 default:
0094 size = 0;
0095 }
0096 return size;
0097 }
0098
0099 void HcalPacker::pack(int fedid,
0100 int dccnumber,
0101 int nl1a,
0102 int orbitn,
0103 int bcn,
0104 const Collections& inputs,
0105 const HcalElectronicsMap& emap,
0106 FEDRawData& output) const {
0107 std::vector<unsigned short> precdata(HcalHTRData::CHANNELS_PER_SPIGOT * HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
0108 std::vector<unsigned short> trigdata(HcalHTRData::CHANNELS_PER_SPIGOT * HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL);
0109 std::vector<unsigned char> preclen(HcalHTRData::CHANNELS_PER_SPIGOT);
0110 std::vector<unsigned char> triglen(HcalHTRData::CHANNELS_PER_SPIGOT);
0111 static const int HTRFormatVersion = 5;
0112 bool channelIsMP[HcalHTRData::CHANNELS_PER_SPIGOT];
0113
0114 HcalHTRData spigots[15];
0115
0116 for (int spigot = 0; spigot < 15; spigot++) {
0117 spigots[spigot].allocate(HTRFormatVersion);
0118 HcalElectronicsId exampleEId;
0119 int npresent = 0;
0120 int presamples = -1, samples = -1;
0121 bool haveUnsuppressed = false;
0122 for (int fiber = 1; fiber <= 8; fiber++) {
0123 for (int fiberchan = 0; fiberchan < 3; fiberchan++) {
0124 int linear = (fiber - 1) * 3 + fiberchan;
0125 HcalQIESample chanSample(0, 0, fiber, fiberchan, false, false);
0126 unsigned short chanid = chanSample.raw() & 0xF800;
0127 preclen[linear] = 0;
0128 channelIsMP[linear] = false;
0129
0130 HcalElectronicsId partialEid(fiberchan, fiber, spigot, dccnumber);
0131
0132 HcalElectronicsId fullEid;
0133 HcalGenericDetId genId;
0134 if (!emap.lookup(partialEid, fullEid, genId)) {
0135 continue;
0136 }
0137
0138
0139 unsigned short* database = &(precdata[linear * HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL]);
0140 int mypresamples = -1;
0141 bool isUS = false, isMP = false;
0142 int mysamples = findSamples(genId, inputs, database, mypresamples, isUS, isMP);
0143 haveUnsuppressed = haveUnsuppressed || isUS;
0144 channelIsMP[linear] = isMP;
0145
0146 if (mysamples > 0) {
0147 if (samples < 0) {
0148 samples = mysamples;
0149 } else if (samples != mysamples) {
0150 edm::LogError("HCAL") << "Mismatch of samples in a single HTR (unsupported) " << mysamples
0151 << " != " << samples;
0152 continue;
0153 }
0154 if (presamples < 0) {
0155 presamples = mypresamples;
0156 exampleEId = fullEid;
0157 } else if (mypresamples != presamples) {
0158 edm::LogError("HCAL") << "Mismatch of presamples in a single HTR (unsupported) " << mypresamples
0159 << " != " << presamples;
0160 continue;
0161 }
0162 for (int ii = 0; ii < samples; ii++) {
0163 database[ii] = (database[ii] & 0x7FF) | chanid;
0164 }
0165 preclen[linear] = (unsigned char)(samples);
0166 npresent++;
0167 }
0168 }
0169 }
0170 for (int slb = 1; slb <= 6; slb++) {
0171 for (int slbchan = 0; slbchan <= 3; slbchan++) {
0172 int linear = (slb - 1) * 4 + slbchan;
0173 HcalTriggerPrimitiveSample idCvt(0, false, slb, slbchan);
0174 unsigned short chanid = idCvt.raw() & 0xF800;
0175 triglen[linear] = 0;
0176
0177 HcalElectronicsId partialEid(slbchan, slb, spigot, dccnumber, 0, 0, 0);
0178
0179 HcalElectronicsId fullEid;
0180 HcalTrigTowerDetId tid;
0181 if (!emap.lookup(partialEid, fullEid, tid)) {
0182
0183 continue;
0184 }
0185
0186
0187 if (!tid.null()) {
0188 if (presamples < 0) {
0189 exampleEId = fullEid;
0190 }
0191 unsigned short* trigbase = &(trigdata[linear * HcalHTRData::MAXIMUM_SAMPLES_PER_CHANNEL]);
0192 triglen[linear] = processTrig(inputs.tpCont, tid, trigbase);
0193 if (triglen[linear]) {
0194 npresent++;
0195 }
0196
0197 for (unsigned char q = 0; q < triglen[linear]; q++) {
0198 trigbase[q] = (trigbase[q] & 0x7FF) | chanid;
0199 }
0200 }
0201 }
0202 }
0203
0204 if (npresent > 0) {
0205 spigots[spigot].pack(&(preclen[0]), &(precdata[0]), &(triglen[0]), &(trigdata[0]), false);
0206 static const int pipeline = 0x22;
0207 static const int firmwareRev = 0;
0208 int submodule = exampleEId.htrTopBottom() & 0x1;
0209 submodule |= (exampleEId.htrSlot() & 0x1F) << 1;
0210 submodule |= (exampleEId.readoutVMECrateId() & 0x1f) << 6;
0211
0212
0213 if (samples < 0) {
0214 samples = 0;
0215 }
0216 if (presamples < 0) {
0217 presamples = 0;
0218 }
0219 spigots[spigot].packHeaderTrailer(nl1a,
0220 bcn,
0221 submodule,
0222 orbitn,
0223 pipeline,
0224 samples,
0225 presamples,
0226 firmwareRev,
0227 1);
0228 if (haveUnsuppressed) {
0229 spigots[spigot].packUnsuppressed(channelIsMP);
0230 }
0231 }
0232 }
0233
0234 int theSize = 0;
0235 for (int spigot = 0; spigot < 15; spigot++) {
0236 theSize += spigots[spigot].getRawLength() * sizeof(unsigned short);
0237 }
0238 theSize += sizeof(HcalDCCHeader) + 8;
0239 theSize += (8 - (theSize % 8)) % 8;
0240 output.resize(theSize);
0241
0242
0243 HcalDCCHeader* dcc = (HcalDCCHeader*)(output.data());
0244 dcc->clear();
0245 dcc->setHeader(fedid, bcn, nl1a, orbitn);
0246
0247
0248 for (int spigot = 0; spigot < 15; spigot++) {
0249 if (spigots[spigot].getRawLength() > 0) {
0250 dcc->copySpigotData(spigot, spigots[spigot], true, 0);
0251 }
0252 }
0253
0254 FEDTrailer fedTrailer(output.data() + (output.size() - 8));
0255 fedTrailer.set(
0256 output.data() + (output.size() - 8), output.size() / 8, evf::compute_crc(output.data(), output.size()), 0, 0);
0257 }