File indexing completed on 2024-04-06 12:10:58
0001 #include "EventFilter/RPCRawToDigi/plugins/RPCTwinMuxDigiToRaw.h"
0002
0003 #include <cstdint>
0004 #include <cstring>
0005 #include <memory>
0006
0007 #include "DataFormats/Common/interface/Handle.h"
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "FWCore/Framework/interface/EventSetup.h"
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0014 #include "FWCore/Utilities/interface/CRC16.h"
0015 #include "FWCore/Utilities/interface/InputTag.h"
0016
0017 #include "CondFormats/RPCObjects/interface/RPCAMCLink.h"
0018 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0019 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0020 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0021 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0022 #include "DataFormats/RPCDigi/interface/RPCDigiCollection.h"
0023 #include "EventFilter/RPCRawToDigi/interface/RPCTwinMuxPacker.h"
0024 #include "EventFilter/RPCRawToDigi/interface/RPCTwinMuxRecord.h"
0025
0026 RPCTwinMuxDigiToRaw::RPCTwinMuxDigiToRaw(edm::ParameterSet const& config)
0027 : es_tm_link_map_br_token_(esConsumes<RPCAMCLinkMap, RPCTwinMuxLinkMapRcd, edm::Transition::BeginRun>()),
0028 es_tm_link_map_token_(esConsumes<RPCInverseAMCLinkMap, RPCInverseTwinMuxLinkMapRcd>()),
0029 es_lb_link_map_token_(esConsumes<RPCInverseLBLinkMap, RPCInverseLBLinkMapRcd>()),
0030 bx_min_(config.getParameter<int>("bxMin")),
0031 bx_max_(config.getParameter<int>("bxMax")),
0032 ignore_eod_(config.getParameter<bool>("ignoreEOD")),
0033 event_type_(config.getParameter<int>("eventType")),
0034 ufov_(config.getParameter<unsigned int>("uFOV")) {
0035 produces<FEDRawDataCollection>();
0036 digi_token_ = consumes<RPCDigiCollection>(config.getParameter<edm::InputTag>("inputTag"));
0037 }
0038
0039 RPCTwinMuxDigiToRaw::~RPCTwinMuxDigiToRaw() {}
0040
0041 void RPCTwinMuxDigiToRaw::fillDescriptions(edm::ConfigurationDescriptions& descs) {
0042 edm::ParameterSetDescription desc;
0043 desc.add<edm::InputTag>("inputTag", edm::InputTag("simMuonRPCDigis", ""));
0044 desc.add<int>("bxMin", -2);
0045 desc.add<int>("bxMax", 2);
0046 desc.add<bool>("ignoreEOD", true);
0047 desc.add<int>("eventType", 1);
0048 desc.add<unsigned int>("uFOV", 1);
0049 descs.add("RPCTwinMuxDigiToRaw", desc);
0050 }
0051
0052 void RPCTwinMuxDigiToRaw::beginRun(edm::Run const& run, edm::EventSetup const& setup) {
0053 if (es_tm_link_map_watcher_.check(setup)) {
0054 edm::ESHandle<RPCAMCLinkMap> es_tm_link_map = setup.getHandle(es_tm_link_map_br_token_);
0055 fed_amcs_.clear();
0056 for (auto const& tm_link : es_tm_link_map->getMap()) {
0057 RPCAMCLink amc(tm_link.first);
0058 amc.setAMCInput();
0059 fed_amcs_[amc.getFED()].push_back(amc);
0060 }
0061 for (auto& fed_amcs : fed_amcs_) {
0062 std::sort(fed_amcs.second.begin(), fed_amcs.second.end());
0063 fed_amcs.second.erase(std::unique(fed_amcs.second.begin(), fed_amcs.second.end()), fed_amcs.second.end());
0064 }
0065 }
0066 }
0067
0068 void RPCTwinMuxDigiToRaw::produce(edm::Event& event, edm::EventSetup const& setup) {
0069
0070 edm::ESHandle<RPCInverseAMCLinkMap> es_tm_link_map_ = setup.getHandle(es_tm_link_map_token_);
0071 edm::ESHandle<RPCInverseLBLinkMap> es_lb_link_map = setup.getHandle(es_lb_link_map_token_);
0072
0073
0074 edm::Handle<RPCDigiCollection> digi_collection;
0075 event.getByToken(digi_token_, digi_collection);
0076
0077
0078 std::unique_ptr<FEDRawDataCollection> data_collection(new FEDRawDataCollection());
0079
0080 std::map<RPCAMCLink, std::vector<std::pair<int, rpctwinmux::RPCRecord> > > amc_bx_tmrecord;
0081 RPCTwinMuxPacker::getRPCTwinMuxRecords(*es_lb_link_map,
0082 *es_tm_link_map_,
0083 bx_min_,
0084 bx_max_,
0085 event.bunchCrossing(),
0086 *digi_collection,
0087 amc_bx_tmrecord,
0088 ignore_eod_);
0089
0090 std::map<int, FEDRawData> fed_data;
0091
0092 for (std::pair<const int, std::vector<RPCAMCLink> > const& fed_amcs : fed_amcs_) {
0093 FEDRawData& data = data_collection->FEDData(fed_amcs.first);
0094 unsigned int size(0);
0095
0096
0097 data.resize((size + 2) * 8);
0098
0099 FEDHeader::set(data.data() + size * 8, event_type_, event.id().event(), event.bunchCrossing(), fed_amcs.first);
0100 ++size;
0101
0102 rpctwinmux::BlockHeader block_header(ufov_, fed_amcs.second.size(), event.eventAuxiliary().orbitNumber());
0103 std::memcpy(data.data() + size * 8, &block_header.getRecord(), 8);
0104 ++size;
0105
0106
0107 data.resize((size + fed_amcs.second.size()) * 8);
0108 unsigned int block_content_size(0);
0109 for (RPCAMCLink const& amc : fed_amcs.second) {
0110 std::map<RPCAMCLink, std::vector<std::pair<int, rpctwinmux::RPCRecord> > >::const_iterator bx_tmrecord(
0111 amc_bx_tmrecord.find(amc));
0112 unsigned int block_amc_size(3 + 2 * (bx_tmrecord == amc_bx_tmrecord.end() ? 0 : bx_tmrecord->second.size()));
0113 block_content_size += block_amc_size;
0114 rpctwinmux::BlockAMCContent amc_content(
0115 true, true, true, true, true, true, true, block_amc_size, 0, amc.getAMCNumber(), 0);
0116 std::memcpy(data.data() + size * 8, &amc_content.getRecord(), 8);
0117 ++size;
0118 }
0119
0120
0121 data.resize((size + block_content_size) * 8);
0122 for (RPCAMCLink const& amc : fed_amcs.second) {
0123
0124 std::map<RPCAMCLink, std::vector<std::pair<int, rpctwinmux::RPCRecord> > >::const_iterator bx_tmrecord(
0125 amc_bx_tmrecord.find(amc));
0126 unsigned int block_amc_size(3 + 2 * (bx_tmrecord == amc_bx_tmrecord.end() ? 0 : bx_tmrecord->second.size()));
0127
0128 rpctwinmux::TwinMuxHeader tm_header(amc.getAMCNumber(),
0129 event.id().event(),
0130 event.bunchCrossing(),
0131 block_amc_size,
0132 event.eventAuxiliary().orbitNumber(),
0133 0);
0134 tm_header.setRPCBXWindow(bx_min_, bx_min_);
0135 std::memcpy(data.data() + size * 8, tm_header.getRecord(), 16);
0136 size += 2;
0137
0138 if (bx_tmrecord != amc_bx_tmrecord.end()) {
0139 for (std::vector<std::pair<int, rpctwinmux::RPCRecord> >::const_iterator tmrecord = bx_tmrecord->second.begin();
0140 tmrecord != bx_tmrecord->second.end();
0141 ++tmrecord) {
0142 std::memcpy(data.data() + size * 8, tmrecord->second.getRecord(), 16);
0143 size += 2;
0144 }
0145 }
0146
0147 rpctwinmux::TwinMuxTrailer tm_trailer(0x0, event.id().event(), 3 + 2 * block_amc_size);
0148 std::memcpy(data.data() + size * 8, &tm_trailer.getRecord(), 8);
0149 ++size;
0150
0151 }
0152
0153
0154 data.resize((size + 2) * 8);
0155
0156 rpctwinmux::BlockTrailer block_trailer(0x0, 0, event.id().event(), event.bunchCrossing());
0157 std::memcpy(data.data() + size * 8, &block_trailer.getRecord(), 8);
0158 ++size;
0159
0160
0161
0162 ++size;
0163 FEDTrailer::set(data.data() + (size - 1) * 8, size, 0x0, 0, 0);
0164 std::uint16_t crc(evf::compute_crc(data.data(), size * 8));
0165 FEDTrailer::set(data.data() + (size - 1) * 8, size, crc, 0, 0);
0166 }
0167
0168 event.put(std::move(data_collection));
0169 }
0170
0171 #include "FWCore/Framework/interface/MakerMacros.h"
0172 DEFINE_FWK_MODULE(RPCTwinMuxDigiToRaw);