Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:21:32

0001 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/buffered_folded_multififo_regionizer_ref.h"
0002 
0003 #include <iostream>
0004 #include <memory>
0005 
0006 #ifdef CMSSW_GIT_HASH
0007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0009 
0010 l1ct::BufferedFoldedMultififoRegionizerEmulator::BufferedFoldedMultififoRegionizerEmulator(
0011     const edm::ParameterSet& iConfig)
0012     : BufferedFoldedMultififoRegionizerEmulator(iConfig.getParameter<uint32_t>("nClocks"),
0013                                                 iConfig.getParameter<uint32_t>("nTrack"),
0014                                                 iConfig.getParameter<uint32_t>("nCalo"),
0015                                                 iConfig.getParameter<uint32_t>("nEmCalo"),
0016                                                 iConfig.getParameter<uint32_t>("nMu"),
0017                                                 /*streaming=*/true,
0018                                                 /*outii=*/6,
0019                                                 /*pauseii=*/3,
0020                                                 iConfig.getParameter<bool>("useAlsoVtxCoords")) {
0021   debug_ = iConfig.getUntrackedParameter<bool>("debug");
0022   if (iConfig.existsAs<edm::ParameterSet>("egInterceptMode")) {
0023     const auto& emSelCfg = iConfig.getParameter<edm::ParameterSet>("egInterceptMode");
0024     setEgInterceptMode(emSelCfg.getParameter<bool>("afterFifo"), emSelCfg);
0025   }
0026 }
0027 
0028 edm::ParameterSetDescription l1ct::BufferedFoldedMultififoRegionizerEmulator::getParameterSetDescription() {
0029   edm::ParameterSetDescription description;
0030   description.add<uint32_t>("nClocks", 162);
0031   description.add<uint32_t>("nTrack", 30);
0032   description.add<uint32_t>("nCalo", 20);
0033   description.add<uint32_t>("nEmCalo", 10);
0034   description.add<uint32_t>("nMu", 4);
0035   edm::ParameterSetDescription egIntercept = l1ct::EGInputSelectorEmuConfig::getParameterSetDescription();
0036   egIntercept.add<bool>("afterFifo", true);
0037   description.addOptional<edm::ParameterSetDescription>("egInterceptMode", egIntercept);
0038   description.add<bool>("useAlsoVtxCoords", true);
0039   description.addUntracked<bool>("debug", false);
0040   return description;
0041 }
0042 #endif
0043 
0044 l1ct::BufferedFoldedMultififoRegionizerEmulator::BufferedFoldedMultififoRegionizerEmulator(unsigned int nclocks,
0045                                                                                            unsigned int ntk,
0046                                                                                            unsigned int ncalo,
0047                                                                                            unsigned int nem,
0048                                                                                            unsigned int nmu,
0049                                                                                            bool streaming,
0050                                                                                            unsigned int outii,
0051                                                                                            unsigned int pauseii,
0052                                                                                            bool useAlsoVtxCoords)
0053     : FoldedMultififoRegionizerEmulator(nclocks,
0054                                         /*NTK_LINKS*/ 1,
0055                                         /*NCALO_LINKS*/ 1,
0056                                         ntk,
0057                                         ncalo,
0058                                         nem,
0059                                         nmu,
0060                                         streaming,
0061                                         outii,
0062                                         pauseii,
0063                                         useAlsoVtxCoords),
0064       tkBuffers_(ntk ? 2 * NTK_SECTORS : 0),
0065       caloBuffers_(ncalo ? 2 * NCALO_SECTORS : 0),
0066       muBuffers_(nmu ? 2 : 0) {}
0067 
0068 l1ct::BufferedFoldedMultififoRegionizerEmulator::~BufferedFoldedMultififoRegionizerEmulator() {}
0069 
0070 void l1ct::BufferedFoldedMultififoRegionizerEmulator::findEtaBounds_(const l1ct::PFRegionEmu& sec,
0071                                                                      const std::vector<PFInputRegion>& reg,
0072                                                                      l1ct::glbeta_t& etaMin,
0073                                                                      l1ct::glbeta_t& etaMax) {
0074   etaMin = reg[0].region.hwEtaCenter - reg[0].region.hwEtaHalfWidth - reg[0].region.hwEtaExtra - sec.hwEtaCenter;
0075   etaMax = reg[0].region.hwEtaCenter + reg[0].region.hwEtaHalfWidth + reg[0].region.hwEtaExtra - sec.hwEtaCenter;
0076   for (const auto& r : reg) {
0077     etaMin = std::min<l1ct::glbeta_t>(
0078         etaMin, r.region.hwEtaCenter - r.region.hwEtaHalfWidth - r.region.hwEtaExtra - sec.hwEtaCenter);
0079     etaMax = std::max<l1ct::glbeta_t>(
0080         etaMax, r.region.hwEtaCenter + r.region.hwEtaHalfWidth + r.region.hwEtaExtra - sec.hwEtaCenter);
0081   }
0082 }
0083 void l1ct::BufferedFoldedMultififoRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedInputs& in,
0084                                                                             const std::vector<PFInputRegion>& out) {
0085   assert(!init_);
0086   FoldedMultififoRegionizerEmulator::initSectorsAndRegions(in, out);
0087   for (int ie = 0; ie < 2; ++ie) {
0088     l1ct::glbeta_t etaMin, etaMax;
0089     findEtaBounds_(fold_[ie].sectors.track[0].region, fold_[ie].regions, etaMin, etaMax);
0090     for (unsigned int isec = 0; ntk_ > 0 && isec < NTK_SECTORS; ++isec) {
0091       tkBuffers_[2 * isec + ie] =
0092           l1ct::multififo_regionizer::EtaPhiBuffer<l1ct::TkObjEmu>(nclocks_ / 2, etaMin, etaMax);
0093     }
0094     findEtaBounds_(fold_[ie].sectors.hadcalo[0].region, fold_[ie].regions, etaMin, etaMax);
0095     for (unsigned int isec = 0; ncalo_ > 0 && isec < NCALO_SECTORS; ++isec) {
0096       caloBuffers_[2 * isec + ie] =
0097           l1ct::multififo_regionizer::EtaPhiBuffer<l1ct::HadCaloObjEmu>(nclocks_ / 2, etaMin, etaMax);
0098     }
0099     findEtaBounds_(fold_[ie].sectors.muon.region, fold_[ie].regions, etaMin, etaMax);
0100     if (nmu_ > 0) {
0101       muBuffers_[ie] = l1ct::multififo_regionizer::EtaPhiBuffer<l1ct::MuObjEmu>(nclocks_ / 2, etaMin, etaMax);
0102     }
0103   }
0104 }
0105 
0106 template <typename T>
0107 void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinksPosNeg_(
0108     unsigned int iclock,
0109     const std::vector<l1ct::DetectorSector<T>>& secNeg,
0110     const std::vector<l1ct::DetectorSector<T>>& secPos,
0111     std::vector<T>& links,
0112     std::vector<bool>& valid) {
0113   unsigned int nlinks = secNeg.size();
0114   links.resize(2 * nlinks);
0115   valid.resize(2 * nlinks);
0116   for (unsigned int isec = 0, ilink = 0; isec < nlinks; ++isec) {
0117     for (int ec = 0; ec < 2; ++ec, ++ilink) {
0118       const l1ct::DetectorSector<T>& sec = (ec ? secPos : secNeg)[isec];
0119       if (iclock < sec.size() && iclock < nclocks_ - 1) {
0120         valid[ilink] = true;
0121         links[ilink] = sec.obj[iclock];
0122       } else {
0123         valid[ilink] = false;
0124         links[ilink].clear();
0125       }
0126     }
0127   }
0128 }
0129 void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinks(unsigned int iclock,
0130                                                                 std::vector<l1ct::TkObjEmu>& links,
0131                                                                 std::vector<bool>& valid) {
0132   if (ntk_)
0133     fillLinksPosNeg_(iclock, fold_[0].sectors.track, fold_[1].sectors.track, links, valid);
0134 }
0135 
0136 void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinks(unsigned int iclock,
0137                                                                 std::vector<l1ct::HadCaloObjEmu>& links,
0138                                                                 std::vector<bool>& valid) {
0139   if (ncalo_)
0140     fillLinksPosNeg_(iclock, fold_[0].sectors.hadcalo, fold_[1].sectors.hadcalo, links, valid);
0141 }
0142 void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinks(unsigned int iclock,
0143                                                                 std::vector<l1ct::EmCaloObjEmu>& links,
0144                                                                 std::vector<bool>& valid) {
0145   // nothing to do normally
0146 }
0147 
0148 void l1ct::BufferedFoldedMultififoRegionizerEmulator::fillLinks(unsigned int iclock,
0149                                                                 std::vector<l1ct::MuObjEmu>& links,
0150                                                                 std::vector<bool>& valid) {
0151   if (nmu_ == 0)
0152     return;
0153   assert(NMU_LINKS == 1);
0154   links.resize(NMU_LINKS);
0155   valid.resize(links.size());
0156   const auto& in = fold_.front().sectors.muon.obj;
0157   if (iclock < in.size() && iclock < nclocks_ - 1) {
0158     links[0] = in[iclock];
0159     valid[0] = true;
0160   } else {
0161     links[0].clear();
0162     valid[0] = false;
0163   }
0164 }
0165 
0166 bool l1ct::BufferedFoldedMultififoRegionizerEmulator::step(bool newEvent,
0167                                                            const std::vector<l1ct::TkObjEmu>& links_tk,
0168                                                            const std::vector<l1ct::HadCaloObjEmu>& links_hadCalo,
0169                                                            const std::vector<l1ct::EmCaloObjEmu>& links_emCalo,
0170                                                            const std::vector<l1ct::MuObjEmu>& links_mu,
0171                                                            std::vector<l1ct::TkObjEmu>& out_tk,
0172                                                            std::vector<l1ct::HadCaloObjEmu>& out_hadCalo,
0173                                                            std::vector<l1ct::EmCaloObjEmu>& out_emCalo,
0174                                                            std::vector<l1ct::MuObjEmu>& out_mu,
0175                                                            bool mux) {
0176   iclock_ = (newEvent ? 0 : iclock_ + 1);
0177   int ifold = (iclock_ / clocksPerFold_);
0178   bool newSubEvent = iclock_ % clocksPerFold_ == 0;
0179 
0180   if (newEvent) {
0181     for (auto& b : tkBuffers_)
0182       b.writeNewEvent();
0183     for (auto& b : caloBuffers_)
0184       b.writeNewEvent();
0185     for (auto& b : muBuffers_)
0186       b.writeNewEvent();
0187   }
0188 
0189   assert(links_tk.size() == tkBuffers_.size() || ntk_ == 0);
0190   for (unsigned int i = 0; ntk_ > 0 && i < 2 * NTK_SECTORS; ++i) {
0191     tkBuffers_[i].maybe_push(links_tk[i]);
0192   }
0193   assert(links_hadCalo.size() == caloBuffers_.size() || ncalo_ == 0);
0194   for (unsigned int i = 0; ncalo_ > 0 && i < 2 * NCALO_SECTORS; ++i) {
0195     caloBuffers_[i].maybe_push(links_hadCalo[i]);
0196   }
0197   for (unsigned int i = 0; nmu_ > 0 && i < 2; ++i) {
0198     muBuffers_[i].maybe_push(links_mu[0]);
0199   }
0200   if (newSubEvent && !newEvent) {
0201     for (auto& b : tkBuffers_)
0202       b.readNewEvent();
0203     for (auto& b : caloBuffers_)
0204       b.readNewEvent();
0205     for (auto& b : muBuffers_)
0206       b.readNewEvent();
0207   }
0208   std::vector<l1ct::TkObjEmu> mylinks_tk(ntk_ ? NTK_SECTORS : 0);
0209   std::vector<l1ct::HadCaloObjEmu> mylinks_hadCalo(ncalo_ ? NCALO_SECTORS : 0);
0210   std::vector<l1ct::EmCaloObjEmu> mylinks_emCalo(0);
0211   std::vector<l1ct::MuObjEmu> mylinks_mu(nmu_ ? 1 : 0);
0212   for (unsigned int i = 0, ib = 1 - ifold; ntk_ > 0 && i < NTK_SECTORS; ++i, ib += 2) {
0213     mylinks_tk[i] = tkBuffers_[ib].pop();
0214   }
0215   for (unsigned int i = 0, ib = 1 - ifold; ncalo_ > 0 && i < NCALO_SECTORS; ++i, ib += 2) {
0216     mylinks_hadCalo[i] = caloBuffers_[ib].pop();
0217   }
0218   if (nmu_) {
0219     mylinks_mu[0] = muBuffers_[1 - ifold].pop();
0220   }
0221 
0222   bool ret = false;
0223   if (!mux) {
0224     Fold& f = fold_[1 - ifold];
0225     ret = f.regionizer->step(newSubEvent,
0226                              mylinks_tk,
0227                              mylinks_hadCalo,
0228                              mylinks_emCalo,
0229                              mylinks_mu,
0230                              out_tk,
0231                              out_hadCalo,
0232                              out_emCalo,
0233                              out_mu,
0234                              false);
0235   } else {
0236     unsigned int inputFold = 1 - ifold;
0237     unsigned int outputFold = ifold;
0238     std::vector<l1ct::TkObjEmu> nolinks_tk(mylinks_tk.size());
0239     std::vector<l1ct::HadCaloObjEmu> nolinks_hadCalo(mylinks_hadCalo.size());
0240     std::vector<l1ct::EmCaloObjEmu> nolinks_emCalo(mylinks_emCalo.size());
0241     std::vector<l1ct::MuObjEmu> nolinks_mu(mylinks_mu.size());
0242     std::vector<l1ct::TkObjEmu> noout_tk;
0243     std::vector<l1ct::HadCaloObjEmu> noout_hadCalo;
0244     std::vector<l1ct::EmCaloObjEmu> noout_emCalo;
0245     std::vector<l1ct::MuObjEmu> noout_mu;
0246     for (auto& f : fold_) {
0247       bool fret = f.regionizer->step(newSubEvent,
0248                                      f.index == inputFold ? mylinks_tk : nolinks_tk,
0249                                      f.index == inputFold ? mylinks_hadCalo : nolinks_hadCalo,
0250                                      f.index == inputFold ? mylinks_emCalo : nolinks_emCalo,
0251                                      f.index == inputFold ? mylinks_mu : nolinks_mu,
0252                                      f.index == outputFold ? out_tk : noout_tk,
0253                                      f.index == outputFold ? out_hadCalo : noout_hadCalo,
0254                                      f.index == outputFold ? out_emCalo : noout_emCalo,
0255                                      f.index == outputFold ? out_mu : noout_mu,
0256                                      true);
0257       if (f.index == outputFold)
0258         ret = fret;
0259     }
0260   }
0261   return ret;
0262 }
0263 
0264 void l1ct::BufferedFoldedMultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in,
0265                                                           std::vector<PFInputRegion>& out) {
0266   if (!init_)
0267     initSectorsAndRegions(in, out);
0268   else {
0269     fillEvent(in);
0270     for (auto& f : fold_)
0271       f.regionizer->reset();
0272   }
0273 
0274   std::vector<l1ct::TkObjEmu> tk_links_in, tk_out;
0275   std::vector<l1ct::EmCaloObjEmu> em_links_in, em_out;
0276   std::vector<l1ct::HadCaloObjEmu> calo_links_in, calo_out;
0277   std::vector<l1ct::MuObjEmu> mu_links_in, mu_out;
0278 
0279   // read and sort the inputs
0280   std::vector<bool> unused;
0281   for (unsigned int iclock = 0; iclock < nclocks_; ++iclock) {
0282     fillLinks(iclock, tk_links_in, unused);
0283     fillLinks(iclock, em_links_in, unused);
0284     fillLinks(iclock, calo_links_in, unused);
0285     fillLinks(iclock, mu_links_in, unused);
0286 
0287     bool newevt = (iclock == 0), mux = true;
0288     step(newevt, tk_links_in, calo_links_in, em_links_in, mu_links_in, tk_out, calo_out, em_out, mu_out, mux);
0289   }
0290 
0291   // set up an empty event
0292   for (auto& l : tk_links_in)
0293     l.clear();
0294   for (auto& l : em_links_in)
0295     l.clear();
0296   for (auto& l : calo_links_in)
0297     l.clear();
0298   for (auto& l : mu_links_in)
0299     l.clear();
0300 
0301   // read and put the inputs in the regions
0302   assert(out.size() == nregions_);
0303   for (unsigned int iclock = 0; iclock < nclocks_; ++iclock) {
0304     bool newevt = (iclock == 0), mux = true;
0305     step(newevt, tk_links_in, calo_links_in, em_links_in, mu_links_in, tk_out, calo_out, em_out, mu_out, mux);
0306 
0307     unsigned int ireg = iclock / (outii_ + pauseii_);
0308     if ((iclock % (outii_ + pauseii_)) >= outii_)
0309       continue;
0310     if (ireg >= nregions_)
0311       break;
0312 
0313     if (streaming_) {
0314       Fold& f = fold_[whichFold(iclock)];
0315       f.regionizer->destream(iclock % clocksPerFold_, tk_out, em_out, calo_out, mu_out, out[ireg]);
0316     } else {
0317       if (iclock % (outii_ + pauseii_) == 0) {
0318         out[ireg].track = tk_out;
0319         out[ireg].emcalo = em_out;
0320         out[ireg].hadcalo = calo_out;
0321         out[ireg].muon = mu_out;
0322       }
0323     }
0324   }
0325 
0326   for (auto& f : fold_)
0327     f.regionizer->reset();
0328 }