Back to home page

Project CMSSW displayed by LXR

 
 

    


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   // Get EventSetup Electronics Maps
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;  // rpcamc::Trailer
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   // no adjustable bx window implemented in readout yet
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         // rpcmp7::BXHeader bx_header(*record);
0121         have_bx_header = true;
0122       } else {
0123         if (caption_id == 0x01) {  // RX
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) {  // TX
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()) {  // EOD comes at the last delay
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);  // 1-16
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   // This translation should become part of a CondFormat
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]  // ring
0271                   ,
0272                   station[word]  // station
0273                   ,
0274                   ((endcap_sector - 1) / 6) + 1  // sector
0275                   ,
0276                   1  // layer
0277                   ,
0278                   (endcap_sector - 1) % 6 + 1  // subsector
0279                   ,
0280                   0);  // roll
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");