Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:53

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