Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 /**  Produces Pseudo-random upstream objects converts them into P2GTCandidates and 
0002  *   writes them into buffer files. Intended to more thoroughly test the whole
0003  *   phase space of Phase-2 GT inputs.
0004  * */
0005 
0006 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0007 #include "FWCore/ParameterSet/interface/allowedValues.h"
0008 #include "DataFormats/Common/interface/Handle.h"
0009 
0010 #include "FWCore/Framework/interface/MakerMacros.h"
0011 #include "DataFormats/Common/interface/View.h"
0012 
0013 #include "FWCore/Framework/interface/Frameworkfwd.h"
0014 #include "FWCore/Framework/interface/one/EDProducer.h"
0015 
0016 #include "FWCore/Framework/interface/Event.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "DataFormats/L1Trigger/interface/P2GTCandidate.h"
0019 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0020 
0021 #include "L1Trigger/DemonstratorTools/interface/BoardDataWriter.h"
0022 #include "L1Trigger/DemonstratorTools/interface/utilities.h"
0023 
0024 #include "L1GTEvaluationInterface.h"
0025 
0026 #include <vector>
0027 #include <array>
0028 #include <string>
0029 #include <unordered_map>
0030 #include <fstream>
0031 #include <limits>
0032 
0033 #include <optional>
0034 #include <random>
0035 
0036 using namespace l1t;
0037 
0038 class L1GTEvaluationProducer : public edm::one::EDProducer<> {
0039 public:
0040   explicit L1GTEvaluationProducer(const edm::ParameterSet &);
0041   ~L1GTEvaluationProducer() override = default;
0042 
0043   static void fillDescriptions(edm::ConfigurationDescriptions &);
0044 
0045 private:
0046   void produce(edm::Event &, const edm::EventSetup &) override;
0047   int nextValue(int mean = 1000, bool sign = false, int max = std::numeric_limits<int>::max());
0048 
0049   int nextPt() {
0050     return std::max<int>(0,
0051                          nextValue(300, false, (1 << P2GTCandidate::hwPT_t::width) - 1) +
0052                              std::normal_distribution<double>(0, 500)(randomGenerator_));
0053   }
0054   int nextEta() {
0055     return std::uniform_int_distribution<int>(-(1 << (P2GTCandidate::hwEta_t::width - 1)),
0056                                               (1 << (P2GTCandidate::hwEta_t::width - 1)) - 1)(randomGenerator_);
0057   }
0058   int nextPhi() {
0059     return std::uniform_int_distribution<int>(-(1 << (P2GTCandidate::hwPhi_t::width - 1)),
0060                                               (1 << (P2GTCandidate::hwPhi_t::width - 1)) - 1)(randomGenerator_);
0061   }
0062 
0063   void writeInputPatterns(
0064       const std::unordered_map<std::string, std::vector<std::unique_ptr<l1t::L1TGT_BaseInterface>>> &inputObjects);
0065 
0066   void writeOutputPatterns(
0067       const std::unordered_map<std::string, std::vector<std::unique_ptr<l1t::L1TGT_BaseInterface>>> &inputObjects);
0068 
0069   void endJob() override;
0070 
0071   std::mt19937 randomGenerator_;
0072   l1t::demo::BoardDataWriter inputBoardDataWriter_;
0073   std::unordered_map<std::string, std::size_t> numChannels_;
0074   l1t::demo::BoardDataWriter outputBoardDataWriter_;
0075 };
0076 
0077 static constexpr std::array<const char *, 29> AVAILABLE_COLLECTIONS{{"GTTPromptJets",
0078                                                                      "GTTDisplacedJets",
0079                                                                      "GTTPromptHtSum",
0080                                                                      "GTTDisplacedHtSum",
0081                                                                      "GTTEtSum",
0082                                                                      "GTTHadronicTaus",
0083                                                                      "CL2JetsSC4",
0084                                                                      "CL2JetsSC8",
0085                                                                      "CL2Taus",
0086                                                                      "CL2HtSum",
0087                                                                      "CL2EtSum",
0088                                                                      "GCTNonIsoEg",
0089                                                                      "GCTIsoEg",
0090                                                                      "GCTJets",
0091                                                                      "GCTTaus",
0092                                                                      "GCTHtSum",
0093                                                                      "GCTEtSum",
0094                                                                      "GMTSaPromptMuons",
0095                                                                      "GMTSaDisplacedMuons",
0096                                                                      "GMTTkMuons",
0097                                                                      "GMTTopo",
0098                                                                      "CL2Electrons",
0099                                                                      "CL2Photons",
0100                                                                      "GTTPhiCandidates",
0101                                                                      "GTTRhoCandidates",
0102                                                                      "GTTBsCandidates",
0103                                                                      "GTTPromptTracks",
0104                                                                      "GTTDisplacedTracks",
0105                                                                      "GTTPrimaryVert"}};
0106 
0107 template <typename T1, typename T2>
0108 static std::vector<T1> vconvert(std::vector<T2> ivec) {
0109   return std::vector<T1>(ivec.begin(), ivec.end());
0110 }
0111 
0112 L1GTEvaluationProducer::L1GTEvaluationProducer(const edm::ParameterSet &config)
0113     : randomGenerator_(config.exists("random_seed") ? config.getUntrackedParameter<unsigned int>("random_seed")
0114                                                     : std::random_device()()),
0115       inputBoardDataWriter_(
0116           l1t::demo::parseFileFormat(config.getUntrackedParameter<std::string>("patternFormat")),
0117           config.getUntrackedParameter<std::string>("inputFilename"),
0118           config.getUntrackedParameter<std::string>("inputFileExtension"),
0119           9,
0120           1,
0121           config.getUntrackedParameter<unsigned int>("maxFrames"),
0122           [&]() {
0123             const edm::ParameterSet &iChannels = config.getUntrackedParameterSet("InputChannels");
0124             demo::BoardDataWriter::ChannelMap_t channelMap;
0125 
0126             channelMap.insert(
0127                 {{"GCT", 1},
0128                  {{6, 0}, vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("GCT_1"))}});
0129             channelMap.insert(
0130                 {{"GMT", 1},
0131                  {{18, 0},
0132                   vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("GMT_1"))}});
0133             channelMap.insert(
0134                 {{"GTT", 1},
0135                  {{6, 0}, vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("GTT_1"))}});
0136             channelMap.insert(
0137                 {{"GTT", 2},
0138                  {{6, 0}, vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("GTT_2"))}});
0139             channelMap.insert(
0140                 {{"GTT", 3},
0141                  {{6, 0}, vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("GTT_3"))}});
0142             channelMap.insert(
0143                 {{"GTT", 4},
0144                  {{6, 0}, vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("GTT_4"))}});
0145             channelMap.insert(
0146                 {{"CL2", 1},
0147                  {{6, 0}, vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("CL2_1"))}});
0148             channelMap.insert(
0149                 {{"CL2", 2},
0150                  {{6, 0}, vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("CL2_2"))}});
0151             channelMap.insert(
0152                 {{"CL2", 3},
0153                  {{6, 0}, vconvert<std::size_t>(iChannels.getUntrackedParameter<std::vector<unsigned int>>("CL2_3"))}});
0154 
0155             return channelMap;
0156           }()),
0157       numChannels_(),
0158       outputBoardDataWriter_(l1t::demo::parseFileFormat(config.getUntrackedParameter<std::string>("patternFormat")),
0159                              config.getUntrackedParameter<std::string>("outputFilename"),
0160                              config.getUntrackedParameter<std::string>("outputFileExtension"),
0161                              9,
0162                              1,
0163                              config.getUntrackedParameter<unsigned int>("maxFrames"),
0164                              [&]() {
0165                                const edm::ParameterSet &oChannels = config.getUntrackedParameterSet("OutputChannels");
0166                                demo::BoardDataWriter::ChannelMap_t channelMap;
0167                                for (const char *name : AVAILABLE_COLLECTIONS) {
0168                                  if (oChannels.exists(name)) {
0169                                    std::vector<unsigned int> channels =
0170                                        oChannels.getUntrackedParameter<std::vector<unsigned int>>(name);
0171                                    for (std::size_t i = 0; i < channels.size(); i++) {
0172                                      channelMap.insert({{name, i}, {{1, 0}, {channels.at(i)}}});
0173                                    }
0174 
0175                                    numChannels_.insert({name, channels.size()});
0176                                  } else {
0177                                    numChannels_.insert({name, 0});
0178                                  }
0179                                }
0180                                return channelMap;
0181                              }()) {
0182   for (const char *name : AVAILABLE_COLLECTIONS) {
0183     produces<P2GTCandidateCollection>(name);
0184   }
0185 }
0186 
0187 void L1GTEvaluationProducer::fillDescriptions(edm::ConfigurationDescriptions &description) {
0188   edm::ParameterSetDescription desc;
0189   desc.addOptionalUntracked<unsigned int>("random_seed");
0190   desc.addUntracked<unsigned int>("maxFrames", 1024);
0191   desc.addUntracked<std::string>("inputFilename");
0192   desc.addUntracked<std::string>("inputFileExtension", "txt");
0193   desc.addUntracked<std::string>("outputFilename");
0194   desc.addUntracked<std::string>("outputFileExtension", "txt");
0195   desc.addUntracked<std::string>("patternFormat", "EMPv2");
0196 
0197   edm::ParameterSetDescription inputChannelDesc;
0198   inputChannelDesc.addUntracked<std::vector<unsigned int>>("GCT_1");
0199   inputChannelDesc.addUntracked<std::vector<unsigned int>>("GMT_1");
0200   inputChannelDesc.addUntracked<std::vector<unsigned int>>("GTT_1");
0201   inputChannelDesc.addUntracked<std::vector<unsigned int>>("GTT_2");
0202   inputChannelDesc.addUntracked<std::vector<unsigned int>>("GTT_3");
0203   inputChannelDesc.addUntracked<std::vector<unsigned int>>("GTT_4");
0204   inputChannelDesc.addUntracked<std::vector<unsigned int>>("CL2_1");
0205   inputChannelDesc.addUntracked<std::vector<unsigned int>>("CL2_2");
0206   inputChannelDesc.addUntracked<std::vector<unsigned int>>("CL2_3");
0207 
0208   desc.addUntracked<edm::ParameterSetDescription>("InputChannels", inputChannelDesc);
0209 
0210   edm::ParameterSetDescription outputChannelDesc;
0211   for (const char *name : AVAILABLE_COLLECTIONS) {
0212     outputChannelDesc.addOptionalUntracked<std::vector<unsigned int>>(name);
0213   }
0214 
0215   desc.addUntracked<edm::ParameterSetDescription>("OutputChannels", outputChannelDesc);
0216 
0217   description.addWithDefaultLabel(desc);
0218 }
0219 
0220 int L1GTEvaluationProducer::nextValue(int mean, bool sign, int max) {
0221   bool positive = sign ? std::bernoulli_distribution(0.5)(randomGenerator_) : true;
0222 
0223   int result;
0224   do {
0225     result = std::poisson_distribution<int>(mean)(randomGenerator_);
0226   } while (result > max);
0227 
0228   return positive ? result : -result;
0229 }
0230 
0231 template <typename... Args>
0232 static std::vector<ap_uint<64>> vpack(const Args &...vobjects) {
0233   std::vector<ap_uint<64>> vpacked;
0234 
0235   (
0236       [&vpacked](const std::vector<std::unique_ptr<l1t::L1TGT_BaseInterface>> &objects) {
0237         std::optional<ap_uint<64>> next_packed;
0238         for (const auto &object : objects) {
0239           if (object->packed_width() == 64) {
0240             const l1t::L1TGT_Interface<64> &interface_obj = dynamic_cast<const l1t::L1TGT_Interface<64> &>(*object);
0241             vpacked.emplace_back(interface_obj.pack());
0242           } else if (object->packed_width() == 96) {
0243             const l1t::L1TGT_Interface<96> &interface_obj = dynamic_cast<const l1t::L1TGT_Interface<96> &>(*object);
0244             ap_uint<96> packed = interface_obj.pack();
0245             if (next_packed.has_value()) {
0246               vpacked.emplace_back(packed(95, 64) << 32 | next_packed.value());
0247               next_packed.reset();
0248             } else {
0249               next_packed = packed(95, 64);
0250             }
0251 
0252             vpacked.emplace_back(packed(63, 0));
0253 
0254           } else if (object->packed_width() == 128) {
0255             const l1t::L1TGT_Interface<128> &interface_obj = dynamic_cast<const l1t::L1TGT_Interface<128> &>(*object);
0256             ap_uint<128> packed = interface_obj.pack();
0257             vpacked.emplace_back(packed(63, 0));
0258             vpacked.emplace_back(packed(127, 64));
0259           }
0260         }
0261       }(vobjects),
0262       ...);
0263 
0264   return vpacked;
0265 }
0266 
0267 void L1GTEvaluationProducer::writeInputPatterns(
0268     const std::unordered_map<std::string, std::vector<std::unique_ptr<l1t::L1TGT_BaseInterface>>> &inputObjects) {
0269   inputBoardDataWriter_.addEvent(
0270       l1t::demo::EventData{{{{"GTT", 1},
0271                              vpack(inputObjects.at("GTTPromptJets"),
0272                                    inputObjects.at("GTTDisplacedJets"),
0273                                    inputObjects.at("GTTPromptHtSum"),
0274                                    inputObjects.at("GTTDisplacedHtSum"),
0275                                    inputObjects.at("GTTEtSum"))},
0276                             {{"GTT", 2}, vpack(inputObjects.at("GTTHadronicTaus"))},
0277                             {{"CL2", 1},
0278                              vpack(inputObjects.at("CL2JetsSC4"),
0279                                    inputObjects.at("CL2HtSum"),
0280                                    inputObjects.at("CL2EtSum"),
0281                                    inputObjects.at("CL2JetsSC8"))},
0282                             {{"CL2", 2}, vpack(inputObjects.at("CL2Taus"))},
0283                             {{"GCT", 1},
0284                              vpack(inputObjects.at("GCTNonIsoEg"),
0285                                    inputObjects.at("GCTIsoEg"),
0286                                    inputObjects.at("GCTJets"),
0287                                    inputObjects.at("GCTTaus"),
0288                                    inputObjects.at("GCTEtSum"),
0289                                    inputObjects.at("GCTHtSum"))},
0290                             {{"GMT", 1},
0291                              vpack(inputObjects.at("GMTSaPromptMuons"),
0292                                    inputObjects.at("GMTSaDisplacedMuons"),
0293                                    inputObjects.at("GMTTkMuons"),
0294                                    inputObjects.at("GMTTopo"))},
0295                             {{"CL2", 3}, vpack(inputObjects.at("CL2Electrons"), inputObjects.at("CL2Photons"))},
0296                             {{"GTT", 3},
0297                              vpack(inputObjects.at("GTTPhiCandidates"),
0298                                    inputObjects.at("GTTRhoCandidates"),
0299                                    inputObjects.at("GTTBsCandidates"))},
0300                             {{"GTT", 4},
0301                              vpack(inputObjects.at("GTTPromptTracks"),
0302                                    inputObjects.at("GTTDisplacedTracks"),
0303                                    inputObjects.at("GTTPrimaryVert"))}}});
0304 }
0305 
0306 void L1GTEvaluationProducer::writeOutputPatterns(
0307     const std::unordered_map<std::string, std::vector<std::unique_ptr<l1t::L1TGT_BaseInterface>>> &outputObjects) {
0308   std::map<demo::LinkId, std::vector<ap_uint<64>>> eventData;
0309 
0310   for (const char *name : AVAILABLE_COLLECTIONS) {
0311     std::vector<ap_uint<64>> data = vpack(outputObjects.at(name));
0312 
0313     for (std::size_t i = 0; i < numChannels_.at(name); i++) {
0314       for (std::size_t j = i; j < data.size(); j += numChannels_.at(name)) {
0315         eventData[{name, i}].push_back(data[j]);
0316       }
0317 
0318       while (eventData[{name, i}].size() < 9) {
0319         eventData[{name, i}].push_back(0);
0320       }
0321     }
0322   }
0323 
0324   outputBoardDataWriter_.addEvent(eventData);
0325 }
0326 
0327 void L1GTEvaluationProducer::produce(edm::Event &event, const edm::EventSetup &setup) {
0328   // Generate random input objects
0329   std::unordered_map<std::string, std::vector<std::unique_ptr<l1t::L1TGT_BaseInterface>>> inputObjects;
0330   for (std::size_t i = 0; i < 12; ++i) {
0331     // Global Muon Trigger
0332     inputObjects["GMTSaPromptMuons"].emplace_back(std::make_unique<l1t::L1TGT_GMT_PromptDisplacedMuon>(
0333         true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue(), nextValue(), nextValue()));
0334 
0335     inputObjects["GMTSaDisplacedMuons"].emplace_back(std::make_unique<l1t::L1TGT_GMT_PromptDisplacedMuon>(
0336         true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue(), nextValue(), nextValue()));
0337     inputObjects["GMTTkMuons"].emplace_back(std::make_unique<l1t::L1TGT_GMT_TrackMatchedmuon>(true,
0338                                                                                               nextPt(),
0339                                                                                               nextEta(),
0340                                                                                               nextPhi(),
0341                                                                                               nextValue(),
0342                                                                                               nextValue(),
0343                                                                                               nextValue(),
0344                                                                                               nextValue(),
0345                                                                                               nextValue(),
0346                                                                                               nextValue()));
0347     inputObjects["GMTTopo"].emplace_back(
0348         std::make_unique<l1t::L1TGT_GMT_TopoObject>(true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue()));
0349 
0350     // Global Calorimeter Trigger
0351     inputObjects["GCTNonIsoEg"].emplace_back(
0352         std::make_unique<l1t::L1TGT_GCT_EgammaNonIsolated6p6>(true, nextPt(), nextEta(), nextPhi()));
0353     inputObjects["GCTIsoEg"].emplace_back(
0354         std::make_unique<l1t::L1TGT_GCT_EgammaIsolated6p6>(true, nextPt(), nextEta(), nextPhi()));
0355     inputObjects["GCTJets"].emplace_back(std::make_unique<l1t::L1TGT_GCT_jet6p6>(true, nextPt(), nextEta(), nextPhi()));
0356     inputObjects["GCTTaus"].emplace_back(
0357         std::make_unique<l1t::L1TGT_GCT_tau6p6>(true, nextPt(), nextEta(), nextPhi(), nextValue()));
0358 
0359     // Global Track Trigger
0360     inputObjects["GTTPromptTracks"].emplace_back(std::make_unique<l1t::L1TGT_GTT_Track>());
0361     inputObjects["GTTDisplacedTracks"].emplace_back(std::make_unique<l1t::L1TGT_GTT_Track>());
0362     inputObjects["GTTPrimaryVert"].emplace_back(
0363         std::make_unique<l1t::L1TGT_GTT_PrimaryVert>(true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue()));
0364     inputObjects["GTTPromptJets"].emplace_back(
0365         std::make_unique<l1t::L1TGT_GTT_PromptJet>(true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue()));
0366     inputObjects["GTTDisplacedJets"].emplace_back(std::make_unique<l1t::L1TGT_GTT_DisplacedJet>(
0367         true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue(), nextValue()));
0368     inputObjects["GTTHadronicTaus"].emplace_back(std::make_unique<l1t::L1TGT_GTT_HadronicTau>(
0369         true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue(), nextValue(), nextValue()));
0370     inputObjects["GTTPhiCandidates"].emplace_back(
0371         std::make_unique<l1t::L1TGT_GTT_LightMeson>(true, nextPt(), nextEta(), nextPhi(), nextValue()));
0372     inputObjects["GTTRhoCandidates"].emplace_back(
0373         std::make_unique<l1t::L1TGT_GTT_LightMeson>(true, nextPt(), nextEta(), nextPhi(), nextValue()));
0374     inputObjects["GTTBsCandidates"].emplace_back(
0375         std::make_unique<l1t::L1TGT_GTT_LightMeson>(true, nextPt(), nextEta(), nextPhi(), nextValue()));
0376 
0377     // Correlator Layer-2
0378     inputObjects["CL2JetsSC4"].emplace_back(
0379         std::make_unique<l1t::L1TGT_CL2_Jet>(true, nextPt(), nextEta(), nextPhi(), nextValue()));
0380     inputObjects["CL2JetsSC8"].emplace_back(
0381         std::make_unique<l1t::L1TGT_CL2_Jet>(true, nextPt(), nextEta(), nextPhi(), nextValue()));
0382     inputObjects["CL2Electrons"].emplace_back(std::make_unique<l1t::L1TGT_CL2_Electron>(
0383         true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue(), nextValue(), nextValue()));
0384     inputObjects["CL2Photons"].emplace_back(
0385         std::make_unique<l1t::L1TGT_CL2_Photon>(true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue()));
0386     inputObjects["CL2Taus"].emplace_back(std::make_unique<l1t::L1TGT_CL2_Tau>(
0387         true, nextPt(), nextEta(), nextPhi(), nextValue(), nextValue(), nextValue(), nextValue()));
0388   }
0389 
0390   inputObjects["CL2HtSum"].emplace_back(
0391       std::make_unique<l1t::L1TGT_CL2_Sum>(true, nextValue(), nextValue(), nextValue()));
0392   inputObjects["CL2EtSum"].emplace_back(
0393       std::make_unique<l1t::L1TGT_CL2_Sum>(true, nextValue(), nextValue(), nextValue()));
0394   inputObjects["GCTHtSum"].emplace_back(
0395       std::make_unique<l1t::L1TGT_GCT_Sum2>(true, nextValue(), nextValue(), nextValue()));
0396   inputObjects["GCTEtSum"].emplace_back(
0397       std::make_unique<l1t::L1TGT_GCT_Sum2>(true, nextValue(), nextValue(), nextValue()));
0398 
0399   inputObjects["GTTPromptHtSum"].emplace_back(
0400       std::make_unique<l1t::L1TGT_GTT_Sum>(true, nextValue(), nextValue(), nextValue()));
0401   inputObjects["GTTDisplacedHtSum"].emplace_back(
0402       std::make_unique<l1t::L1TGT_GTT_Sum>(true, nextValue(), nextValue(), nextValue()));
0403   inputObjects["GTTEtSum"].emplace_back(
0404       std::make_unique<l1t::L1TGT_GTT_Sum>(true, nextValue(), nextValue(), nextValue()));
0405 
0406   // Write them to a pattern file
0407   writeInputPatterns(inputObjects);
0408   writeOutputPatterns(inputObjects);
0409 
0410   for (const auto &[key, inputCollection] : inputObjects) {
0411     std::unique_ptr<P2GTCandidateCollection> gtCollection = std::make_unique<P2GTCandidateCollection>();
0412     for (const auto &object : inputCollection) {
0413       gtCollection->emplace_back(object->to_GTObject());
0414     }
0415 
0416     event.put(std::move(gtCollection), key);
0417   }
0418 }
0419 
0420 void L1GTEvaluationProducer::endJob() {
0421   inputBoardDataWriter_.flush();
0422   outputBoardDataWriter_.flush();
0423 }
0424 
0425 DEFINE_FWK_MODULE(L1GTEvaluationProducer);