Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-12 04:16:39

0001 /**
0002  * BoardDataWriter for validation with hardware. Currently only writing the algo bits is implemented.
0003  **/
0004 
0005 #include "FWCore/Framework/interface/Frameworkfwd.h"
0006 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0007 
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "FWCore/Framework/interface/MakerMacros.h"
0010 
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0013 #include "FWCore/Utilities/interface/InputTag.h"
0014 
0015 #include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h"
0016 #include "L1Trigger/DemonstratorTools/interface/utilities.h"
0017 
0018 #include "FWCore/Utilities/interface/EDGetToken.h"
0019 #include "FWCore/Utilities/interface/EDMException.h"
0020 
0021 #include "DataFormats/L1Trigger/interface/P2GTAlgoBlock.h"
0022 
0023 #include "ap_int.h"
0024 
0025 #include <vector>
0026 #include <algorithm>
0027 #include <string>
0028 #include <array>
0029 
0030 using namespace l1t;
0031 
0032 class L1GTFinOrBoardWriter : public edm::one::EDAnalyzer<> {
0033 public:
0034   explicit L1GTFinOrBoardWriter(const edm::ParameterSet&);
0035 
0036   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0037 
0038 private:
0039   void analyze(const edm::Event&, const edm::EventSetup&) override;
0040   void endJob() override;
0041 
0042   unsigned int eventCounter_;
0043   const unsigned int maxEvents_;
0044   const std::array<unsigned int, 3> channelsLow_;
0045   const std::array<unsigned int, 3> channelsMid_;
0046   const std::array<unsigned int, 3> channelsHigh_;
0047   const unsigned int channelFinOr_;
0048   const edm::EDGetTokenT<P2GTAlgoBlockMap> algoBlocksToken_;
0049   l1t::demo::BoardDataWriter boardDataWriter_;
0050 
0051   std::map<l1t::demo::LinkId, std::vector<ap_uint<64>>> linkData_;
0052   std::size_t tmuxCounter_;
0053 };
0054 
0055 template <typename T, std::size_t N>
0056 static std::array<T, N> convert(std::vector<T> vec, const char* name) {
0057   if (vec.size() != N) {
0058     throw edm::Exception(edm::errors::Configuration)
0059         << "The parameter '" << name << "' should have " << N << " elements, but has " << vec.size()
0060         << " elements in the configuration.\n";
0061   }
0062   std::array<T, N> a;
0063   std::copy_n(std::make_move_iterator(vec.begin()), N, a.begin());
0064   return a;
0065 }
0066 
0067 L1GTFinOrBoardWriter::L1GTFinOrBoardWriter(const edm::ParameterSet& config)
0068     : eventCounter_(0),
0069       maxEvents_(config.getUntrackedParameter<unsigned int>("maxEvents")),
0070       channelsLow_(convert<unsigned int, 3>(config.getUntrackedParameter<std::vector<unsigned int>>("channelsLow"),
0071                                             "channelsLow")),
0072       channelsMid_(convert<unsigned int, 3>(config.getUntrackedParameter<std::vector<unsigned int>>("channelsMid"),
0073                                             "channelsMid")),
0074       channelsHigh_(convert<unsigned int, 3>(config.getUntrackedParameter<std::vector<unsigned int>>("channelsHigh"),
0075                                              "channelsHigh")),
0076       channelFinOr_(config.getUntrackedParameter<unsigned int>("channelFinOr")),
0077       algoBlocksToken_(consumes<P2GTAlgoBlockMap>(config.getUntrackedParameter<edm::InputTag>("algoBlocksTag"))),
0078       boardDataWriter_(l1t::demo::parseFileFormat(config.getUntrackedParameter<std::string>("patternFormat")),
0079                        config.getUntrackedParameter<std::string>("filename"),
0080                        config.getUntrackedParameter<std::string>("fileExtension"),
0081                        9,
0082                        2,
0083                        config.getUntrackedParameter<unsigned int>("maxFrames"),
0084                        [&]() {
0085                          l1t::demo::BoardDataWriter::ChannelMap_t channelMap;
0086                          channelMap.insert({l1t::demo::LinkId{"BeforeBxMaskAndPrescaleLow", channelsLow_[0]},
0087                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsLow_[0]}}});
0088                          channelMap.insert({l1t::demo::LinkId{"BeforePrescaleLow", channelsLow_[1]},
0089                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsLow_[1]}}});
0090                          channelMap.insert({l1t::demo::LinkId{"FinalLow", channelsLow_[2]},
0091                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsLow_[2]}}});
0092 
0093                          channelMap.insert({l1t::demo::LinkId{"BeforeBxMaskAndPrescaleMid", channelsMid_[0]},
0094                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsMid_[0]}}});
0095                          channelMap.insert({l1t::demo::LinkId{"BeforePrescaleMid", channelsMid_[1]},
0096                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsMid_[1]}}});
0097                          channelMap.insert({l1t::demo::LinkId{"FinalMid", channelsMid_[2]},
0098                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsMid_[2]}}});
0099 
0100                          channelMap.insert({l1t::demo::LinkId{"BeforeBxMaskAndPrescaleHigh", channelsHigh_[0]},
0101                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsHigh_[0]}}});
0102                          channelMap.insert({l1t::demo::LinkId{"BeforePrescaleHigh", channelsHigh_[1]},
0103                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsHigh_[1]}}});
0104                          channelMap.insert({l1t::demo::LinkId{"FinalHigh", channelsHigh_[2]},
0105                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelsHigh_[2]}}});
0106 
0107                          channelMap.insert({l1t::demo::LinkId{"FinOr", channelFinOr_},
0108                                             {l1t::demo::ChannelSpec{2, 0, 0}, {channelFinOr_}}});
0109 
0110                          return channelMap;
0111                        }()),
0112       linkData_(),
0113       tmuxCounter_(0) {}
0114 
0115 void L1GTFinOrBoardWriter::analyze(const edm::Event& event, const edm::EventSetup& iSetup) {
0116   const P2GTAlgoBlockMap& algoBlocks = event.get(algoBlocksToken_);
0117 
0118   auto algoBlockIt = algoBlocks.begin();
0119 
0120   if (tmuxCounter_ == 0) {
0121     linkData_[l1t::demo::LinkId{"BeforeBxMaskAndPrescaleLow", channelsLow_[0]}] = std::vector<ap_uint<64>>(18, 0);
0122     linkData_[l1t::demo::LinkId{"BeforePrescaleLow", channelsLow_[1]}] = std::vector<ap_uint<64>>(18, 0);
0123     linkData_[l1t::demo::LinkId{"FinalLow", channelsLow_[2]}] = std::vector<ap_uint<64>>(18, 0);
0124     linkData_[l1t::demo::LinkId{"BeforeBxMaskAndPrescaleMid", channelsMid_[0]}] = std::vector<ap_uint<64>>(18, 0);
0125     linkData_[l1t::demo::LinkId{"BeforePrescaleMid", channelsMid_[1]}] = std::vector<ap_uint<64>>(18, 0);
0126     linkData_[l1t::demo::LinkId{"FinalMid", channelsMid_[2]}] = std::vector<ap_uint<64>>(18, 0);
0127     linkData_[l1t::demo::LinkId{"BeforeBxMaskAndPrescaleHigh", channelsHigh_[0]}] = std::vector<ap_uint<64>>(18, 0);
0128     linkData_[l1t::demo::LinkId{"BeforePrescaleHigh", channelsHigh_[1]}] = std::vector<ap_uint<64>>(18, 0);
0129     linkData_[l1t::demo::LinkId{"FinalHigh", channelsHigh_[2]}] = std::vector<ap_uint<64>>(18, 0);
0130     linkData_[l1t::demo::LinkId{"FinOr", channelFinOr_}] = std::vector<ap_uint<64>>(18, 0);
0131   }
0132 
0133   for (std::size_t word = 0; word < 9; word++) {
0134     for (std::size_t idx = 0; idx < 64 && algoBlockIt != algoBlocks.end(); idx++, algoBlockIt++) {
0135       auto& [alogName, algoBlock] = *algoBlockIt;
0136       linkData_[l1t::demo::LinkId{"BeforeBxMaskAndPrescaleLow", channelsLow_[0]}][word + tmuxCounter_ * 9].set(
0137           idx, algoBlock.decisionBeforeBxMaskAndPrescale());
0138       linkData_[l1t::demo::LinkId{"BeforePrescaleLow", channelsLow_[1]}][word + tmuxCounter_ * 9].set(
0139           idx, algoBlock.decisionBeforePrescale());
0140       linkData_[l1t::demo::LinkId{"FinalLow", channelsLow_[2]}][word + tmuxCounter_ * 9].set(idx,
0141                                                                                              algoBlock.decisionFinal());
0142     }
0143   }
0144 
0145   for (std::size_t word = 0; word < 9; word++) {
0146     for (std::size_t idx = 0; idx < 64 && algoBlockIt != algoBlocks.end(); idx++, algoBlockIt++) {
0147       auto& [alogName, algoBlock] = *algoBlockIt;
0148       linkData_[l1t::demo::LinkId{"BeforeBxMaskAndPrescaleMid", channelsMid_[0]}][word + tmuxCounter_ * 9].set(
0149           idx, algoBlock.decisionBeforeBxMaskAndPrescale());
0150       linkData_[l1t::demo::LinkId{"BeforePrescaleMid", channelsMid_[1]}][word + tmuxCounter_ * 9].set(
0151           idx, algoBlock.decisionBeforePrescale());
0152       linkData_[l1t::demo::LinkId{"FinalMid", channelsMid_[2]}][word + tmuxCounter_ * 9].set(idx,
0153                                                                                              algoBlock.decisionFinal());
0154     }
0155   }
0156 
0157   for (std::size_t word = 0; word < 9; word++) {
0158     for (std::size_t idx = 0; idx < 64 && algoBlockIt != algoBlocks.end(); idx++, algoBlockIt++) {
0159       auto& [algoName, algoBlock] = *algoBlockIt;
0160       linkData_[l1t::demo::LinkId{"BeforeBxMaskAndPrescaleHigh", channelsHigh_[0]}][word + tmuxCounter_ * 9].set(
0161           idx, algoBlock.decisionBeforeBxMaskAndPrescale());
0162       linkData_[l1t::demo::LinkId{"BeforePrescaleHigh", channelsHigh_[1]}][word + tmuxCounter_ * 9].set(
0163           idx, algoBlock.decisionBeforePrescale());
0164       linkData_[l1t::demo::LinkId{"FinalHigh", channelsHigh_[2]}][word + tmuxCounter_ * 9].set(
0165           idx, algoBlock.decisionFinal());
0166     }
0167   }
0168 
0169   bool vetoed = false, vetoedPreview = false;
0170   int finOrByTypes = 0, finOrPreviewByTypes = 0;
0171   for (auto algoBlockIt = algoBlocks.begin(); algoBlockIt != algoBlocks.end(); algoBlockIt++) {
0172     auto& [alogName, algoBlock] = *algoBlockIt;
0173     vetoed |= (algoBlock.isVeto() && algoBlock.decisionFinal());
0174     vetoedPreview |= (algoBlock.isVeto() && algoBlock.decisionFinalPreview());
0175     finOrByTypes |= algoBlock.decisionFinal() ? algoBlock.triggerTypes() : 0;
0176     finOrPreviewByTypes |= algoBlock.decisionFinalPreview() ? algoBlock.triggerTypes() : 0;
0177   }
0178 
0179   // Add FinOrTrigger bits per https://gitlab.cern.ch/cms-cactus/phase2/firmware/gt-final-or#output-finor-bits
0180   ap_uint<64> finOrBits(0);
0181   finOrBits(7, 0) = finOrByTypes;
0182   finOrBits(15, 8) = finOrPreviewByTypes;
0183   finOrBits(23, 16) = vetoed ? 0 : finOrByTypes;
0184   finOrBits(31, 24) = vetoedPreview ? 0 : finOrPreviewByTypes;
0185 
0186   linkData_[l1t::demo::LinkId{"FinOr", channelFinOr_}][0 + tmuxCounter_ * 9] = finOrBits;
0187 
0188   if (tmuxCounter_ == 1) {
0189     boardDataWriter_.addEvent(l1t::demo::EventData(linkData_));
0190   }
0191 
0192   tmuxCounter_ = (tmuxCounter_ + 1) % 2;
0193 
0194   eventCounter_++;
0195 
0196   if (maxEvents_ != 0 && eventCounter_ == maxEvents_) {
0197     boardDataWriter_.flush();
0198     eventCounter_ = 0;
0199   }
0200 }
0201 
0202 void L1GTFinOrBoardWriter::endJob() {
0203   if (tmuxCounter_ == 1) {
0204     boardDataWriter_.addEvent(l1t::demo::EventData(linkData_));
0205   }
0206 
0207   boardDataWriter_.flush();
0208 }
0209 
0210 void L1GTFinOrBoardWriter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0211   edm::ParameterSetDescription desc;
0212   desc.addUntracked<std::string>("filename");
0213   desc.addUntracked<std::string>("fileExtension", "txt");
0214   desc.addUntracked<edm::InputTag>("algoBlocksTag");
0215   desc.addUntracked<std::vector<unsigned int>>("channelsLow");
0216   desc.addUntracked<std::vector<unsigned int>>("channelsMid");
0217   desc.addUntracked<std::vector<unsigned int>>("channelsHigh");
0218   desc.addUntracked<unsigned int>("channelFinOr");
0219   desc.addUntracked<unsigned int>("maxFrames", 1024);
0220   desc.addUntracked<unsigned int>("maxEvents", 0);
0221   desc.addUntracked<std::string>("patternFormat", "EMPv2");
0222 
0223   descriptions.addDefault(desc);
0224 }
0225 
0226 DEFINE_FWK_MODULE(L1GTFinOrBoardWriter);