Back to home page

Project CMSSW displayed by LXR

 
 

    


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);  // this piece of code won't really work otherwise
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       // put header word and (dummy) towers
0246       ret[il].resize(31);
0247       ap_uint<64>& head64 = ret[il][0];
0248       head64(63, 48) = 0xABC0;                 // Magic
0249       head64(47, 38) = 0;                      // Opaque
0250       head64(39, 32) = (eventIndex_ % 3) * 6;  // TM slice
0251       head64(31, 24) = iS;                     // Sector
0252       head64(23, 16) = il;                     // link
0253       head64(15, 0) = eventIndex_ % 3564;      // BX
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 }