Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:26:07

0001 // -*- C++ -*-
0002 //
0003 // Package:    EventFilter/L1TRawToDigi
0004 // Class:      L1TDigiToRaw
0005 //
0006 /**\class L1TDigiToRaw L1TDigiToRaw.cc EventFilter/L1TRawToDigi/plugins/L1TDigiToRaw.cc
0007 
0008  Description: [one line class summary]
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  Matthias Wolf
0015 //         Created:  Mon, 10 Feb 2014 14:29:40 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <iomanip>
0021 #include <memory>
0022 
0023 #define EDM_ML_DEBUG 1
0024 
0025 // user include files
0026 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
0027 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
0028 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
0029 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
0030 
0031 #include "FWCore/Framework/interface/ConsumesCollector.h"
0032 #include "FWCore/Framework/interface/Frameworkfwd.h"
0033 #include "FWCore/Framework/interface/stream/EDProducer.h"
0034 #include "FWCore/Framework/interface/Event.h"
0035 #include "FWCore/Framework/interface/MakerMacros.h"
0036 #include "FWCore/Utilities/interface/CRC16.h"
0037 
0038 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0039 
0040 #include "FWCore/Utilities/interface/InputTag.h"
0041 
0042 #include "EventFilter/L1TRawToDigi/interface/AMC13Spec.h"
0043 
0044 #include "PackingSetupFactory.h"
0045 
0046 namespace l1t {
0047   class L1TDigiToRaw : public edm::stream::EDProducer<> {
0048   public:
0049     explicit L1TDigiToRaw(const edm::ParameterSet&);
0050     ~L1TDigiToRaw() override;
0051 
0052     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0053 
0054     using edm::stream::EDProducer<>::consumes;
0055 
0056   private:
0057     void produce(edm::Event&, const edm::EventSetup&) override;
0058 
0059     void beginRun(edm::Run const&, edm::EventSetup const&) override{};
0060     void endRun(edm::Run const&, edm::EventSetup const&) override{};
0061     void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override{};
0062     void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override{};
0063 
0064     // ----------member data ---------------------------
0065     int evtType_;
0066     int fedId_;
0067     unsigned fwId_;
0068 
0069     // header and trailer sizes in chars
0070     int slinkHeaderSize_;
0071     int slinkTrailerSize_;
0072 
0073     std::unique_ptr<PackingSetup> setup_;
0074     std::unique_ptr<PackerTokens> tokens_;
0075 
0076     bool ctp7_mode_;
0077   };
0078 }  // namespace l1t
0079 
0080 namespace l1t {
0081   L1TDigiToRaw::L1TDigiToRaw(const edm::ParameterSet& config)
0082       : fedId_(config.getParameter<int>("FedId")), ctp7_mode_(config.getUntrackedParameter<bool>("CTP7")) {
0083     // Register products
0084     produces<FEDRawDataCollection>();
0085 
0086     fwId_ = config.getParameter<unsigned int>("FWId");
0087     evtType_ = config.getUntrackedParameter<int>("eventType", 1);
0088 
0089     auto cc = edm::ConsumesCollector(consumesCollector());
0090 
0091     setup_ = PackingSetupFactory::get()->make(config.getParameter<std::string>("Setup"));
0092     tokens_ = setup_->registerConsumes(config, cc);
0093 
0094     slinkHeaderSize_ = config.getUntrackedParameter<int>("lenSlinkHeader", 8);
0095     slinkTrailerSize_ = config.getUntrackedParameter<int>("lenSlinkTrailer", 8);
0096   }
0097 
0098   L1TDigiToRaw::~L1TDigiToRaw() {}
0099 
0100   // ------------ method called to produce the data  ------------
0101   void L1TDigiToRaw::produce(edm::Event& event, const edm::EventSetup& setup) {
0102     using namespace edm;
0103 
0104     LogDebug("L1T") << "Packing data with FED ID " << fedId_;
0105 
0106     amc13::Packet amc13;
0107 
0108     auto bxId = event.bunchCrossing();
0109     // Note: L1ID != event ID
0110     // See e.g. triggerCount vs. eventNumber
0111     // in EventFilter/FEDInterface/interface/FED1024.h
0112     // But the trigger count is not stored in cmssw event class
0113     auto evtId = event.id().event();
0114     auto orbit = event.eventAuxiliary().orbitNumber();
0115     LogDebug("L1T") << "Forming FED with metadata bxId=" << bxId << ", l1ID=" << evtId << ", orbit=" << orbit;
0116 
0117     // Create all the AMC payloads to pack into the AMC13
0118     for (const auto& item : setup_->getPackers(fedId_, fwId_)) {
0119       auto amc_no = item.first.first;
0120       auto board = item.first.second;
0121       auto packers = item.second;
0122 
0123       Blocks block_load;
0124       for (const auto& packer : packers) {
0125         LogDebug("L1T") << "Adding packed blocks";
0126         packer->setBoard(board);
0127         auto blocks = packer->pack(event, tokens_.get());
0128         block_load.insert(block_load.end(), blocks.begin(), blocks.end());
0129       }
0130 
0131       std::sort(block_load.begin(), block_load.end());
0132 
0133       LogDebug("L1T") << "Concatenating blocks";
0134 
0135       std::vector<uint32_t> load32;
0136       // CTP7 stores this info in AMC user header
0137       if (not ctp7_mode_) {
0138         // TODO Infrastructure firmware version.  Currently not used.
0139         // Would change the way the payload has to be unpacked.
0140         load32.push_back(0);
0141         load32.push_back(fwId_);
0142       }
0143       for (const auto& block : block_load) {
0144         LogDebug("L1T") << "Adding block " << block.header().getID() << " with size " << block.payload().size();
0145         auto load = block.payload();
0146 
0147 #ifdef EDM_ML_DEBUG
0148         std::stringstream s("");
0149         s << "Block content:" << std::endl << std::hex << std::setfill('0');
0150         for (const auto& word : load)
0151           s << std::setw(8) << word << std::endl;
0152         LogDebug("L1T") << s.str();
0153 #endif
0154 
0155         if (block.header().getType() == CTP7) {
0156           // Header is two words for CTP7, first word is just a magic
0157           load32.push_back(0xA110CA7E);
0158         }
0159         load32.push_back(block.header().raw());
0160         load32.insert(load32.end(), load.begin(), load.end());
0161       }
0162 
0163       LogDebug("L1T") << "Converting payload";
0164 
0165       std::vector<uint64_t> load64;
0166       for (unsigned int i = 0; i < load32.size(); i += 2) {
0167         uint64_t word = load32[i];
0168         if (i + 1 < load32.size()) {
0169           word |= static_cast<uint64_t>(load32[i + 1]) << 32;
0170         } else {
0171           word |= static_cast<uint64_t>(0xffffffff) << 32;
0172         }
0173         load64.push_back(word);
0174       }
0175 
0176       LogDebug("L1T") << "Creating AMC packet";
0177 
0178       unsigned amc_user_header = 0;
0179       if (ctp7_mode_)
0180         amc_user_header = fwId_;
0181       amc13.add(amc_no, board, evtId, orbit, bxId, load64, amc_user_header);
0182     }
0183 
0184     std::unique_ptr<FEDRawDataCollection> raw_coll(new FEDRawDataCollection());
0185     FEDRawData& fed_data = raw_coll->FEDData(fedId_);
0186 
0187     unsigned int size = slinkHeaderSize_ + slinkTrailerSize_ + amc13.size() * 8;
0188     fed_data.resize(size);
0189     unsigned char* payload = fed_data.data();
0190     unsigned char* payload_start = payload;
0191 
0192     FEDHeader header(payload);
0193     header.set(payload, evtType_, evtId, bxId, fedId_);
0194 
0195     amc13.write(event, payload, slinkHeaderSize_, size - slinkHeaderSize_ - slinkTrailerSize_);
0196 
0197     payload += slinkHeaderSize_;
0198     payload += amc13.size() * 8;
0199 
0200     FEDTrailer trailer(payload);
0201     trailer.set(payload, size / 8, evf::compute_crc(payload_start, size), 0, 0);
0202 
0203     event.put(std::move(raw_coll));
0204   }
0205 
0206   // ------------ method called when starting to processes a run  ------------
0207   /*
0208    void
0209    L1TDigiToRaw::beginRun(edm::Run const&, edm::EventSetup const&)
0210    {
0211    }
0212    */
0213 
0214   // ------------ method called when ending the processing of a run  ------------
0215   /*
0216    void
0217    L1TDigiToRaw::endRun(edm::Run const&, edm::EventSetup const&)
0218    {
0219    }
0220    */
0221 
0222   // ------------ method called when starting to processes a luminosity block  ------------
0223   /*
0224    void
0225    L1TDigiToRaw::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
0226    {
0227    }
0228    */
0229 
0230   // ------------ method called when ending the processing of a luminosity block  ------------
0231   /*
0232    void
0233    L1TDigiToRaw::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
0234    {
0235    }
0236    */
0237 
0238   // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0239   void L1TDigiToRaw::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0240     edm::ParameterSetDescription desc;
0241     desc.add<unsigned int>("FWId", -1);
0242     desc.add<int>("FedId");
0243     desc.addUntracked<int>("eventType", 1);
0244     desc.add<std::string>("Setup");
0245     desc.addOptional<edm::InputTag>("InputLabel", edm::InputTag(""));
0246     desc.addOptional<edm::InputTag>("InputLabel2", edm::InputTag(""));
0247     desc.addUntracked<int>("lenSlinkHeader", 8);
0248     desc.addUntracked<int>("lenSlinkTrailer", 8);
0249     desc.addUntracked<bool>("CTP7", false);
0250 
0251     PackingSetupFactory::get()->fillDescription(desc);
0252 
0253     descriptions.add("l1tDigiToRaw", desc);
0254   }
0255 }  // namespace l1t
0256 
0257 using namespace l1t;
0258 //define this as a plug-in
0259 DEFINE_FWK_MODULE(L1TDigiToRaw);