File indexing completed on 2023-03-17 10:59:18
0001 #include "EventFilter/CastorRawToDigi/interface/CastorCtdcPacker.h"
0002 #include "EventFilter/CastorRawToDigi/interface/CastorCORData.h"
0003 #include "EventFilter/CastorRawToDigi/interface/CastorMergerData.h"
0004 #include "EventFilter/CastorRawToDigi/interface/CastorCTDCHeader.h"
0005 #include "DataFormats/HcalDetId/interface/HcalGenericDetId.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0008 #include "FWCore/Utilities/interface/CRC16.h"
0009 #include "EventFilter/CastorRawToDigi/interface/CastorCollections.h"
0010 #include <iostream>
0011
0012 using namespace std;
0013
0014 namespace {
0015 template <class Coll, class DetIdClass>
0016 int process(const Coll* pt, const DetId& did, unsigned short* buffer, int& presamples) {
0017 if (pt == nullptr)
0018 return 0;
0019 int size = 0;
0020 typename Coll::const_iterator i = pt->find(DetIdClass(did));
0021 if (i != pt->end()) {
0022 presamples = i->presamples();
0023 size = i->size();
0024 for (int j = 0; j < size; j++)
0025 buffer[j] = (*i)[j].raw();
0026 }
0027 return size;
0028 }
0029 }
0030
0031 int CastorCtdcPacker::findSamples(const DetId& did,
0032 const CastorCollections& inputs,
0033 unsigned short* buffer,
0034 int& presamples) {
0035 if (did.det() != DetId::Calo)
0036 return 0;
0037 int size = 0;
0038 HcalCastorDetId genId(did);
0039
0040 size = process<CastorDigiCollection, HcalCastorDetId>(inputs.castorCont, did, buffer, presamples);
0041
0042 return size;
0043 }
0044
0045 void CastorCtdcPacker::pack(int fedid,
0046 int dccnumber,
0047 int nl1a,
0048 int orbitn,
0049 int bcn,
0050 const CastorCollections& inputs,
0051 const CastorElectronicsMap& emap,
0052 FEDRawData& output) {
0053 std::vector<unsigned short> precdata(CastorCORData::CHANNELS_PER_SPIGOT * CastorCORData::MAXIMUM_SAMPLES_PER_CHANNEL);
0054 std::vector<unsigned short> trigdata(CastorCORData::CHANNELS_PER_SPIGOT * CastorCORData::MAXIMUM_SAMPLES_PER_CHANNEL);
0055 std::vector<unsigned char> preclen(CastorCORData::CHANNELS_PER_SPIGOT);
0056 std::vector<unsigned char> triglen(CastorCORData::CHANNELS_PER_SPIGOT);
0057 constexpr int CORFormatVersion = 1;
0058
0059
0060 CastorCORData spigots[2];
0061
0062 for (int spigot = 0; spigot < CastorCTDCHeader::SPIGOT_COUNT; spigot++) {
0063 spigots[spigot].allocate(CORFormatVersion);
0064 CastorElectronicsId exampleEId;
0065 int npresent = 0;
0066 int presamples = -1, samples = -1;
0067 for (int fiber = 1; fiber <= 12; fiber++)
0068 for (int fiberchan = 0; fiberchan < 3; fiberchan++) {
0069 int linear = (fiber - 1) * 3 + fiberchan;
0070
0071
0072 preclen[linear] = 0;
0073 CastorElectronicsId partialEid(fiberchan, fiber, spigot, dccnumber);
0074
0075 CastorElectronicsId fullEid;
0076 HcalGenericDetId genId;
0077 if (!emap.lookup(partialEid, fullEid, genId))
0078 continue;
0079
0080
0081 unsigned short* database = &(precdata[linear * CastorCORData::MAXIMUM_SAMPLES_PER_CHANNEL]);
0082 int mypresamples;
0083 int mysamples = findSamples(genId, inputs, database, mypresamples);
0084 if (mysamples > 0) {
0085 if (samples < 0)
0086 samples = mysamples;
0087 else if (samples != mysamples) {
0088 edm::LogError("CASTOR") << "Mismatch of samples in a single COR (unsupported) " << mysamples
0089 << " != " << samples;
0090 continue;
0091 }
0092 if (presamples < 0) {
0093 presamples = mypresamples;
0094 exampleEId = fullEid;
0095 } else if (mypresamples != presamples) {
0096 edm::LogError("CASTOR") << "Mismatch of presamples in a single COR (unsupported) " << mypresamples
0097 << " != " << presamples;
0098 continue;
0099 }
0100 preclen[linear] = (unsigned char)(samples);
0101 npresent++;
0102 }
0103 }
0104
0105 if (npresent > 0) {
0106 spigots[spigot].pack(&(preclen[0]), &(precdata[0]), &(triglen[0]), &(trigdata[0]), true);
0107 constexpr int pipeline = 0x22;
0108 constexpr int firmwareRev = 0;
0109 int submodule = exampleEId.htrTopBottom() & 0x1;
0110 submodule |= (exampleEId.htrSlot() & 0x1F) << 1;
0111 submodule |= (exampleEId.readoutVMECrateId() & 0x1f) << 6;
0112 spigots[spigot].packHeaderTrailer(nl1a, bcn, submodule, orbitn, pipeline, samples, presamples, firmwareRev);
0113 }
0114 }
0115
0116 int theSize = 0;
0117 for (int spigot = 0; spigot < 2; spigot++) {
0118 theSize += spigots[spigot].getRawLength() * sizeof(unsigned short);
0119 }
0120
0121 CastorMergerData mergerdata;
0122
0123 theSize += mergerdata.getRawLength() * sizeof(unsigned short);
0124
0125 theSize += sizeof(CastorCTDCHeader) + 8;
0126 theSize += (8 - (theSize % 8)) % 8;
0127 output.resize(theSize);
0128
0129
0130 CastorCTDCHeader* dcc = (CastorCTDCHeader*)(output.data());
0131 dcc->clear();
0132 dcc->setHeader(fedid, bcn, nl1a, orbitn);
0133
0134
0135 for (int spigot = 0; spigot < 2; spigot++) {
0136 if (spigots[spigot].getRawLength() > 0)
0137 dcc->copySpigotData(spigot, spigots[spigot], true, 0);
0138 }
0139 if (mergerdata.getRawLength() > 0)
0140 dcc->copyMergerData(mergerdata, true);
0141
0142 FEDTrailer fedTrailer(output.data() + (output.size() - 8));
0143 fedTrailer.set(
0144 output.data() + (output.size() - 8), output.size() / 8, evf::compute_crc(output.data(), output.size()), 0, 0);
0145 }