File indexing completed on 2024-09-12 04:16:39
0001
0002
0003
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
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
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
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
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
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
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);