File indexing completed on 2022-10-01 01:02:15
0001 #include "L1Trigger/Phase2L1ParticleFlow/interface/L1TCorrelatorLayer1PatternFileWriter.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include <iostream>
0004
0005 L1TCorrelatorLayer1PatternFileWriter::L1TCorrelatorLayer1PatternFileWriter(const edm::ParameterSet& iConfig,
0006 const l1ct::Event& eventTemplate)
0007 : partition_(parsePartition(iConfig.getParameter<std::string>("partition"))),
0008 writeInputs_(iConfig.existsAs<std::string>("inputFileName") &&
0009 !iConfig.getParameter<std::string>("inputFileName").empty()),
0010 writeOutputs_(iConfig.existsAs<std::string>("outputFileName") &&
0011 !iConfig.getParameter<std::string>("outputFileName").empty()),
0012 outputBoard_(-1),
0013 outputLinkEgamma_(-1),
0014 fileFormat_(iConfig.getParameter<std::string>("fileFormat")),
0015 eventsPerFile_(iConfig.getParameter<uint32_t>("eventsPerFile")),
0016 eventIndex_(0) {
0017 if (writeInputs_) {
0018 nInputFramesPerBX_ = iConfig.getParameter<uint32_t>("nInputFramesPerBX");
0019
0020 if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) {
0021 configTimeSlices(iConfig, "tf", eventTemplate.raw.track.size(), tfTimeslices_, tfLinksFactor_);
0022 channelSpecsInput_["tf"] = {tmuxFactor_ * tfTimeslices_, tfTimeslices_};
0023 }
0024 if (partition_ == Partition::Barrel) {
0025 auto sectorConfig = iConfig.getParameter<std::vector<edm::ParameterSet>>("gctSectors");
0026 if (sectorConfig.size() != gctSectors_)
0027 throw cms::Exception("Configuration", "Bad number of GCT sectors");
0028 for (unsigned int iS = 0; iS < gctSectors_; ++iS) {
0029 auto linksEcal = sectorConfig[iS].getParameter<std::vector<int32_t>>("gctLinksEcal");
0030 auto linksHad = sectorConfig[iS].getParameter<std::vector<int32_t>>("gctLinksHad");
0031 if (linksEcal.size() != gctLinksEcal_ || linksHad.size() != gctLinksHad_)
0032 throw cms::Exception("Configuration", "Bad number of GCT links");
0033 unsigned int iLink = 0;
0034 for (unsigned int i = 0; i < gctLinksHad_; ++i, ++iLink) {
0035 if (linksHad[i] != -1)
0036 channelIdsInput_[l1t::demo::LinkId{"gct", iLink + 10 * iS}].push_back(linksHad[i]);
0037 }
0038 for (unsigned int i = 0; i < gctLinksEcal_; ++i) {
0039 if (linksEcal[i] != -1)
0040 channelIdsInput_[l1t::demo::LinkId{"gct", iLink + 10 * iS}].push_back(linksEcal[i]);
0041 }
0042 channelSpecsInput_["gct"] = {tmuxFactor_ * gctTimeslices_, 0};
0043 }
0044 }
0045 if (partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) {
0046 configTimeSlices(iConfig, "hgc", eventTemplate.raw.hgcalcluster.size(), hgcTimeslices_, hgcLinksFactor_);
0047 channelSpecsInput_["hgc"] = {tmuxFactor_ * hgcTimeslices_, hgcTimeslices_};
0048 }
0049 if (partition_ == Partition::Barrel || partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) {
0050 configTimeSlices(iConfig, "gmt", 1, gmtTimeslices_, gmtLinksFactor_);
0051 gmtNumberOfMuons_ = iConfig.getParameter<uint32_t>("gmtNumberOfMuons");
0052 channelSpecsInput_["gmt"] = {tmuxFactor_ * gmtTimeslices_,
0053 gmtTimeslices_ * nInputFramesPerBX_ * tmuxFactor_ - gmtNumberOfMuons_};
0054 }
0055 if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) {
0056 configTimeSlices(iConfig, "gtt", 1, gttTimeslices_, gttLinksFactor_);
0057 gttLatency_ = iConfig.getParameter<uint32_t>("gttLatency");
0058 gttNumberOfPVs_ = iConfig.getParameter<uint32_t>("gttNumberOfPVs");
0059 channelSpecsInput_["gtt"] = l1t::demo::ChannelSpec{tmuxFactor_, gttTimeslices_, gttLatency_};
0060 }
0061 inputFileWriter_ =
0062 std::make_unique<l1t::demo::BoardDataWriter>(l1t::demo::parseFileFormat(fileFormat_),
0063 iConfig.getParameter<std::string>("inputFileName"),
0064 nInputFramesPerBX_,
0065 tmuxFactor_,
0066 iConfig.getParameter<uint32_t>("maxLinesPerInputFile"),
0067 channelIdsInput_,
0068 channelSpecsInput_);
0069 }
0070
0071 if (writeOutputs_) {
0072 nOutputFramesPerBX_ = iConfig.getParameter<uint32_t>("nOutputFramesPerBX");
0073
0074 outputRegions_ = iConfig.getParameter<std::vector<uint32_t>>("outputRegions");
0075 outputLinksPuppi_ = iConfig.getParameter<std::vector<uint32_t>>("outputLinksPuppi");
0076 for (unsigned int i = 0; i < outputLinksPuppi_.size(); ++i) {
0077 channelIdsOutput_[l1t::demo::LinkId{"puppi", i}].push_back(outputLinksPuppi_[i]);
0078 }
0079 channelSpecsOutput_["puppi"] = {tmuxFactor_, 0};
0080 nPuppiFramesPerRegion_ = (nOutputFramesPerBX_ * tmuxFactor_) / outputRegions_.size();
0081 if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) {
0082 outputBoard_ = iConfig.getParameter<int32_t>("outputBoard");
0083 outputLinkEgamma_ = iConfig.getParameter<int32_t>("outputLinkEgamma");
0084 nEgammaObjectsOut_ = iConfig.getParameter<uint32_t>("nEgammaObjectsOut");
0085 if (outputLinkEgamma_ != -1) {
0086 channelIdsOutput_[l1t::demo::LinkId{"egamma", 0}].push_back(outputLinkEgamma_);
0087 channelSpecsOutput_["egamma"] = {tmuxFactor_, nOutputFramesPerBX_ * tmuxFactor_ - 3 * nEgammaObjectsOut_};
0088 }
0089 }
0090 if ((outputBoard_ == -1) != (outputLinkEgamma_ == -1)) {
0091 throw cms::Exception("Configuration", "Inconsistent configuration of outputLinkEgamma, outputBoard");
0092 }
0093 outputFileWriter_ =
0094 std::make_unique<l1t::demo::BoardDataWriter>(l1t::demo::parseFileFormat(fileFormat_),
0095 iConfig.getParameter<std::string>("outputFileName"),
0096 nOutputFramesPerBX_,
0097 tmuxFactor_,
0098 iConfig.getParameter<uint32_t>("maxLinesPerOutputFile"),
0099 channelIdsOutput_,
0100 channelSpecsOutput_);
0101 }
0102 }
0103
0104 L1TCorrelatorLayer1PatternFileWriter::~L1TCorrelatorLayer1PatternFileWriter() {}
0105
0106 void L1TCorrelatorLayer1PatternFileWriter::write(const l1ct::Event& event) {
0107 if (writeInputs_) {
0108 l1t::demo::EventData inputs;
0109 if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) {
0110 writeTF(event, inputs);
0111 }
0112 if (partition_ == Partition::Barrel) {
0113 writeBarrelGCT(event, inputs);
0114 }
0115 if (partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) {
0116 writeHGC(event, inputs);
0117 }
0118 if (partition_ == Partition::Barrel || partition_ == Partition::HGCal || partition_ == Partition::HGCalNoTk) {
0119 writeGMT(event, inputs);
0120 }
0121 if (partition_ == Partition::Barrel || partition_ == Partition::HGCal) {
0122 writeGTT(event, inputs);
0123 }
0124 inputFileWriter_->addEvent(inputs);
0125 }
0126
0127 if (writeOutputs_) {
0128 l1t::demo::EventData outputs;
0129 writePuppi(event, outputs);
0130 if (outputLinkEgamma_ != -1)
0131 writeEgamma(event, outputs);
0132 outputFileWriter_->addEvent(outputs);
0133 }
0134
0135 eventIndex_++;
0136 if (eventIndex_ % eventsPerFile_ == 0) {
0137 if (writeInputs_)
0138 inputFileWriter_->flush();
0139 if (writeOutputs_)
0140 outputFileWriter_->flush();
0141 }
0142 }
0143
0144 L1TCorrelatorLayer1PatternFileWriter::Partition L1TCorrelatorLayer1PatternFileWriter::parsePartition(
0145 const std::string& partition) {
0146 if (partition == "Barrel")
0147 return Partition::Barrel;
0148 if (partition == "HGCal")
0149 return Partition::HGCal;
0150 if (partition == "HGCalNoTk")
0151 return Partition::HGCalNoTk;
0152 if (partition == "HF")
0153 return Partition::HF;
0154 throw cms::Exception("Configuration", "Unsupported partition_ '" + partition + "'\n");
0155 }
0156
0157 void L1TCorrelatorLayer1PatternFileWriter::configTimeSlices(const edm::ParameterSet& iConfig,
0158 const std::string& prefix,
0159 unsigned int nSectors,
0160 unsigned int nTimeSlices,
0161 unsigned int linksFactor) {
0162 if (nTimeSlices > 1) {
0163 auto timeSliceConfig = iConfig.getParameter<std::vector<edm::ParameterSet>>(prefix + "TimeSlices");
0164 if (timeSliceConfig.size() != nTimeSlices)
0165 throw cms::Exception("Configuration")
0166 << "Mismatched number of " << prefix << "TimeSlices, expected " << nTimeSlices << std::endl;
0167 for (unsigned int iT = 0; iT < nTimeSlices; ++iT) {
0168 configSectors(timeSliceConfig[iT], prefix, nSectors, linksFactor);
0169 }
0170 } else {
0171 configSectors(iConfig, prefix, nSectors, linksFactor);
0172 }
0173 }
0174
0175 void L1TCorrelatorLayer1PatternFileWriter::configSectors(const edm::ParameterSet& iConfig,
0176 const std::string& prefix,
0177 unsigned int nSectors,
0178 unsigned int linksFactor) {
0179 if (nSectors > 1) {
0180 auto sectorConfig = iConfig.getParameter<std::vector<edm::ParameterSet>>(prefix + "Sectors");
0181 if (sectorConfig.size() != nSectors)
0182 throw cms::Exception("Configuration")
0183 << "Mismatched number of " << prefix << "Sectors, expected " << nSectors << std::endl;
0184 for (unsigned int iS = 0; iS < nSectors; ++iS) {
0185 configLinks(sectorConfig[iS], prefix, linksFactor, linksFactor > 1 ? iS * 10 : iS);
0186 }
0187 } else {
0188 configLinks(iConfig, prefix, linksFactor, 0);
0189 }
0190 }
0191 void L1TCorrelatorLayer1PatternFileWriter::configLinks(const edm::ParameterSet& iConfig,
0192 const std::string& prefix,
0193 unsigned int linksFactor,
0194 unsigned int offset) {
0195 if (linksFactor > 1) {
0196 auto links = iConfig.getParameter<std::vector<int32_t>>(prefix + "Links");
0197 if (links.size() != linksFactor)
0198 throw cms::Exception("Configuration")
0199 << "Mismatched number of " << prefix << "Links, expected " << linksFactor << std::endl;
0200 for (unsigned int i = 0; i < linksFactor; ++i) {
0201 if (links[i] != -1) {
0202 channelIdsInput_[l1t::demo::LinkId{prefix, i + offset}].push_back(links[i]);
0203 }
0204 }
0205 } else {
0206 auto link = iConfig.getParameter<int32_t>(prefix + "Link");
0207 if (link != -1) {
0208 channelIdsInput_[l1t::demo::LinkId{prefix, offset}].push_back(link);
0209 }
0210 }
0211 }
0212
0213 void L1TCorrelatorLayer1PatternFileWriter::writeTF(const l1ct::Event& event, l1t::demo::EventData& out) {
0214 for (unsigned int iS = 0, nS = event.raw.track.size(); iS < nS; ++iS) {
0215 l1t::demo::LinkId key{"tf", iS};
0216 if (channelIdsInput_.count(key) == 0)
0217 continue;
0218 std::vector<ap_uint<64>> ret;
0219 std::vector<ap_uint<96>> tracks = event.raw.track[iS].obj;
0220 if (tracks.empty())
0221 tracks.emplace_back(0);
0222 for (unsigned int i = 0, n = tracks.size(); i < n; ++i) {
0223 const ap_uint<96>& packedtk = tracks[i];
0224 if (i % 2 == 0) {
0225 ret.emplace_back(packedtk(63, 0));
0226 ret.emplace_back(0);
0227 ret.back()(31, 0) = packedtk(95, 64);
0228 } else {
0229 ret.back()(63, 32) = packedtk(31, 0);
0230 ret.emplace_back(packedtk(95, 32));
0231 }
0232 }
0233 out.add(key, ret);
0234 }
0235 }
0236
0237 void L1TCorrelatorLayer1PatternFileWriter::writeHGC(const l1ct::Event& event, l1t::demo::EventData& out) {
0238 assert(hgcLinksFactor_ == 4);
0239 std::vector<ap_uint<64>> ret[hgcLinksFactor_];
0240 for (unsigned int iS = 0, nS = event.raw.hgcalcluster.size(); iS < nS; ++iS) {
0241 l1t::demo::LinkId key0{"hgc", iS * 10};
0242 if (channelIdsInput_.count(key0) == 0)
0243 continue;
0244 for (unsigned int il = 0; il < hgcLinksFactor_; ++il) {
0245
0246 ret[il].resize(31);
0247 ap_uint<64>& head64 = ret[il][0];
0248 head64(63, 48) = 0xABC0;
0249 head64(47, 38) = 0;
0250 head64(39, 32) = (eventIndex_ % 3) * 6;
0251 head64(31, 24) = iS;
0252 head64(23, 16) = il;
0253 head64(15, 0) = eventIndex_ % 3564;
0254 for (unsigned int j = 0; j < 30; ++j) {
0255 ret[il][j + 1] = 4 * j + il;
0256 }
0257 }
0258 for (auto clust : event.raw.hgcalcluster[iS].obj) {
0259 for (unsigned int il = 0; il < hgcLinksFactor_; ++il) {
0260 ret[il].push_back(clust(64 * il + 63, 64 * il));
0261 }
0262 }
0263 for (unsigned int il = 0; il < hgcLinksFactor_; ++il) {
0264 out.add(l1t::demo::LinkId{"hgc", iS * 10 + il}, ret[il]);
0265 }
0266 }
0267 }
0268
0269 void L1TCorrelatorLayer1PatternFileWriter::writeBarrelGCT(const l1ct::Event& event, l1t::demo::EventData& out) {
0270 std::vector<ap_uint<64>> ret;
0271 for (unsigned int iS = 0; iS < gctSectors_; ++iS) {
0272 l1t::demo::LinkId key0{"gct", iS * 10};
0273 if (channelIdsInput_.count(key0) == 0)
0274 continue;
0275 const auto& had = event.decoded.hadcalo[iS];
0276 const auto& ecal = event.decoded.emcalo[iS];
0277 unsigned int iLink = 0, nHad = had.size(), nEcal = ecal.size();
0278 for (unsigned int i = 0; i < gctLinksHad_; ++i, ++iLink) {
0279 ret.clear();
0280 for (unsigned int iHad = i; iHad < nHad; iHad += gctLinksHad_) {
0281 ret.emplace_back(had[iHad].pack());
0282 }
0283 if (ret.empty())
0284 ret.emplace_back(0);
0285 out.add(l1t::demo::LinkId{"gct", iS * 10 + iLink}, ret);
0286 }
0287 for (unsigned int i = 0; i < gctLinksEcal_; ++i, ++iLink) {
0288 ret.clear();
0289 for (unsigned int iEcal = i; iEcal < nEcal; iEcal += gctLinksEcal_) {
0290 ret.emplace_back(ecal[iEcal].pack());
0291 }
0292 if (ret.empty())
0293 ret.emplace_back(0);
0294 out.add(l1t::demo::LinkId{"gct", iS * 10 + iLink}, ret);
0295 }
0296 }
0297 }
0298
0299 void L1TCorrelatorLayer1PatternFileWriter::writeGMT(const l1ct::Event& event, l1t::demo::EventData& out) {
0300 l1t::demo::LinkId key{"gmt", 0};
0301 if (channelIdsInput_.count(key) == 0)
0302 return;
0303 std::vector<ap_uint<64>> muons = event.raw.muon.obj;
0304 muons.resize(gmtNumberOfMuons_, ap_uint<64>(0));
0305 out.add(key, muons);
0306 }
0307
0308 void L1TCorrelatorLayer1PatternFileWriter::writeGTT(const l1ct::Event& event, l1t::demo::EventData& out) {
0309 l1t::demo::LinkId key{"gtt", 0};
0310 if (channelIdsInput_.count(key) == 0)
0311 return;
0312 std::vector<ap_uint<64>> pvs = event.pvs_emu;
0313 pvs.resize(gttNumberOfPVs_, ap_uint<64>(0));
0314 out.add(key, pvs);
0315 }
0316
0317 void L1TCorrelatorLayer1PatternFileWriter::writePuppi(const l1ct::Event& event, l1t::demo::EventData& out) {
0318 unsigned int n = outputLinksPuppi_.size();
0319 std::vector<std::vector<ap_uint<64>>> links(n);
0320 for (auto ir : outputRegions_) {
0321 auto puppi = event.out[ir].puppi;
0322 unsigned int npuppi = puppi.size();
0323 for (unsigned int i = 0; i < n * nPuppiFramesPerRegion_; ++i) {
0324 links[i / nPuppiFramesPerRegion_].push_back(i < npuppi ? puppi[i].pack() : ap_uint<l1ct::PuppiObj::BITWIDTH>(0));
0325 }
0326 }
0327 for (unsigned int i = 0; i < n; ++i) {
0328 out.add(l1t::demo::LinkId{"puppi", i}, links[i]);
0329 }
0330 }
0331
0332 void L1TCorrelatorLayer1PatternFileWriter::writeEgamma(const l1ct::Event& event, l1t::demo::EventData& out) {
0333 std::vector<ap_uint<64>> ret;
0334 const auto& pho = event.board_out[outputBoard_].egphoton;
0335 const auto& ele = event.board_out[outputBoard_].egelectron;
0336 ret.reserve(3 * nEgammaObjectsOut_);
0337 for (const auto& p : pho) {
0338 ret.emplace_back(p.pack());
0339 }
0340 ret.resize(nEgammaObjectsOut_, ap_uint<64>(0));
0341 for (const auto& p : ele) {
0342 ap_uint<128> dword = p.pack();
0343 ret.push_back(dword(63, 0));
0344 ret.push_back(dword(127, 64));
0345 }
0346 ret.resize(3 * nEgammaObjectsOut_, ap_uint<64>(0));
0347 out.add(l1t::demo::LinkId{"egamma", 0}, ret);
0348 }
0349
0350 void L1TCorrelatorLayer1PatternFileWriter::flush() {
0351 if (inputFileWriter_)
0352 inputFileWriter_->flush();
0353 if (outputFileWriter_)
0354 outputFileWriter_->flush();
0355 }