Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-05-26 01:15:39

0001 /****************************************************************************
0002  *
0003  * This is a part of HGCAL offline software.
0004  * Authors:
0005  *   Pedro Silva, CERN
0006  *   Laurent Forthomme, CERN
0007  *
0008  ****************************************************************************/
0009 
0010 #include <memory>
0011 
0012 #include "FWCore/Framework/interface/Frameworkfwd.h"
0013 #include "FWCore/Framework/interface/stream/EDProducer.h"
0014 #include "FWCore/Framework/interface/Event.h"
0015 #include "FWCore/Framework/interface/MakerMacros.h"
0016 #include "FWCore/ParameterSet/interface/EmptyGroupDescription.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/ServiceRegistry/interface/Service.h"
0019 #include "FWCore/Utilities/interface/CRC16.h"
0020 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0021 #include "FWCore/Utilities/interface/StreamID.h"
0022 
0023 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0024 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0025 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0026 
0027 #include "DataFormats/HGCalDigi/interface/HGCalRawDataEmulatorInfo.h"
0028 #include "EventFilter/HGCalRawToDigi/interface/HGCalFrameGenerator.h"
0029 #include "EventFilter/HGCalRawToDigi/interface/HGCalModuleTreeReader.h"
0030 
0031 class HGCalSlinkEmulator : public edm::stream::EDProducer<> {
0032 public:
0033   explicit HGCalSlinkEmulator(const edm::ParameterSet&);
0034 
0035   static void fillDescriptions(edm::ConfigurationDescriptions&);
0036 
0037 private:
0038   void produce(edm::Event&, const edm::EventSetup&) override;
0039 
0040   const unsigned int fed_id_;
0041 
0042   const bool store_emul_info_;
0043   const bool store_fed_header_trailer_;
0044 
0045   const edm::EDPutTokenT<FEDRawDataCollection> fedRawToken_;
0046   std::unique_ptr<hgcal::econd::Emulator> emulator_;
0047 
0048   edm::Service<edm::RandomNumberGenerator> rng_;
0049   edm::EDPutTokenT<HGCalSlinkEmulatorInfo> fedEmulInfoToken_;
0050   hgcal::HGCalFrameGenerator frame_gen_;
0051 };
0052 
0053 HGCalSlinkEmulator::HGCalSlinkEmulator(const edm::ParameterSet& iConfig)
0054     : fed_id_(iConfig.getParameter<unsigned int>("fedId")),
0055       store_emul_info_(iConfig.getParameter<bool>("storeEmulatorInfo")),
0056       store_fed_header_trailer_(iConfig.getParameter<bool>("fedHeaderTrailer")),
0057       fedRawToken_(produces<FEDRawDataCollection>()),
0058       frame_gen_(iConfig) {
0059   // figure out which emulator is to be used
0060   const auto& emul_type = iConfig.getParameter<std::string>("emulatorType");
0061   if (frame_gen_.econdParams().empty())
0062     throw cms::Exception("HGCalSlinkEmulator")
0063         << "No ECON-D parameters were retrieved from the configuration. Please add at least one.";
0064   const auto& econd_params = frame_gen_.econdParams().begin()->second;
0065   if (emul_type == "trivial")
0066     emulator_ = std::make_unique<hgcal::econd::TrivialEmulator>(econd_params);
0067   else if (emul_type == "hgcmodule")
0068     emulator_ = std::make_unique<hgcal::econd::HGCalModuleTreeReader>(
0069         econd_params,
0070         iConfig.getUntrackedParameter<std::string>("treeName"),
0071         iConfig.getUntrackedParameter<std::vector<std::string>>("inputs"));
0072   else
0073     throw cms::Exception("HGCalSlinkEmulator") << "Invalid emulator type chosen: '" << emul_type << "'.";
0074 
0075   frame_gen_.setEmulator(*emulator_);
0076 
0077   // ensure the random number generator service is present in configuration
0078   if (!rng_.isAvailable())
0079     throw cms::Exception("HGCalSlinkEmulator") << "The HGCalSlinkEmulator module requires the "
0080                                                   "RandomNumberGeneratorService,\n"
0081                                                   "which appears to be absent. Please add that service to your "
0082                                                   "configuration\n"
0083                                                   "or remove the modules that require it.";
0084 
0085   if (store_emul_info_)
0086     fedEmulInfoToken_ = produces<HGCalSlinkEmulatorInfo>();
0087 }
0088 
0089 void HGCalSlinkEmulator::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0090   frame_gen_.setRandomEngine(rng_->getEngine(iEvent.streamID()));
0091 
0092   // build the S-link payload
0093   auto slink_event = frame_gen_.produceSlinkEvent(fed_id_);
0094   const auto slink_event_size = slink_event.size() * sizeof(slink_event.at(0));
0095 
0096   // compute the total S-link payload size
0097   size_t total_event_size = slink_event_size;
0098   if (store_fed_header_trailer_)
0099     total_event_size += FEDHeader::length + FEDTrailer::length;
0100 
0101   // fill the output FED raw data collection
0102   FEDRawDataCollection raw_data;
0103   auto& fed_data = raw_data.FEDData(fed_id_);
0104   fed_data.resize(total_event_size);
0105   auto* ptr = fed_data.data();
0106 
0107   if (store_fed_header_trailer_) {
0108     const auto& last_event = frame_gen_.lastECONDEmulatedInput();
0109     const auto event_id = std::get<0>(last_event.first), bx_id = std::get<1>(last_event.first);
0110     int trg_type = 0;
0111     // compose 2*32-bit FED header word
0112     FEDHeader::set(ptr, trg_type, event_id, bx_id, fed_id_);
0113     LogDebug("HGCalSlinkEmulator").log([&](auto& log) {
0114       const FEDHeader hdr(ptr);
0115       log << "FED header: lvl1ID=" << hdr.lvl1ID() << ", bxID=" << hdr.bxID() << ", source ID=" << hdr.sourceID()
0116           << ".";
0117     });
0118     ptr += FEDHeader::length;
0119   }
0120 
0121   // insert ECON-D payload
0122   std::memcpy(ptr, slink_event.data(), slink_event_size);
0123   ptr += slink_event_size;
0124   LogDebug("HGCalSlinkEmulator") << "Wrote " << slink_event.size() << " 64-bit words = " << slink_event_size
0125                                  << " 8-bit words.";
0126 
0127   if (store_fed_header_trailer_) {
0128     // compose 2*32-bit FED trailer word
0129     FEDTrailer::set(ptr,
0130                     slink_event.size() + 2,
0131                     evf::compute_crc(reinterpret_cast<uint8_t*>(slink_event.data()), slink_event_size),
0132                     0,
0133                     0);
0134     LogDebug("HGCalSlinkEmulator").log([&](auto& log) {
0135       const FEDTrailer trl(ptr);
0136       log << "FED trailer: fragment length: " << trl.fragmentLength() << ", CRC=0x" << std::hex << trl.crc() << std::dec
0137           << ", status: " << trl.evtStatus() << ".";
0138     });
0139     ptr += FEDTrailer::length;
0140   }
0141 
0142   iEvent.emplace(fedRawToken_, std::move(raw_data));
0143 
0144   // store the emulation information if requested
0145   if (store_emul_info_)
0146     iEvent.emplace(fedEmulInfoToken_, frame_gen_.lastSlinkEmulatedInfo());
0147 }
0148 
0149 //
0150 void HGCalSlinkEmulator::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0151   auto desc = hgcal::HGCalFrameGenerator::description();
0152   desc.ifValue(
0153           edm::ParameterDescription<std::string>("emulatorType", "trivial", true),
0154           // trivial emulator
0155           "trivial" >> edm::EmptyGroupDescription() or
0156               // test beam tree content
0157               "hgcmodule" >> (edm::ParameterDescription<std::string>("treeName", "hgcroc_rawdata/eventdata", false) and
0158                               edm::ParameterDescription<std::vector<std::string>>("inputs", {}, false)))
0159       ->setComment("emulator mode (trivial, or hgcmodule)");
0160   desc.add<unsigned int>("fedId", 0)->setComment("FED number delivering the emulated frames");
0161   desc.add<bool>("fedHeaderTrailer", false)->setComment("also add FED header/trailer info");
0162   desc.add<bool>("storeEmulatorInfo", false)
0163       ->setComment("also append a 'truth' auxiliary info to the output event content");
0164   descriptions.add("hgcalEmulatedSlinkRawData", desc);
0165 }
0166 
0167 // define this as a plug-in
0168 DEFINE_FWK_MODULE(HGCalSlinkEmulator);