File indexing completed on 2024-04-06 12:10:58
0001 #include "EventFilter/RPCRawToDigi/plugins/RPCTwinMuxRawToDigi.h"
0002
0003 #include <memory>
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/ConfigurationDescriptions.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0012 #include "FWCore/Utilities/interface/CRC16.h"
0013 #include "FWCore/Utilities/interface/InputTag.h"
0014
0015 #include "CondFormats/RPCObjects/interface/RPCAMCLink.h"
0016 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0017 #include "DataFormats/FEDRawData/interface/FEDRawData.h"
0018 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0019 #include "DataFormats/RPCDigi/interface/RPCDigiCollection.h"
0020 #include "EventFilter/RPCRawToDigi/interface/RPCTwinMuxRecord.h"
0021 #include "EventFilter/RPCRawToDigi/interface/RPCAMCLinkEvents.h"
0022
0023 RPCTwinMuxRawToDigi::RPCTwinMuxRawToDigi(edm::ParameterSet const &config)
0024 : calculate_crc_(config.getParameter<bool>("calculateCRC")),
0025 fill_counters_(config.getParameter<bool>("fillCounters")),
0026 bx_min_(config.getParameter<int>("bxMin")),
0027 bx_max_(config.getParameter<int>("bxMax")),
0028 es_tm_link_map_br_token_(esConsumes<RPCAMCLinkMap, RPCTwinMuxLinkMapRcd, edm::Transition::BeginRun>()),
0029 es_tm_link_map_token_(esConsumes<RPCAMCLinkMap, RPCTwinMuxLinkMapRcd>()),
0030 es_lb_link_map_token_(esConsumes<RPCLBLinkMap, RPCLBLinkMapRcd>()) {
0031 produces<RPCDigiCollection>();
0032 if (fill_counters_) {
0033 produces<RPCAMCLinkCounters>();
0034 }
0035 raw_token_ = consumes<FEDRawDataCollection>(config.getParameter<edm::InputTag>("inputTag"));
0036 }
0037
0038 RPCTwinMuxRawToDigi::~RPCTwinMuxRawToDigi() {}
0039
0040 void RPCTwinMuxRawToDigi::compute_crc_64bit(
0041 std::uint16_t &crc, std::uint64_t const &word) {
0042 unsigned char const *uchars(reinterpret_cast<unsigned char const *>(&word));
0043 for (unsigned char const *uchar = uchars + 7; uchar >= uchars; --uchar) {
0044 crc = evf::compute_crc_8bit(crc, *uchar);
0045 }
0046 }
0047
0048 void RPCTwinMuxRawToDigi::fillDescriptions(edm::ConfigurationDescriptions &descs) {
0049 edm::ParameterSetDescription desc;
0050 desc.add<edm::InputTag>("inputTag", edm::InputTag("rawDataCollector", ""));
0051 desc.add<bool>("calculateCRC", true);
0052 desc.add<bool>("fillCounters", true);
0053 desc.add<int>("bxMin", -2);
0054 desc.add<int>("bxMax", 2);
0055 descs.add("rpcTwinMuxRawToDigi", desc);
0056 }
0057
0058 void RPCTwinMuxRawToDigi::beginRun(edm::Run const &run, edm::EventSetup const &setup) {
0059 if (es_tm_link_map_watcher_.check(setup)) {
0060 auto link_map = setup.getHandle(es_tm_link_map_br_token_);
0061 std::set<int> feds;
0062 for (auto const &tm_link : link_map->getMap()) {
0063 feds.insert(tm_link.first.getFED());
0064 }
0065 feds_.assign(feds.begin(), feds.end());
0066 }
0067 }
0068
0069 void RPCTwinMuxRawToDigi::produce(edm::Event &event, edm::EventSetup const &setup) {
0070
0071 es_tm_link_map_ = setup.getHandle(es_tm_link_map_token_);
0072 es_lb_link_map_ = setup.getHandle(es_lb_link_map_token_);
0073
0074
0075 edm::Handle<FEDRawDataCollection> raw_data_collection;
0076 event.getByToken(raw_token_, raw_data_collection);
0077
0078 std::set<std::pair<RPCDetId, RPCDigi> > rpc_digis;
0079 std::unique_ptr<RPCAMCLinkCounters> counters(new RPCAMCLinkCounters());
0080
0081
0082 for (int fed : feds_) {
0083 if (fill_counters_) {
0084 counters->add(RPCAMCLinkEvents::fed_event_, RPCAMCLink(fed, RPCAMCLink::wildcard_));
0085 }
0086
0087 std::uint16_t crc(0xffff);
0088
0089 FEDRawData const &raw_data = raw_data_collection->FEDData(fed);
0090 unsigned int nwords(raw_data.size() / sizeof(std::uint64_t));
0091 if (!nwords) {
0092 continue;
0093 }
0094
0095 std::uint64_t const *word(reinterpret_cast<std::uint64_t const *>(raw_data.data()));
0096 std::uint64_t const *word_end = word + nwords;
0097
0098 LogDebug("RPCTwinMuxRawToDigi") << "Handling FED " << fed << " with length " << nwords;
0099
0100
0101 if (!processCDFHeaders(fed, word, word_end, crc, *counters)) {
0102 continue;
0103 }
0104
0105
0106 if (!processCDFTrailers(fed, nwords, word, word_end, crc, *counters)) {
0107 continue;
0108 }
0109
0110
0111 while (word < word_end) {
0112 processBlock(fed, word, word_end, crc, *counters, rpc_digis);
0113 }
0114
0115
0116 if (calculate_crc_) {
0117 word = word_end;
0118 word_end = reinterpret_cast<std::uint64_t const *>(raw_data.data()) + nwords - 1;
0119 for (; word < word_end; ++word) {
0120 compute_crc_64bit(crc, *word);
0121 }
0122 compute_crc_64bit(crc, (*word & 0xffffffff0000ffff));
0123 FEDTrailer trailer(reinterpret_cast<unsigned char const *>(word_end));
0124 if ((unsigned int)(trailer.crc()) != crc) {
0125 if (fill_counters_) {
0126 counters->add(RPCAMCLinkEvents::fed_trailer_crc_mismatch_, RPCAMCLink(fed, RPCAMCLink::wildcard_));
0127 }
0128 edm::LogWarning("RPCTwinMuxRawToDigi") << "FED Trailer CRC doesn't match for FED id " << fed;
0129 }
0130 }
0131 }
0132
0133 putRPCDigis(event, rpc_digis);
0134 if (fill_counters_) {
0135 putCounters(event, std::move(counters));
0136 }
0137 }
0138
0139 bool RPCTwinMuxRawToDigi::processCDFHeaders(int fed,
0140 std::uint64_t const *&word,
0141 std::uint64_t const *&word_end,
0142 std::uint16_t &crc,
0143 RPCAMCLinkCounters &counters) const {
0144 bool more_headers(true);
0145 for (; word < word_end && more_headers; ++word) {
0146 if (calculate_crc_) {
0147 compute_crc_64bit(crc, *word);
0148 }
0149
0150 LogDebug("RPCTwinMuxRawToDigi") << "CDF Header " << std::hex << *word << std::dec;
0151 FEDHeader header(reinterpret_cast<unsigned char const *>(word));
0152 if (!header.check()) {
0153 if (fill_counters_) {
0154 counters.add(RPCAMCLinkEvents::fed_header_check_fail_, RPCAMCLink(fed, RPCAMCLink::wildcard_));
0155 }
0156 edm::LogWarning("RPCTwinMuxRawToDigi") << "FED Header check failed for FED id " << fed;
0157 ++word;
0158 break;
0159 }
0160 if (header.sourceID() != fed) {
0161 if (fill_counters_) {
0162 counters.add(RPCAMCLinkEvents::fed_header_id_mismatch_, RPCAMCLink(fed, RPCAMCLink::wildcard_));
0163 }
0164 edm::LogWarning("RPCTwinMuxRawToDigi")
0165 << "FED Header Source ID " << header.sourceID() << " does not match requested FED id " << fed;
0166 break;
0167 }
0168
0169
0170
0171 more_headers = false;
0172 }
0173
0174 return !more_headers;
0175 }
0176
0177 bool RPCTwinMuxRawToDigi::processCDFTrailers(int fed,
0178 unsigned int nwords,
0179 std::uint64_t const *&word,
0180 std::uint64_t const *&word_end,
0181 std::uint16_t &crc,
0182 RPCAMCLinkCounters &counters) const {
0183 bool more_trailers(true);
0184 for (--word_end; word_end > word && more_trailers; --word_end) {
0185 FEDTrailer trailer(reinterpret_cast<unsigned char const *>(word_end));
0186 LogDebug("RPCTwinMuxRawToDigi") << "CDF Trailer " << std::hex << *word_end << std::dec << ", length "
0187 << trailer.fragmentLength();
0188 if (!trailer.check()) {
0189 if (fill_counters_) {
0190 counters.add(RPCAMCLinkEvents::fed_trailer_check_fail_, RPCAMCLink(fed, RPCAMCLink::wildcard_));
0191 }
0192 edm::LogWarning("RPCTwinMuxRawToDigi") << "FED Trailer check failed for FED id " << fed;
0193 --word_end;
0194 break;
0195 }
0196 if (trailer.fragmentLength() != nwords) {
0197 if (fill_counters_) {
0198 counters.add(RPCAMCLinkEvents::fed_trailer_length_mismatch_, RPCAMCLink(fed, RPCAMCLink::wildcard_));
0199 }
0200 edm::LogWarning("RPCTwinMuxRawToDigi") << "FED Trailer length " << trailer.fragmentLength()
0201 << " does not match actual data size " << nwords << " for FED id " << fed;
0202 --word_end;
0203 break;
0204 }
0205
0206
0207
0208 more_trailers = false;
0209 }
0210
0211 ++word_end;
0212
0213 return !more_trailers;
0214 }
0215
0216 bool RPCTwinMuxRawToDigi::processBlock(int fed,
0217 std::uint64_t const *&word,
0218 std::uint64_t const *word_end,
0219 std::uint16_t &crc,
0220 RPCAMCLinkCounters &counters,
0221 std::set<std::pair<RPCDetId, RPCDigi> > &digis) const {
0222
0223 rpctwinmux::BlockHeader block_header(*word);
0224 if (calculate_crc_) {
0225 compute_crc_64bit(crc, *word);
0226 }
0227 ++word;
0228
0229 unsigned int n_amc(block_header.getNAMC());
0230 if (word + n_amc + 1 >= word_end) {
0231 if (fill_counters_) {
0232 counters.add(RPCAMCLinkEvents::fed_amc13_block_incomplete_, RPCAMCLink(fed, RPCAMCLink::wildcard_));
0233 }
0234 edm::LogWarning("RPCTwinMuxRawToDigi") << "Block can not be complete for FED " << fed;
0235 word = word_end;
0236 return false;
0237 }
0238
0239 std::vector<std::pair<unsigned int, unsigned int> > amc_size_map;
0240 for (unsigned int amc = 0; amc < n_amc; ++amc) {
0241 LogDebug("RPCTwinMuxRawToDigi") << "Block AMC " << amc;
0242 rpctwinmux::BlockAMCContent amc_content(*word);
0243 if (calculate_crc_) {
0244 compute_crc_64bit(crc, *word);
0245 }
0246 ++word;
0247
0248 amc_size_map.push_back(std::make_pair(amc_content.getAMCNumber(), amc_content.getSize()));
0249 if (!amc_content.isValid()) {
0250 if (fill_counters_) {
0251 counters.add(RPCAMCLinkEvents::amc_amc13_evc_bc_invalid_, RPCAMCLink(fed, amc_content.getAMCNumber()));
0252 }
0253 edm::LogWarning("RPCTwinMuxRawToDigi")
0254 << "BlockAMCContent is reporting an invalid "
0255 << "Event Counter or Bunch Counter for FED " << fed << ", AMC " << amc_content.getAMCNumber();
0256 }
0257 }
0258
0259 for (std::pair<unsigned int, unsigned int> const &amc_size : amc_size_map) {
0260 processTwinMux(fed, amc_size.first, amc_size.second, word, word_end, crc, counters, digis);
0261 }
0262
0263 if (word < word_end) {
0264 rpctwinmux::BlockTrailer block_trailer(*word);
0265 if (calculate_crc_) {
0266 compute_crc_64bit(crc, *word);
0267 }
0268 ++word;
0269 return true;
0270 } else {
0271 return false;
0272 }
0273 }
0274
0275 bool RPCTwinMuxRawToDigi::processTwinMux(int fed,
0276 unsigned int amc_number,
0277 unsigned int size,
0278 std::uint64_t const *&word,
0279 std::uint64_t const *word_end,
0280 std::uint16_t &crc,
0281 RPCAMCLinkCounters &counters,
0282 std::set<std::pair<RPCDetId, RPCDigi> > &digis) const {
0283 LogDebug("RPCTwinMuxRawToDigi") << "TwinMux AMC#" << amc_number << ", size " << size;
0284 if (!size) {
0285 return true;
0286 }
0287 if (amc_number > (unsigned int)RPCAMCLink::max_amcnumber_) {
0288 if (fill_counters_) {
0289 counters.add(RPCAMCLinkEvents::fed_amc13_amc_number_invalid_, RPCAMCLink(fed, RPCAMCLink::wildcard_));
0290 }
0291 edm::LogWarning("RPCTwinMuxRawToDigi") << "Invalid AMC Number " << amc_number << " for FED " << fed;
0292 if (calculate_crc_) {
0293 for (; size > 0; --size, ++word) {
0294 compute_crc_64bit(crc, *word);
0295 }
0296 } else {
0297 word += size;
0298 }
0299 return false;
0300 }
0301 if (word + size >= word_end || size < 3) {
0302 if (fill_counters_) {
0303 counters.add(RPCAMCLinkEvents::amc_payload_incomplete_, RPCAMCLink(fed, amc_number));
0304 }
0305 edm::LogWarning("RPCTwinMuxRawToDigi")
0306 << "TwinMux Data can not be complete for FED " << fed << " AMC #" << amc_number;
0307 if (calculate_crc_) {
0308 for (; size > 0; --size, ++word) {
0309 compute_crc_64bit(crc, *word);
0310 }
0311 } else {
0312 word += size;
0313 }
0314 return false;
0315 }
0316
0317 rpctwinmux::TwinMuxHeader header(word);
0318 unsigned int bx_counter(header.getBXCounter());
0319 if (calculate_crc_) {
0320 compute_crc_64bit(crc, *word);
0321 ++word;
0322 compute_crc_64bit(crc, *word);
0323 ++word;
0324 } else {
0325 word += 2;
0326 }
0327 size -= 2;
0328
0329 if (amc_number != header.getAMCNumber()) {
0330 if (fill_counters_) {
0331 counters.add(RPCAMCLinkEvents::amc_number_mismatch_, RPCAMCLink(fed, amc_number));
0332 }
0333 edm::LogWarning("RPCTwinMuxRawToDigi")
0334 << "AMC Number inconsistent in TwinMuxHeader vs BlockAMCContent: " << header.getAMCNumber() << " vs "
0335 << amc_number;
0336 if (calculate_crc_) {
0337 for (; size > 0; --size, ++word) {
0338 compute_crc_64bit(crc, *word);
0339 }
0340 } else {
0341 word += size;
0342 }
0343 return false;
0344 }
0345
0346 int bx_min(bx_min_), bx_max(bx_max_);
0347 if (header.hasRPCBXWindow()) {
0348 bx_min = std::max(bx_min, header.getRPCBXMin());
0349 bx_max = std::min(bx_max, header.getRPCBXMax());
0350 LogDebug("RPCTwinMuxRawToDigi") << "BX range set to " << bx_min << ", " << bx_max;
0351 }
0352
0353 bool has_first_rpc_word(false);
0354 rpctwinmux::RPCRecord rpc_record;
0355 for (; size > 1; --size, ++word) {
0356 if (calculate_crc_) {
0357 compute_crc_64bit(crc, *word);
0358 }
0359 unsigned int type(rpctwinmux::TwinMuxRecord::getType(*word));
0360 LogDebug("RPCTwinMuxRawToDigi") << "TwinMux data type " << std::hex << type << std::dec;
0361 if (type == rpctwinmux::TwinMuxRecord::rpc_first_type_) {
0362 if (has_first_rpc_word) {
0363 processRPCRecord(fed, amc_number, bx_counter, rpc_record, counters, digis, bx_min, bx_max, 0, 1);
0364 }
0365 rpc_record.reset();
0366 rpc_record.set(0, *word);
0367 has_first_rpc_word = true;
0368 } else if (type == rpctwinmux::TwinMuxRecord::rpc_second_type_) {
0369 if (!has_first_rpc_word) {
0370 edm::LogWarning("RPCTwinMuxRawToDigi") << "Received second RPC word without first";
0371 } else {
0372 rpc_record.set(1, *word);
0373 processRPCRecord(fed, amc_number, bx_counter, rpc_record, counters, digis, bx_min, bx_max, 0, 4);
0374 has_first_rpc_word = false;
0375 }
0376 }
0377 }
0378 if (has_first_rpc_word) {
0379 processRPCRecord(fed, amc_number, bx_counter, rpc_record, counters, digis, bx_min, bx_max, 0, 1);
0380 }
0381
0382 rpctwinmux::TwinMuxTrailer trailer(*word);
0383 LogDebug("RPCTwinMuxRawToDigi") << "TwinMux Trailer " << std::hex << *word << std::dec;
0384 if (calculate_crc_) {
0385 compute_crc_64bit(crc, *word);
0386 }
0387 ++word;
0388 return true;
0389 }
0390
0391 void RPCTwinMuxRawToDigi::processRPCRecord(int fed,
0392 unsigned int amc_number,
0393 unsigned int bx_counter,
0394 rpctwinmux::RPCRecord const &record,
0395 RPCAMCLinkCounters &counters,
0396 std::set<std::pair<RPCDetId, RPCDigi> > &digis,
0397 int bx_min,
0398 int bx_max,
0399 unsigned int link,
0400 unsigned int link_max) const {
0401 LogDebug("RPCTwinMuxRawToDigi") << "RPCRecord " << std::hex << record.getRecord()[0] << ", " << record.getRecord()[1]
0402 << std::dec << std::endl;
0403 int bx_offset(record.getBXOffset());
0404 RPCAMCLink tm_link(fed, amc_number);
0405 for (; link <= link_max; ++link) {
0406 tm_link.setAMCInput(link);
0407 rpctwinmux::RPCLinkRecord link_record(record.getRPCLinkRecord(link));
0408
0409 if (link_record.isError()) {
0410 if (fill_counters_ && bx_offset == 0) {
0411 counters.add(RPCAMCLinkEvents::input_link_error_, tm_link);
0412 }
0413 LogDebug("RPCTwinMuxRawToDigi") << "Link in error for " << tm_link;
0414 continue;
0415 } else if (!link_record.isAcknowledge()) {
0416 if (fill_counters_ && bx_offset == 0) {
0417 counters.add(RPCAMCLinkEvents::input_link_ack_fail_, tm_link);
0418 }
0419 LogDebug("RPCTwinMuxRawToDigi") << "Link without acknowledge for " << tm_link;
0420 continue;
0421 }
0422
0423 if (!link_record.getPartitionData()) {
0424 continue;
0425 }
0426
0427 int bx(bx_offset - (int)(link_record.getDelay()));
0428 LogDebug("RPCTwinMuxRawToDigi") << "RPC BX " << bx << " for offset " << bx_offset;
0429
0430 if (fill_counters_ && bx == 0 && link_record.isEOD()) {
0431 counters.add(RPCAMCLinkEvents::input_eod_, tm_link);
0432 }
0433
0434 RPCAMCLinkMap::map_type::const_iterator tm_link_it = es_tm_link_map_->getMap().find(tm_link);
0435 if (tm_link_it == es_tm_link_map_->getMap().end()) {
0436 if (fill_counters_ && bx_offset == 0) {
0437 counters.add(RPCAMCLinkEvents::amc_link_invalid_, RPCAMCLink(fed, amc_number));
0438 }
0439 LogDebug("RPCTwinMuxRawToDigi") << "Skipping unknown TwinMuxLink " << tm_link;
0440 continue;
0441 }
0442
0443 RPCLBLink lb_link = tm_link_it->second;
0444
0445 if (link_record.getLinkBoard() > (unsigned int)RPCLBLink::max_linkboard_) {
0446 if (fill_counters_ && bx_offset == 0) {
0447 counters.add(RPCAMCLinkEvents::input_lb_invalid_, tm_link);
0448 }
0449 LogDebug("RPCTwinMuxRawToDigi") << "Skipping invalid LinkBoard " << link_record.getLinkBoard() << " for record "
0450 << link << " (" << std::hex << link_record.getRecord() << " in "
0451 << record.getRecord()[0] << ':' << record.getRecord()[1] << std::dec << " from "
0452 << tm_link;
0453 continue;
0454 }
0455
0456 if (link_record.getConnector() > (unsigned int)RPCLBLink::max_connector_) {
0457 if (fill_counters_ && bx_offset == 0) {
0458 counters.add(RPCAMCLinkEvents::input_connector_invalid_, tm_link);
0459 }
0460 LogDebug("RPCTwinMuxRawToDigi") << "Skipping invalid Connector " << link_record.getConnector() << " for record "
0461 << link << " (" << std::hex << link_record.getRecord() << " in "
0462 << record.getRecord()[0] << ':' << record.getRecord()[1] << std::dec << ") from "
0463 << tm_link;
0464 continue;
0465 }
0466
0467 lb_link.setLinkBoard(link_record.getLinkBoard());
0468 lb_link.setConnector(link_record.getConnector());
0469
0470 RPCLBLinkMap::map_type::const_iterator lb_link_it = es_lb_link_map_->getMap().find(lb_link);
0471 if (lb_link_it == es_lb_link_map_->getMap().end()) {
0472 if (fill_counters_ && bx_offset == 0) {
0473 counters.add(RPCAMCLinkEvents::input_connector_not_used_, tm_link);
0474 }
0475 LogDebug("RPCTwinMuxRawToDigi") << "Could not find " << lb_link << " for record " << link << " (" << std::hex
0476 << link_record.getRecord() << " in " << record.getRecord()[0] << ':'
0477 << record.getRecord()[1] << std::dec << ") from " << tm_link;
0478 continue;
0479 }
0480
0481 if (bx < bx_min || bx > bx_max) {
0482 continue;
0483 }
0484
0485 if (fill_counters_ && bx == 0) {
0486 counters.add(RPCAMCLinkEvents::amc_event_, RPCAMCLink(fed, amc_number));
0487 counters.add(RPCAMCLinkEvents::input_event_, tm_link);
0488 }
0489
0490 RPCFebConnector const &feb_connector(lb_link_it->second);
0491 RPCDetId det_id(feb_connector.getRPCDetId());
0492 unsigned int channel_offset(link_record.getPartition() ? 9 : 1);
0493 std::uint8_t data(link_record.getPartitionData());
0494
0495 for (unsigned int channel = 0; channel < 8; ++channel) {
0496 if (data & (0x1 << channel)) {
0497 unsigned int strip(feb_connector.getStrip(channel + channel_offset));
0498 if (strip) {
0499 digis.insert(std::pair<RPCDetId, RPCDigi>(det_id, RPCDigi(strip, bx)));
0500 LogDebug("RPCTwinMuxRawToDigi") << "RPCDigi " << det_id.rawId() << ", " << strip << ", " << bx;
0501 }
0502 }
0503 }
0504
0505
0506 }
0507 }
0508
0509 void RPCTwinMuxRawToDigi::putRPCDigis(edm::Event &event, std::set<std::pair<RPCDetId, RPCDigi> > const &digis) {
0510 std::unique_ptr<RPCDigiCollection> rpc_digi_collection(new RPCDigiCollection());
0511 RPCDetId rpc_det_id;
0512 std::vector<RPCDigi> local_digis;
0513 for (std::pair<RPCDetId, RPCDigi> const &rpc_digi : digis) {
0514 LogDebug("RPCTwinMuxRawToDigi") << "RPCDigi " << rpc_digi.first.rawId() << ", " << rpc_digi.second.strip() << ", "
0515 << rpc_digi.second.bx();
0516 if (rpc_digi.first != rpc_det_id) {
0517 if (!local_digis.empty()) {
0518 rpc_digi_collection->put(RPCDigiCollection::Range(local_digis.begin(), local_digis.end()), rpc_det_id);
0519 local_digis.clear();
0520 }
0521 rpc_det_id = rpc_digi.first;
0522 }
0523 local_digis.push_back(rpc_digi.second);
0524 }
0525 if (!local_digis.empty()) {
0526 rpc_digi_collection->put(RPCDigiCollection::Range(local_digis.begin(), local_digis.end()), rpc_det_id);
0527 }
0528
0529 event.put(std::move(rpc_digi_collection));
0530 }
0531
0532 void RPCTwinMuxRawToDigi::putCounters(edm::Event &event, std::unique_ptr<RPCAMCLinkCounters> counters) {
0533 event.put(std::move(counters));
0534 }
0535
0536 #include "FWCore/Framework/interface/MakerMacros.h"
0537 DEFINE_FWK_MODULE(RPCTwinMuxRawToDigi);