File indexing completed on 2024-04-06 12:10:44
0001 #include <memory>
0002
0003 #include "FWCore/Framework/interface/Frameworkfwd.h"
0004 #include "FWCore/Framework/interface/stream/EDProducer.h"
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/MakerMacros.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008 #include "FWCore/Utilities/interface/StreamID.h"
0009
0010 #include "EventFilter/HGCalRawToDigi/interface/HGCalUnpacker.h"
0011
0012 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0013 #include "DataFormats/HGCalDigi/interface/HGCalElectronicsId.h"
0014 #include "DataFormats/HGCalDigi/interface/HGCalDigiCollections.h"
0015
0016 class HGCalRawToDigi : public edm::stream::EDProducer<> {
0017 public:
0018 explicit HGCalRawToDigi(const edm::ParameterSet&);
0019
0020 static void fillDescriptions(edm::ConfigurationDescriptions&);
0021
0022 private:
0023 void produce(edm::Event&, const edm::EventSetup&) override;
0024
0025 const edm::EDGetTokenT<FEDRawDataCollection> fedRawToken_;
0026 const edm::EDPutTokenT<HGCalDigiCollection> digisToken_;
0027 const edm::EDPutTokenT<HGCalElecDigiCollection> elecDigisToken_;
0028
0029 const std::vector<unsigned int> fedIds_;
0030 const unsigned int badECONDMax_;
0031 const unsigned int numERxsInECOND_;
0032 const std::unique_ptr<HGCalUnpacker<HGCalElectronicsId> > unpacker_;
0033 };
0034
0035 HGCalRawToDigi::HGCalRawToDigi(const edm::ParameterSet& iConfig)
0036 : fedRawToken_(consumes<FEDRawDataCollection>(iConfig.getParameter<edm::InputTag>("src"))),
0037 digisToken_(produces<HGCalDigiCollection>()),
0038 elecDigisToken_(produces<HGCalElecDigiCollection>()),
0039 fedIds_(iConfig.getParameter<std::vector<unsigned int> >("fedIds")),
0040 badECONDMax_(iConfig.getParameter<unsigned int>("badECONDMax")),
0041 numERxsInECOND_(iConfig.getParameter<unsigned int>("numERxsInECOND")),
0042 unpacker_(new HGCalUnpacker<HGCalElectronicsId>(
0043 HGCalUnpackerConfig{.sLinkBOE = iConfig.getParameter<unsigned int>("slinkBOE"),
0044 .captureBlockReserved = iConfig.getParameter<unsigned int>("captureBlockReserved"),
0045 .econdHeaderMarker = iConfig.getParameter<unsigned int>("econdHeaderMarker"),
0046 .sLinkCaptureBlockMax = iConfig.getParameter<unsigned int>("maxCaptureBlock"),
0047 .captureBlockECONDMax = iConfig.getParameter<unsigned int>("captureBlockECONDMax"),
0048 .econdERXMax = iConfig.getParameter<unsigned int>("econdERXMax"),
0049 .erxChannelMax = iConfig.getParameter<unsigned int>("erxChannelMax"),
0050 .payloadLengthMax = iConfig.getParameter<unsigned int>("payloadLengthMax"),
0051 .channelMax = iConfig.getParameter<unsigned int>("channelMax"),
0052 .commonModeMax = iConfig.getParameter<unsigned int>("commonModeMax")})) {}
0053
0054 void HGCalRawToDigi::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0055
0056 const auto& raw_data = iEvent.get(fedRawToken_);
0057
0058 HGCalDigiCollection digis;
0059 HGCalElecDigiCollection elec_digis;
0060 for (const auto& fed_id : fedIds_) {
0061 const auto& fed_data = raw_data.FEDData(fed_id);
0062 if (fed_data.size() == 0)
0063 continue;
0064
0065 std::vector<uint32_t> data_32bit;
0066 auto* ptr = fed_data.data();
0067 size_t fed_size = fed_data.size();
0068 for (size_t i = 0; i < fed_size; i += 4)
0069 data_32bit.emplace_back(((*(ptr + i) & 0xff) << 0) + (((i + 1) < fed_size) ? ((*(ptr + i + 1) & 0xff) << 8) : 0) +
0070 (((i + 2) < fed_size) ? ((*(ptr + i + 2) & 0xff) << 16) : 0) +
0071 (((i + 3) < fed_size) ? ((*(ptr + i + 3) & 0xff) << 24) : 0));
0072
0073 unpacker_->parseSLink(
0074 data_32bit,
0075 [this](uint16_t , uint8_t , uint8_t ) { return (1 << numERxsInECOND_) - 1; },
0076 [](HGCalElectronicsId elecID) -> HGCalElectronicsId { return elecID; });
0077 const auto elecid_to_detid = [](const HGCalElectronicsId& id) -> HGCalDetId {
0078 return HGCalDetId(id.raw());
0079 };
0080
0081 auto channeldata = unpacker_->channelData();
0082 auto cms = unpacker_->commonModeIndex();
0083 for (unsigned int i = 0; i < channeldata.size(); i++) {
0084 auto data = channeldata.at(i);
0085 auto cm = cms.at(i);
0086 const auto& id = data.id();
0087 auto idraw = id.raw();
0088 auto raw = data.raw();
0089 LogDebug("HGCalRawToDigi:produce") << "id=" << idraw << ", raw=" << raw << ", common mode index=" << cm << ".";
0090 digis.push_back(HGCROCChannelDataFrameSpec(elecid_to_detid(id), data.raw()));
0091 elec_digis.push_back(data);
0092 }
0093 if (const auto& bad_econds = unpacker_->badECOND(); !bad_econds.empty()) {
0094 if (bad_econds.size() > badECONDMax_)
0095 throw cms::Exception("HGCalRawToDigi:produce")
0096 << "Too many bad ECON-Ds: " << bad_econds.size() << " > " << badECONDMax_ << ".";
0097 edm::LogWarning("HGCalRawToDigi:produce").log([&bad_econds](auto& log) {
0098 log << "Bad ECON-D: " << std::dec;
0099 std::string prefix;
0100 for (const auto& badECOND : bad_econds)
0101 log << prefix << badECOND, prefix = ", ";
0102 log << ".";
0103 });
0104 }
0105 }
0106 iEvent.emplace(digisToken_, std::move(digis));
0107 iEvent.emplace(elecDigisToken_, std::move(elec_digis));
0108 }
0109
0110 void HGCalRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0111 edm::ParameterSetDescription desc;
0112 desc.add<edm::InputTag>("src", edm::InputTag("rawDataCollector"));
0113 desc.add<unsigned int>("maxCaptureBlock", 1)->setComment("maximum number of capture blocks in one S-Link");
0114 desc.add<unsigned int>("captureBlockReserved", 0)->setComment("capture block reserved pattern");
0115 desc.add<unsigned int>("econdHeaderMarker", 0x154)->setComment("ECON-D header Marker pattern");
0116 desc.add<unsigned int>("slinkBOE", 0x2a)->setComment("SLink BOE pattern");
0117 desc.add<unsigned int>("captureBlockECONDMax", 12)->setComment("maximum number of ECON-D's in one capture block");
0118 desc.add<unsigned int>("econdERXMax", 12)->setComment("maximum number of eRx's in one ECON-D");
0119 desc.add<unsigned int>("erxChannelMax", 37)->setComment("maximum number of channels in one eRx");
0120 desc.add<unsigned int>("payloadLengthMax", 469)->setComment("maximum length of payload length");
0121 desc.add<unsigned int>("channelMax", 7000000)->setComment("maximum number of channels unpacked");
0122 desc.add<unsigned int>("commonModeMax", 4000000)->setComment("maximum number of common modes unpacked");
0123 desc.add<unsigned int>("badECONDMax", 200)->setComment("maximum number of bad ECON-D's");
0124 desc.add<std::vector<unsigned int> >("fedIds", {});
0125 desc.add<unsigned int>("numERxsInECOND", 12)->setComment("number of eRxs in each ECON-D payload");
0126 descriptions.add("hgcalDigis", desc);
0127 }
0128
0129
0130 DEFINE_FWK_MODULE(HGCalRawToDigi);