File indexing completed on 2024-04-06 12:10:58
0001 #include "EventFilter/RPCRawToDigi/plugins/RPCCPPFUnpacker.h"
0002
0003 #include <algorithm>
0004
0005 #include "DataFormats/Common/interface/Handle.h"
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/Framework/interface/EventSetup.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0011
0012 #include "DataFormats/RPCDigi/interface/RPCAMCLinkCounters.h"
0013 #include "DataFormats/RPCDigi/interface/RPCDigiCollection.h"
0014 #include "EventFilter/RPCRawToDigi/interface/RPCAMCLinkEvents.h"
0015 #include "EventFilter/RPCRawToDigi/interface/RPCMP7Record.h"
0016
0017 RPCCPPFUnpacker::RPCCPPFUnpacker(edm::ParameterSet const& config,
0018 edm::ConsumesCollector consumesCollector,
0019 edm::ProducesCollector producesCollector)
0020 : RPCAMCUnpacker(config, consumesCollector, producesCollector),
0021 fill_counters_(config.getParameter<bool>("fillAMCCounters")),
0022 bx_min_(config.getParameter<int>("bxMin")),
0023 bx_max_(config.getParameter<int>("bxMax")),
0024 cppfDaq_Delay_(config.getParameter<int>("cppfDaqDelay")),
0025 es_cppf_link_map_br_token_(
0026 consumesCollector.esConsumes<RPCAMCLinkMap, RPCCPPFLinkMapRcd, edm::Transition::BeginRun>()),
0027 es_cppf_link_map_token_(consumesCollector.esConsumes<RPCAMCLinkMap, RPCCPPFLinkMapRcd>()),
0028 es_lb_link_map_token_(consumesCollector.esConsumes<RPCLBLinkMap, RPCLBLinkMapRcd>()) {
0029 producesCollector.produces<RPCDigiCollection>();
0030 producesCollector.produces<l1t::CPPFDigiCollection>();
0031 if (fill_counters_) {
0032 producesCollector.produces<RPCAMCLinkCounters>("RPCAMCUnpacker");
0033 }
0034 }
0035
0036 void RPCCPPFUnpacker::beginRun(edm::Run const& run, edm::EventSetup const& setup) {
0037 if (es_cppf_link_map_watcher_.check(setup)) {
0038 auto link_map = setup.getHandle(es_cppf_link_map_br_token_);
0039 std::set<int> feds;
0040 for (auto const& cppf_link : link_map->getMap()) {
0041 feds.insert(cppf_link.first.getFED());
0042 }
0043 feds_.assign(feds.begin(), feds.end());
0044 }
0045 }
0046
0047 void RPCCPPFUnpacker::produce(edm::Event& event,
0048 edm::EventSetup const& setup,
0049 std::map<RPCAMCLink, rpcamc13::AMCPayload> const& amc_payload) {
0050
0051 es_cppf_link_map_ = setup.getHandle(es_cppf_link_map_token_);
0052 es_lb_link_map_ = setup.getHandle(es_lb_link_map_token_);
0053
0054 std::set<std::pair<RPCDetId, RPCDigi> > rpc_digis;
0055 std::unique_ptr<l1t::CPPFDigiCollection> rpc_cppf_digis(new l1t::CPPFDigiCollection());
0056 std::unique_ptr<RPCAMCLinkCounters> counters(new RPCAMCLinkCounters());
0057
0058 for (std::pair<RPCAMCLink const, rpcamc13::AMCPayload> const& payload : amc_payload) {
0059 processCPPF(payload.first, payload.second, *counters, rpc_digis, *rpc_cppf_digis);
0060 }
0061
0062 putRPCDigis(event, rpc_digis);
0063 std::sort(rpc_cppf_digis->begin(), rpc_cppf_digis->end());
0064 event.put(std::move(rpc_cppf_digis));
0065 if (fill_counters_) {
0066 event.put(std::move(counters), "RPCAMCUnpacker");
0067 }
0068 }
0069
0070 bool RPCCPPFUnpacker::processCPPF(RPCAMCLink const& link,
0071 rpcamc13::AMCPayload const& payload,
0072 RPCAMCLinkCounters& counters,
0073 std::set<std::pair<RPCDetId, RPCDigi> >& rpc_digis,
0074 l1t::CPPFDigiCollection& rpc_cppf_digis) const {
0075 LogDebug("RPCCPPFRawToDigi") << "RPCCPPF " << link << ", size " << payload.getData().size();
0076
0077 if (!payload.isValid()) {
0078 return false;
0079 }
0080
0081 std::vector<std::uint64_t>::const_iterator word(payload.getData().begin());
0082 rpcmp7::Header header(&(*word));
0083 ++word;
0084 ++word;
0085 rpcmp7::SubHeader subheader(*word);
0086 ++word;
0087 std::vector<std::uint64_t>::const_iterator word_end(payload.getData().end());
0088 --word_end;
0089 unsigned int bx_counter(header.getBXCounter());
0090 unsigned int bx_counter_mod(bx_counter % 27);
0091
0092 int bx_min(bx_min_), bx_max(bx_max_), cppfDaq_Delay(cppfDaq_Delay_);
0093
0094
0095 unsigned int pos(0), length(0);
0096 unsigned int caption_id(0);
0097 bool zs_per_bx(false), have_bx_header(false);
0098 unsigned int bx_words(0);
0099 unsigned int block_id(0);
0100 std::uint32_t records[2];
0101 for (; word != word_end; ++word) {
0102 records[0] = *word & 0xffffffff;
0103 records[1] = (*word >> 32) & 0xffffffff;
0104 for (std::uint32_t* record = &(records[0]); record < &(records[2]); ++record) {
0105 if (pos >= length) {
0106 rpcmp7::BlockHeader block_header(*record);
0107 LogDebug("RPCCPPFUnpacker") << "block header " << std::hex << block_header.getRecord() << std::dec
0108 << " caption id " << block_header.getCaptionId() << " zs per bx "
0109 << block_header.hasZeroSuppressionPerBX() << " zs "
0110 << block_header.isZeroSuppressed() << " length " << block_header.getLength() << " "
0111 << word_end - word;
0112 pos = 0;
0113 length = block_header.getLength();
0114 caption_id = block_header.getCaptionId();
0115 zs_per_bx = block_header.hasZeroSuppressionPerBX();
0116 have_bx_header = false;
0117 bx_words = 6;
0118 block_id = block_header.getId();
0119 } else if (zs_per_bx && !have_bx_header) {
0120
0121 have_bx_header = true;
0122 } else {
0123 if (caption_id == 0x01) {
0124 processRXRecord(
0125 link, bx_counter_mod, rpccppf::RXRecord(*record), counters, rpc_digis, bx_min, bx_max, cppfDaq_Delay);
0126 } else if (caption_id == 0x02) {
0127 processTXRecord(link, block_id, 6 - bx_words, rpccppf::TXRecord(*record), rpc_cppf_digis);
0128 }
0129 ++pos;
0130 --bx_words;
0131 }
0132 }
0133 }
0134
0135 return true;
0136 }
0137
0138 void RPCCPPFUnpacker::processRXRecord(RPCAMCLink link,
0139 unsigned int bx_counter_mod,
0140 rpccppf::RXRecord const& record,
0141 RPCAMCLinkCounters& counters,
0142 std::set<std::pair<RPCDetId, RPCDigi> >& rpc_digis,
0143 int bx_min,
0144 int bx_max,
0145 int cppfDaq_Delay) const {
0146 LogDebug("RPCCPPFRawToDigi") << "RXRecord " << std::hex << record.getRecord() << std::dec << std::endl;
0147 unsigned int fed(link.getFED());
0148 unsigned int amc_number(link.getAMCNumber());
0149 if (record.getLink() > 80)
0150 return;
0151 link.setAMCInput(record.getLink());
0152
0153 int bx_offset = (int)(record.getBXCounterMod() + 31 - bx_counter_mod) % 27 - 4;
0154
0155 if (record.isError()) {
0156 if (fill_counters_ && bx_offset == 0) {
0157 counters.add(RPCAMCLinkEvents::input_link_error_, link);
0158 }
0159 LogDebug("RPCCPPFRawToDigi") << "Link in error for " << link;
0160 return;
0161 } else if (!record.isAcknowledge()) {
0162 if (fill_counters_ && bx_offset == 0) {
0163 counters.add(RPCAMCLinkEvents::input_link_ack_fail_, link);
0164 }
0165 LogDebug("RPCCPPFRawToDigi") << "Link without acknowledge for " << link;
0166 return;
0167 }
0168
0169 std::uint8_t data(record.getPartitionData());
0170 if (!data) {
0171 return;
0172 }
0173
0174 int bx(bx_offset - (int)(record.getDelay()));
0175 LogDebug("RPCCPPFRawToDigi") << "RPC BX " << bx << " for offset " << bx_offset;
0176
0177 if (fill_counters_ && bx == 0 && record.isEOD()) {
0178 counters.add(RPCAMCLinkEvents::input_eod_, link);
0179 }
0180
0181 RPCAMCLinkMap::map_type::const_iterator link_it = es_cppf_link_map_->getMap().find(link);
0182 if (link_it == es_cppf_link_map_->getMap().end()) {
0183 if (fill_counters_ && bx_offset == 0) {
0184 counters.add(RPCAMCLinkEvents::amc_link_invalid_, RPCAMCLink(fed, amc_number));
0185 }
0186 LogDebug("RPCCPPFRawToDigi") << "Skipping unknown RPCCPPFLink " << link;
0187 return;
0188 }
0189
0190 RPCLBLink lb_link = link_it->second;
0191
0192 if (record.getLinkBoard() > (unsigned int)RPCLBLink::max_linkboard_) {
0193 if (fill_counters_ && bx_offset == 0) {
0194 counters.add(RPCAMCLinkEvents::input_lb_invalid_, link);
0195 }
0196 LogDebug("RPCCPPFRawToDigi") << "Skipping invalid LinkBoard " << record.getLinkBoard() << " for record " << link
0197 << " (" << std::hex << record.getRecord() << " in " << record.getRecord() << std::dec
0198 << " from " << link;
0199 return;
0200 }
0201
0202 if (record.getConnector() > (unsigned int)RPCLBLink::max_connector_) {
0203 if (fill_counters_ && bx_offset == 0) {
0204 counters.add(RPCAMCLinkEvents::input_connector_invalid_, link);
0205 }
0206 LogDebug("RPCCPPFRawToDigi") << "Skipping invalid Connector " << record.getConnector() << " for record " << link
0207 << " (" << std::hex << record.getRecord() << " in " << record.getRecord() << std::dec
0208 << ") from " << link;
0209 return;
0210 }
0211
0212 lb_link.setLinkBoard(record.getLinkBoard());
0213 lb_link.setConnector(record.getConnector());
0214
0215 RPCLBLinkMap::map_type::const_iterator lb_link_it = es_lb_link_map_->getMap().find(lb_link);
0216 if (lb_link_it == es_lb_link_map_->getMap().end()) {
0217 if (fill_counters_ && bx_offset == 0) {
0218 counters.add(RPCAMCLinkEvents::input_connector_not_used_, link);
0219 }
0220 LogDebug("RPCCPPFRawToDigi") << "Could not find " << lb_link << " for record " << link << " (" << std::hex
0221 << record.getRecord() << " in " << record.getRecord() << std::dec << ") from " << link;
0222 return;
0223 }
0224
0225 auto bx_corrected = bx - cppfDaq_Delay;
0226 if (bx_corrected < bx_min || bx_corrected > bx_max) {
0227 return;
0228 }
0229
0230 if (fill_counters_ && bx == 0) {
0231 counters.add(RPCAMCLinkEvents::input_event_, link);
0232 }
0233
0234 RPCFebConnector const& feb_connector(lb_link_it->second);
0235 RPCDetId det_id(feb_connector.getRPCDetId());
0236 unsigned int channel_offset(record.getPartition() ? 9 : 1);
0237
0238 for (unsigned int channel = 0; channel < 8; ++channel) {
0239 if (data & (0x1 << channel)) {
0240 unsigned int strip(feb_connector.getStrip(channel + channel_offset));
0241 if (strip) {
0242 rpc_digis.insert(std::pair<RPCDetId, RPCDigi>(det_id, RPCDigi(strip, bx - cppfDaq_Delay_)));
0243 LogDebug("RPCCPPFRawToDigi") << "RPCDigi " << det_id.rawId() << ", " << strip << ", " << bx << ", "
0244 << bx - cppfDaq_Delay_;
0245 }
0246 }
0247 }
0248 }
0249
0250 void RPCCPPFUnpacker::processTXRecord(RPCAMCLink link,
0251 unsigned int block,
0252 unsigned int word,
0253 rpccppf::TXRecord const& record,
0254 l1t::CPPFDigiCollection& rpc_cppf_digis) const {
0255 if (!record.isValid(0) && !record.isValid(1)) {
0256 return;
0257 }
0258
0259
0260 if (word > 5) {
0261 return;
0262 }
0263 static int const ring[6] = {2, 2, 2, 3, 2, 3};
0264 static int const station[6] = {1, 2, 3, 3, 4, 4};
0265 int region(link.getAMCNumber() < 7 ? 1 : -1);
0266 unsigned int endcap_sector((35 + (link.getAMCNumber() - (region > 0 ? 3 : 7)) * 9 + (block >> 1)) % 36 + 1);
0267 unsigned int emtf_link(((34 + (link.getAMCNumber() - (region > 0 ? 3 : 7)) * 9 + (block >> 1)) % 36) % 6 + 1);
0268 unsigned int emtf_sector(((34 + (link.getAMCNumber() - (region > 0 ? 3 : 7)) * 9 + (block >> 1)) % 36) / 6 + 1);
0269 RPCDetId rpc_id(region,
0270 ring[word]
0271 ,
0272 station[word]
0273 ,
0274 ((endcap_sector - 1) / 6) + 1
0275 ,
0276 1
0277 ,
0278 (endcap_sector - 1) % 6 + 1
0279 ,
0280 0);
0281
0282 if (record.isValid(0)) {
0283 rpc_cppf_digis.push_back(
0284 l1t::CPPFDigi(rpc_id, 0, record.getPhi(0), record.getTheta(0), 0, 0, 0, emtf_sector, emtf_link, 0, 0, 0, 0));
0285 }
0286 if (record.isValid(1)) {
0287 rpc_cppf_digis.push_back(
0288 l1t::CPPFDigi(rpc_id, 0, record.getPhi(1), record.getTheta(1), 1, 0, 0, emtf_sector, emtf_link, 0, 0, 0, 0));
0289 }
0290 }
0291
0292 void RPCCPPFUnpacker::putRPCDigis(edm::Event& event, std::set<std::pair<RPCDetId, RPCDigi> > const& rpc_digis) const {
0293 std::unique_ptr<RPCDigiCollection> rpc_digi_collection(new RPCDigiCollection());
0294 RPCDetId rpc_det_id;
0295 std::vector<RPCDigi> local_rpc_digis;
0296 for (std::pair<RPCDetId, RPCDigi> const& rpc_digi : rpc_digis) {
0297 LogDebug("RPCCPPFRawToDigi") << "RPCDigi " << rpc_digi.first.rawId() << ", " << rpc_digi.second.strip() << ", "
0298 << rpc_digi.second.bx();
0299 if (rpc_digi.first != rpc_det_id) {
0300 if (!local_rpc_digis.empty()) {
0301 rpc_digi_collection->put(RPCDigiCollection::Range(local_rpc_digis.begin(), local_rpc_digis.end()), rpc_det_id);
0302 local_rpc_digis.clear();
0303 }
0304 rpc_det_id = rpc_digi.first;
0305 }
0306 local_rpc_digis.push_back(rpc_digi.second);
0307 }
0308 if (!local_rpc_digis.empty()) {
0309 rpc_digi_collection->put(RPCDigiCollection::Range(local_rpc_digis.begin(), local_rpc_digis.end()), rpc_det_id);
0310 }
0311
0312 event.put(std::move(rpc_digi_collection));
0313 }
0314
0315 #include "FWCore/Framework/interface/MakerMacros.h"
0316 #include "EventFilter/RPCRawToDigi/plugins/RPCAMCUnpackerFactory.h"
0317 DEFINE_EDM_PLUGIN(RPCAMCUnpackerFactory, RPCCPPFUnpacker, "RPCCPPFUnpacker");