Back to home page

Project CMSSW displayed by LXR

 
 

    


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   // Get EventSetup Electronics Maps
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   // Get Digi Collection
0074   edm::Handle<RPCDigiCollection> digi_collection;
0075   event.getByToken(digi_token_, digi_collection);
0076 
0077   // Create output
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   // Loop over the FEDs
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     // FED Header + BLOCK Header (1 word + 1 word)
0097     data.resize((size + 2) * 8);
0098     // FED Header
0099     FEDHeader::set(data.data() + size * 8, event_type_, event.id().event(), event.bunchCrossing(), fed_amcs.first);
0100     ++size;
0101     // BLOCK Header
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     // BLOCK AMC Content - 1 word each
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     // AMC Payload - 2 words header, 1 word trailer, 2 words per RPCRecord
0121     data.resize((size + block_content_size) * 8);
0122     for (RPCAMCLink const& amc : fed_amcs.second) {
0123       // TwinMux Header
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       // CRC32 not calculated (for now)
0151     }
0152 
0153     // BLOCK Trailer + FED Trailer (1 word + 1 word)
0154     data.resize((size + 2) * 8);
0155     // BLOCK Trailer
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     // CRC32 not calculated (for now)
0160 
0161     // FED Trailer
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);