File indexing completed on 2023-03-17 11:00:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <iostream>
0021 #include <iomanip>
0022 #include <memory>
0023
0024
0025 #include "FWCore/Framework/interface/Frameworkfwd.h"
0026 #include "FWCore/Framework/interface/stream/EDProducer.h"
0027 #include "FWCore/Framework/interface/Event.h"
0028 #include "FWCore/Framework/interface/MakerMacros.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0030 #include "FWCore/Utilities/interface/InputTag.h"
0031
0032 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0033 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0034 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0035 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0036
0037 #include "EventFilter/L1TRawToDigi/interface/AMC13Spec.h"
0038 #include "EventFilter/L1TRawToDigi/interface/Block.h"
0039
0040 #include "PackingSetupFactory.h"
0041
0042 #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TStage2Layer2Constants.h"
0043
0044 namespace l1t {
0045 class L1TRawToDigi : public edm::stream::EDProducer<> {
0046 public:
0047 explicit L1TRawToDigi(const edm::ParameterSet&);
0048 ~L1TRawToDigi() override;
0049
0050 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0051
0052 private:
0053 void produce(edm::Event&, const edm::EventSetup&) override;
0054
0055 void beginRun(edm::Run const&, edm::EventSetup const&) override{};
0056 void endRun(edm::Run const&, edm::EventSetup const&) override{};
0057 void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override{};
0058 void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override{};
0059
0060
0061 edm::EDGetTokenT<FEDRawDataCollection> fedData_;
0062 std::vector<int> fedIds_;
0063 unsigned int minFeds_;
0064 unsigned int fwId_;
0065 unsigned int dmxFwId_;
0066 bool fwOverride_;
0067
0068 std::unique_ptr<PackingSetup> prov_;
0069
0070
0071 int slinkHeaderSize_;
0072 int slinkTrailerSize_;
0073 int amcHeaderSize_;
0074 int amcTrailerSize_;
0075 int amc13HeaderSize_;
0076 int amc13TrailerSize_;
0077
0078 bool tmtCheck_;
0079
0080 bool ctp7_mode_;
0081 bool mtf7_mode_;
0082 bool debug_;
0083 int warnsa_;
0084 int warnsb_;
0085 };
0086 }
0087
0088 std::ostream& operator<<(std::ostream& o, const l1t::BlockHeader& h) {
0089 o << "L1T Block Header " << h.getID() << " with size " << h.getSize();
0090 return o;
0091 };
0092
0093 namespace l1t {
0094 L1TRawToDigi::L1TRawToDigi(const edm::ParameterSet& config)
0095 : fedIds_(config.getParameter<std::vector<int>>("FedIds")),
0096 minFeds_(config.getParameter<unsigned int>("MinFeds")),
0097 fwId_(config.getParameter<unsigned int>("FWId")),
0098 dmxFwId_(config.getParameter<unsigned int>("DmxFWId")),
0099 fwOverride_(config.getParameter<bool>("FWOverride")),
0100 tmtCheck_(config.getParameter<bool>("TMTCheck")),
0101 ctp7_mode_(config.getUntrackedParameter<bool>("CTP7")),
0102 mtf7_mode_(config.getUntrackedParameter<bool>("MTF7")) {
0103 fedData_ = consumes<FEDRawDataCollection>(config.getParameter<edm::InputTag>("InputLabel"));
0104
0105 if (ctp7_mode_ and mtf7_mode_) {
0106 throw cms::Exception("L1TRawToDigi") << "Can only use one unpacking mode concurrently!";
0107 }
0108
0109 prov_ = PackingSetupFactory::get()->make(config.getParameter<std::string>("Setup"));
0110 prov_->registerProducts(producesCollector());
0111
0112 slinkHeaderSize_ = config.getUntrackedParameter<int>("lenSlinkHeader");
0113 slinkTrailerSize_ = config.getUntrackedParameter<int>("lenSlinkTrailer");
0114 amcHeaderSize_ = config.getUntrackedParameter<int>("lenAMCHeader");
0115 amcTrailerSize_ = config.getUntrackedParameter<int>("lenAMCTrailer");
0116 amc13HeaderSize_ = config.getUntrackedParameter<int>("lenAMC13Header");
0117 amc13TrailerSize_ = config.getUntrackedParameter<int>("lenAMC13Trailer");
0118
0119 debug_ = config.getUntrackedParameter<bool>("debug");
0120 warnsa_ = 0;
0121 warnsb_ = 0;
0122 }
0123
0124 L1TRawToDigi::~L1TRawToDigi() {}
0125
0126
0127
0128
0129
0130
0131 void L1TRawToDigi::produce(edm::Event& event, const edm::EventSetup& setup) {
0132 using namespace edm;
0133
0134 std::unique_ptr<UnpackerCollections> coll = prov_->getCollections(event);
0135
0136 edm::Handle<FEDRawDataCollection> feds;
0137 event.getByToken(fedData_, feds);
0138
0139 if (!feds.isValid()) {
0140 LogError("L1T") << "Cannot unpack: no FEDRawDataCollection found";
0141 return;
0142 }
0143
0144 unsigned valid_count = 0;
0145 for (const auto& fedId : fedIds_) {
0146 const FEDRawData& l1tRcd = feds->FEDData(fedId);
0147
0148 LogDebug("L1T") << "Found FEDRawDataCollection with ID " << fedId << " and size " << l1tRcd.size();
0149
0150 if ((int)l1tRcd.size() < slinkHeaderSize_ + slinkTrailerSize_ + amc13HeaderSize_ + amc13TrailerSize_ +
0151 amcHeaderSize_ + amcTrailerSize_) {
0152 if (l1tRcd.size() > 0) {
0153 LogError("L1T") << "Cannot unpack: invalid L1T raw data (size = " << l1tRcd.size() << ") for ID " << fedId
0154 << ". Returning empty collections!";
0155 } else if (warnsa_ < 5) {
0156 warnsa_++;
0157 LogInfo("L1T") << "During unpacking, encountered empty L1T raw data (size = " << l1tRcd.size()
0158 << ") for FED ID " << fedId << ".";
0159 }
0160 continue;
0161 } else {
0162 valid_count++;
0163 }
0164
0165 const unsigned char* data = l1tRcd.data();
0166 FEDHeader header(data);
0167
0168 if (header.check()) {
0169 LogDebug("L1T") << "Found SLink header:"
0170 << " Trigger type " << header.triggerType() << " L1 event ID " << header.lvl1ID()
0171 << " BX Number " << header.bxID() << " FED source " << header.sourceID() << " FED version "
0172 << header.version();
0173 } else {
0174 LogWarning("L1T") << "Did not find a SLink header!";
0175 }
0176
0177 FEDTrailer trailer(data + (l1tRcd.size() - slinkTrailerSize_));
0178
0179 if (trailer.check()) {
0180 LogDebug("L1T") << "Found SLink trailer:"
0181 << " Length " << trailer.fragmentLength() << " CRC " << trailer.crc() << " Status "
0182 << trailer.evtStatus() << " Throttling bits " << trailer.ttsBits();
0183 } else {
0184 LogWarning("L1T") << "Did not find a SLink trailer!";
0185 }
0186
0187
0188
0189
0190 bool legacy_mc = fwOverride_ && ((fwId_ >> 24) == 0xff);
0191
0192 amc13::Packet packet;
0193 if (!packet.parse((const uint64_t*)data,
0194 (const uint64_t*)(data + slinkHeaderSize_),
0195 (l1tRcd.size() - slinkHeaderSize_ - slinkTrailerSize_) / 8,
0196 header.lvl1ID(),
0197 header.bxID(),
0198 legacy_mc,
0199 mtf7_mode_)) {
0200 LogError("L1T") << "Could not extract AMC13 Packet.";
0201 return;
0202 }
0203
0204 for (auto& amc : packet.payload()) {
0205 if (amc.size() == 0)
0206 continue;
0207
0208 auto payload64 = amc.data();
0209 const uint32_t* start = (const uint32_t*)payload64.get();
0210
0211
0212 const uint32_t* end = start + (amc.size() * 2);
0213
0214 std::unique_ptr<Payload> payload;
0215 if (ctp7_mode_) {
0216 LogDebug("L1T") << "Using CTP7 mode";
0217
0218 payload = std::make_unique<CTP7Payload>(start, end, amc.header());
0219 } else if (mtf7_mode_) {
0220 LogDebug("L1T") << "Using MTF7 mode";
0221 payload = std::make_unique<MTF7Payload>(start, end);
0222 } else {
0223 LogDebug("L1T") << "Using MP7 mode";
0224 payload = std::make_unique<MP7Payload>(start, end, legacy_mc);
0225 }
0226 unsigned fw = payload->getAlgorithmFWVersion();
0227 unsigned board = amc.blockHeader().getBoardID();
0228 unsigned amc_no = amc.blockHeader().getAMCNumber();
0229
0230
0231 if (fwOverride_) {
0232 if (fedId == 1360)
0233 fw = fwId_;
0234 else if (fedId == 1366)
0235 fw = dmxFwId_;
0236 }
0237
0238 auto unpackers = prov_->getUnpackers(fedId, board, amc_no, fw);
0239
0240
0241 std::unique_ptr<Block> block;
0242 while ((block = payload->getBlock()).get()) {
0243
0244 unsigned tmtId = board - l1t::stage2::layer2::mp::offsetBoardId + 1;
0245 unsigned bxId = header.bxID();
0246 unsigned unpackTMT = (!tmtCheck_ || ((tmtId - 1) == ((bxId - 1 + 3) % 9)));
0247 unsigned isCaloL2TMT =
0248 (fedId == l1t::stage2::layer2::fedId && (amc_no != l1t::stage2::layer2::demux::amcSlotNum));
0249
0250 if (!isCaloL2TMT || unpackTMT) {
0251 if (debug_) {
0252 std::cout << ">>> block to unpack <<<" << std::endl
0253 << "hdr: " << std::hex << std::setw(8) << std::setfill('0') << block->header().raw()
0254 << std::dec << " (ID " << block->header().getID() << ", size " << block->header().getSize()
0255 << ", CapID 0x" << std::hex << std::setw(2) << std::setfill('0') << block->header().getCapID()
0256 << ")" << std::dec << std::endl;
0257 for (const auto& word : block->payload()) {
0258 if (debug_)
0259 std::cout << "data: " << std::hex << std::setw(8) << std::setfill('0') << word << std::dec
0260 << std::endl;
0261 }
0262 }
0263
0264 auto unpacker = unpackers.find(block->header().getID());
0265
0266 block->amc(amc.header());
0267
0268 if (unpacker == unpackers.end()) {
0269 LogDebug("L1T") << "Cannot find an unpacker for"
0270 << "\n\tblock: ID " << block->header().getID() << ", size " << block->header().getSize()
0271 << "\n\tAMC: # " << amc_no << ", board ID 0x" << std::hex << board << std::dec
0272 << "\n\tFED ID " << fedId << ", and FW ID " << fw;
0273
0274 } else if (!unpacker->second->unpack(*block, coll.get())) {
0275 LogDebug("L1T") << "Error unpacking data for block ID " << block->header().getID() << ", AMC # " << amc_no
0276 << ", board ID " << board << ", FED ID " << fedId << ", and FW ID " << fw << "!";
0277
0278 }
0279 }
0280 }
0281 }
0282 }
0283 if (valid_count < minFeds_) {
0284 if (warnsb_ < 5) {
0285 warnsb_++;
0286 LogWarning("L1T") << "Unpacked " << valid_count << " non-empty FED IDs but minimum is set to " << minFeds_
0287 << "\n";
0288 }
0289 }
0290 }
0291
0292
0293 void L1TRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0294 edm::ParameterSetDescription desc;
0295
0296 desc.add<std::vector<int>>("FedIds", {})->setComment("required parameter: default value is invalid");
0297 desc.add<std::string>("Setup", "")->setComment("required parameter: default value is invalid");
0298
0299
0300 desc.add<unsigned int>("FWId", 0)->setComment(
0301 "Ignored unless FWOverride is true. Calo Stage1: 32 bits: if the first eight bits are 0xff, will read the "
0302 "74x MC format.\n");
0303 desc.add<unsigned int>("DmxFWId", 0)
0304 ->setComment(
0305 "Ignored unless FWOverride is true. Calo Stage1: 32 bits: if the first eight bits are 0xff, will read "
0306 "the 74x MC format.\n");
0307 desc.add<bool>("FWOverride", false)->setComment("Firmware version should be taken as FWId parameters");
0308 desc.add<bool>("TMTCheck", true)->setComment("Flag for turning on/off Calo Layer 2 TMT node check");
0309 desc.addUntracked<bool>("CTP7", false);
0310 desc.addUntracked<bool>("MTF7", false);
0311 desc.add<edm::InputTag>("InputLabel", edm::InputTag("rawDataCollector"));
0312 desc.addUntracked<int>("lenSlinkHeader", 8);
0313 desc.addUntracked<int>("lenSlinkTrailer", 8);
0314 desc.addUntracked<int>("lenAMCHeader", 8);
0315 desc.addUntracked<int>("lenAMCTrailer", 0);
0316 desc.addUntracked<int>("lenAMC13Header", 8);
0317 desc.addUntracked<int>("lenAMC13Trailer", 8);
0318 desc.addUntracked<bool>("debug", false)->setComment("turn on verbose output");
0319 desc.add<unsigned int>("MinFeds", 0)
0320 ->setComment("optional parameter: warn if less than MinFeds non-empty FED ids unpacked.");
0321 descriptions.add("l1tRawToDigi", desc);
0322 }
0323 }
0324
0325 using namespace l1t;
0326
0327 DEFINE_FWK_MODULE(L1TRawToDigi);