Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-10-01 01:02:15

0001 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_ref.h"
0002 #include "L1Trigger/Phase2L1ParticleFlow/interface/egamma/pfeginput_ref.h"
0003 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/multififo_regionizer_elements_ref.icc"
0004 
0005 #include <iostream>
0006 #include <memory>
0007 
0008 #ifdef CMSSW_GIT_HASH
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 
0011 l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(const edm::ParameterSet& iConfig)
0012     : MultififoRegionizerEmulator(iConfig.getParameter<uint32_t>("nEndcaps"),
0013                                   iConfig.getParameter<uint32_t>("nClocks"),
0014                                   iConfig.getParameter<uint32_t>("nTrack"),
0015                                   iConfig.getParameter<uint32_t>("nCalo"),
0016                                   iConfig.getParameter<uint32_t>("nEmCalo"),
0017                                   iConfig.getParameter<uint32_t>("nMu"),
0018                                   /*streaming=*/false,
0019                                   /*outii=*/1,
0020                                   iConfig.getParameter<bool>("useAlsoVtxCoords")) {
0021   debug_ = iConfig.getUntrackedParameter<bool>("debug", false);
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 #endif
0028 
0029 l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(unsigned int nendcaps,
0030                                                                unsigned int nclocks,
0031                                                                unsigned int ntk,
0032                                                                unsigned int ncalo,
0033                                                                unsigned int nem,
0034                                                                unsigned int nmu,
0035                                                                bool streaming,
0036                                                                unsigned int outii,
0037                                                                bool useAlsoVtxCoords)
0038     : RegionizerEmulator(useAlsoVtxCoords),
0039       NTK_SECTORS(9),
0040       NCALO_SECTORS(3),
0041       NTK_LINKS(2),
0042       NCALO_LINKS(3),
0043       HCAL_LINKS(0),
0044       ECAL_LINKS(0),
0045       NMU_LINKS(1),
0046       nendcaps_(nendcaps),
0047       nclocks_(nclocks),
0048       ntk_(ntk),
0049       ncalo_(ncalo),
0050       nem_(nem),
0051       nmu_(nmu),
0052       outii_(outii),
0053       pauseii_(0),
0054       streaming_(streaming),
0055       emInterceptMode_(noIntercept),
0056       init_(false),
0057       tkRegionizer_(ntk, streaming ? (ntk + outii - 1) / outii : ntk, streaming, outii, 0, useAlsoVtxCoords),
0058       hadCaloRegionizer_(ncalo, streaming ? (ncalo + outii - 1) / outii : ncalo, streaming, outii, 0),
0059       emCaloRegionizer_(nem, streaming ? (nem + outii - 1) / outii : nem, streaming, outii, 0),
0060       muRegionizer_(nmu, streaming ? std::max(1u, (nmu + outii - 1) / outii) : nmu, streaming, outii, 0) {
0061   // now we initialize the routes: track finder
0062   for (unsigned int ie = 0; ie < nendcaps && ntk > 0; ++ie) {
0063     for (unsigned int is = 0; is < NTK_SECTORS; ++is) {  // 9 tf sectors
0064       for (unsigned int il = 0; il < NTK_LINKS; ++il) {  // max tracks per sector per clock
0065         unsigned int isp = (is + 1) % NTK_SECTORS, ism = (is + NTK_SECTORS - 1) % NTK_SECTORS;
0066         tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, is + NTK_SECTORS * ie, il);
0067         tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, isp + NTK_SECTORS * ie, il + 2);
0068         tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, ism + NTK_SECTORS * ie, il + 4);
0069       }
0070     }
0071   }
0072   // hgcal
0073   assert(NCALO_SECTORS == 3 && NTK_SECTORS == 9);  // otherwise math below is broken, but it's hard to make it generic
0074   for (unsigned int ie = 0; ie < nendcaps; ++ie) {
0075     for (unsigned int is = 0; is < NCALO_SECTORS; ++is) {                      // NCALO_SECTORS sectors
0076       for (unsigned int il = 0; il < NCALO_LINKS; ++il) {                      // max clusters per sector per clock
0077         for (unsigned int j = 0; j < 3; ++j) {                                 // PF REGION
0078           caloRoutes_.emplace_back(is + 3 * ie, il, 3 * is + j + 9 * ie, il);  // 4 args are: sector, link, region, fifo
0079           if (j != 2) {  // pf regions 0 and 1 take also from previous sector
0080             int isprev = (is > 0 ? is - 1 : NCALO_SECTORS - 1);
0081             caloRoutes_.emplace_back(isprev + 3 * ie, il, 3 * is + j + 9 * ie, il + NCALO_LINKS);
0082           }
0083         }
0084       }
0085     }
0086   }
0087   emCaloRoutes_ = caloRoutes_;  // in the endcaps there's only one calo
0088   // mu
0089   for (unsigned int il = 0; il < NMU_LINKS && nmu > 0; ++il) {  // max clusters per sector per clock
0090     for (unsigned int j = 0; j < NTK_SECTORS * nendcaps; ++j) {
0091       muRoutes_.emplace_back(0, il, j, il);
0092     }
0093   }
0094 }
0095 
0096 l1ct::MultififoRegionizerEmulator::MultififoRegionizerEmulator(BarrelSetup barrelSetup,
0097                                                                unsigned int nHCalLinks,
0098                                                                unsigned int nECalLinks,
0099                                                                unsigned int nclocks,
0100                                                                unsigned int ntk,
0101                                                                unsigned int ncalo,
0102                                                                unsigned int nem,
0103                                                                unsigned int nmu,
0104                                                                bool streaming,
0105                                                                unsigned int outii,
0106                                                                unsigned int pauseii,
0107                                                                bool useAlsoVtxCoords)
0108     : RegionizerEmulator(useAlsoVtxCoords),
0109       NTK_SECTORS((barrelSetup == BarrelSetup::Phi18 || barrelSetup == BarrelSetup::Phi9) ? 5 : 9),
0110       NCALO_SECTORS((barrelSetup == BarrelSetup::Phi18 || barrelSetup == BarrelSetup::Phi9) ? 2 : 3),
0111       NTK_LINKS(2),
0112       NCALO_LINKS(2),
0113       HCAL_LINKS(nHCalLinks),
0114       ECAL_LINKS(nECalLinks),
0115       NMU_LINKS(1),
0116       nendcaps_(0),
0117       nclocks_(nclocks),
0118       ntk_(ntk),
0119       ncalo_(ncalo),
0120       nem_(nem),
0121       nmu_(nmu),
0122       outii_(outii),
0123       pauseii_(pauseii),
0124       streaming_(streaming),
0125       emInterceptMode_(noIntercept),
0126       init_(false),
0127       tkRegionizer_(ntk, streaming ? (ntk + outii - 1) / outii : ntk, streaming, outii, pauseii, useAlsoVtxCoords),
0128       hadCaloRegionizer_(ncalo, streaming ? (ncalo + outii - 1) / outii : ncalo, streaming, outii, pauseii),
0129       emCaloRegionizer_(nem, streaming ? (nem + outii - 1) / outii : nem, streaming, outii, pauseii),
0130       muRegionizer_(nmu, streaming ? std::max(1u, (nmu + outii - 1) / outii) : nmu, streaming, outii, pauseii) {
0131   unsigned int nendcaps = 2, etaslices = 0;
0132   switch (barrelSetup) {
0133     case BarrelSetup::Full54:
0134       nregions_ = 54;
0135       etaslices = 6;
0136       break;
0137     case BarrelSetup::Full27:
0138       nregions_ = 27;
0139       etaslices = 3;
0140       break;
0141     case BarrelSetup::Central18:
0142       nregions_ = 18;
0143       etaslices = 2;
0144       break;
0145     case BarrelSetup::Central9:
0146       nregions_ = 9;
0147       etaslices = 1;
0148       break;
0149     case BarrelSetup::Phi18:
0150       nregions_ = 18;
0151       etaslices = 6;
0152       break;
0153     case BarrelSetup::Phi9:
0154       nregions_ = 9;
0155       etaslices = 3;
0156       break;
0157   }
0158   unsigned int phisectors = nregions_ / etaslices;
0159   // now we initialize the routes: track finder
0160   for (unsigned int ietaslice = 0; ietaslice < etaslices && ntk > 0; ++ietaslice) {
0161     for (unsigned int ie = 0; ie < nendcaps; ++ie) {  // 0 = negative, 1 = positive
0162       unsigned int nTFEtaSlices = 1;
0163       if (etaslices == 3) {
0164         if (ietaslice == 0 && ie == 1)
0165           continue;
0166         if (ietaslice == 2 && ie == 0)
0167           continue;
0168         if (ietaslice == 1)
0169           nTFEtaSlices = 2;
0170       } else if (etaslices == 6) {
0171         if (ietaslice <= 1 && ie == 1)
0172           continue;
0173         if (ietaslice >= 4 && ie == 0)
0174           continue;
0175         if (ietaslice == 2 || ietaslice == 3)
0176           nTFEtaSlices = 2;
0177       } else if (barrelSetup == BarrelSetup::Central18 || barrelSetup == BarrelSetup::Central9) {
0178         nTFEtaSlices = 2;
0179       }
0180       unsigned int ireg0 = phisectors * ietaslice, il0 = 6 * (nTFEtaSlices - 1) * ie;
0181       if (barrelSetup == BarrelSetup::Phi18 || barrelSetup == BarrelSetup::Phi9) {
0182         for (unsigned int iregphi = 0; iregphi < (nregions_ / etaslices); ++iregphi) {
0183           for (unsigned int il = 0; il < NTK_LINKS; ++il) {
0184             tkRoutes_.emplace_back((iregphi + 1) + NTK_SECTORS * ie, il, iregphi + ireg0, il0 + il);
0185             tkRoutes_.emplace_back((iregphi + 0) + NTK_SECTORS * ie, il, iregphi + ireg0, il0 + il + 2);
0186             tkRoutes_.emplace_back((iregphi + 2) + NTK_SECTORS * ie, il, iregphi + ireg0, il0 + il + 4);
0187           }
0188         }
0189       } else {
0190         for (unsigned int is = 0; is < NTK_SECTORS; ++is) {  // 9 tf sectors
0191           for (unsigned int il = 0; il < NTK_LINKS; ++il) {  // max tracks per sector per clock
0192             unsigned int isp = (is + 1) % NTK_SECTORS, ism = (is + NTK_SECTORS - 1) % NTK_SECTORS;
0193             tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, is + ireg0, il0 + il);
0194             tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, isp + ireg0, il0 + il + 2);
0195             tkRoutes_.emplace_back(is + NTK_SECTORS * ie, il, ism + ireg0, il0 + il + 4);
0196           }
0197         }
0198       }
0199     }
0200   }
0201   // calo
0202   unsigned int calo_sectors_to_loop = NCALO_SECTORS;
0203   if (barrelSetup == BarrelSetup::Phi18 || barrelSetup == BarrelSetup::Phi9) {
0204     calo_sectors_to_loop = 1;
0205     assert(NCALO_SECTORS == 2 && NTK_SECTORS == 5);  // otherwise math below is broken, but it's hard to make it generic
0206   } else {
0207     assert(NCALO_SECTORS == 3 && NTK_SECTORS == 9);  // otherwise math below is broken, but it's hard to make it generic
0208   }
0209   for (unsigned int ie = 0; ie < etaslices; ++ie) {
0210     for (unsigned int is = 0; is < calo_sectors_to_loop; ++is) {  // NCALO_SECTORS sectors
0211       for (unsigned int j = 0; j < 3; ++j) {                      // 3 regions x sector
0212         for (unsigned int il = 0; il < HCAL_LINKS; ++il) {
0213           caloRoutes_.emplace_back(is, il, 3 * is + j + phisectors * ie, il);
0214           if (j) {
0215             caloRoutes_.emplace_back((is + 1) % 3, il, 3 * is + j + phisectors * ie, il + HCAL_LINKS);
0216           }
0217         }
0218         for (unsigned int il = 0; il < ECAL_LINKS; ++il) {
0219           emCaloRoutes_.emplace_back(is, il, 3 * is + j + phisectors * ie, il);
0220           if (j) {
0221             emCaloRoutes_.emplace_back((is + 1) % 3, il, 3 * is + j + phisectors * ie, il + ECAL_LINKS);
0222           }
0223         }
0224       }
0225     }
0226   }
0227   // mu
0228   for (unsigned int il = 0; il < NMU_LINKS && nmu > 0; ++il) {
0229     for (unsigned int j = 0; j < nregions_; ++j) {
0230       muRoutes_.emplace_back(0, il, j, il);
0231     }
0232   }
0233 }
0234 
0235 l1ct::MultififoRegionizerEmulator::~MultififoRegionizerEmulator() {}
0236 
0237 void l1ct::MultififoRegionizerEmulator::setEgInterceptMode(bool afterFifo,
0238                                                            const l1ct::EGInputSelectorEmuConfig& interceptorConfig) {
0239   emInterceptMode_ = afterFifo ? interceptPostFifo : interceptPreFifo;
0240   interceptor_ = std::make_unique<EGInputSelectorEmulator>(interceptorConfig);
0241 }
0242 
0243 void l1ct::MultififoRegionizerEmulator::initSectorsAndRegions(const RegionizerDecodedInputs& in,
0244                                                               const std::vector<PFInputRegion>& out) {
0245   assert(!init_);
0246   init_ = true;
0247   if (nendcaps_ > 0) {
0248     assert(out.size() == NTK_SECTORS * nendcaps_);
0249   } else {
0250     assert(out.size() == nregions_);
0251   }
0252   nregions_ = out.size();
0253   if (ntk_) {
0254     assert(in.track.size() == NTK_SECTORS * (nendcaps_ ? nendcaps_ : 2));
0255     tkRegionizer_.initSectors(in.track);
0256     tkRegionizer_.initRegions(out);
0257     tkRegionizer_.initRouting(tkRoutes_);
0258   }
0259   if (ncalo_) {
0260     assert(in.hadcalo.size() == NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1));
0261     hadCaloRegionizer_.initSectors(in.hadcalo);
0262     hadCaloRegionizer_.initRegions(out);
0263     hadCaloRegionizer_.initRouting(caloRoutes_);
0264   }
0265   if (nem_) {
0266     assert(in.emcalo.size() == NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1));
0267     emCaloRegionizer_.initSectors(in.emcalo);
0268     emCaloRegionizer_.initRegions(out);
0269     emCaloRegionizer_.initRouting(emCaloRoutes_);
0270   }
0271   if (nmu_) {
0272     muRegionizer_.initSectors(in.muon);
0273     muRegionizer_.initRegions(out);
0274     muRegionizer_.initRouting(muRoutes_);
0275   }
0276 }
0277 
0278 // clock-cycle emulation
0279 bool l1ct::MultififoRegionizerEmulator::step(bool newEvent,
0280                                              const std::vector<l1ct::TkObjEmu>& links,
0281                                              std::vector<l1ct::TkObjEmu>& out,
0282                                              bool mux) {
0283   return ntk_ ? tkRegionizer_.step(newEvent, links, out, mux) : false;
0284 }
0285 
0286 bool l1ct::MultififoRegionizerEmulator::step(bool newEvent,
0287                                              const std::vector<l1ct::EmCaloObjEmu>& links,
0288                                              std::vector<l1ct::EmCaloObjEmu>& out,
0289                                              bool mux) {
0290   assert(emInterceptMode_ == noIntercept);  // otherwise the em & had calo can't be stepped independently
0291   return nem_ ? emCaloRegionizer_.step(newEvent, links, out, mux) : false;
0292 }
0293 
0294 bool l1ct::MultififoRegionizerEmulator::step(bool newEvent,
0295                                              const std::vector<l1ct::HadCaloObjEmu>& links,
0296                                              std::vector<l1ct::HadCaloObjEmu>& out,
0297                                              bool mux) {
0298   return ncalo_ ? hadCaloRegionizer_.step(newEvent, links, out, mux) : false;
0299 }
0300 
0301 bool l1ct::MultififoRegionizerEmulator::step(bool newEvent,
0302                                              const std::vector<l1ct::MuObjEmu>& links,
0303                                              std::vector<l1ct::MuObjEmu>& out,
0304                                              bool mux) {
0305   return nmu_ ? muRegionizer_.step(newEvent, links, out, mux) : false;
0306 }
0307 
0308 bool l1ct::MultififoRegionizerEmulator::step(bool newEvent,
0309                                              const std::vector<l1ct::TkObjEmu>& links_tk,
0310                                              const std::vector<l1ct::HadCaloObjEmu>& links_hadCalo,
0311                                              const std::vector<l1ct::EmCaloObjEmu>& links_emCalo,
0312                                              const std::vector<l1ct::MuObjEmu>& links_mu,
0313                                              std::vector<l1ct::TkObjEmu>& out_tk,
0314                                              std::vector<l1ct::HadCaloObjEmu>& out_hadCalo,
0315                                              std::vector<l1ct::EmCaloObjEmu>& out_emCalo,
0316                                              std::vector<l1ct::MuObjEmu>& out_mu,
0317                                              bool mux) {
0318   bool ret = false;
0319   if (ntk_)
0320     ret = tkRegionizer_.step(newEvent, links_tk, out_tk, mux);
0321   if (nmu_)
0322     ret = muRegionizer_.step(newEvent, links_mu, out_mu, mux);
0323   switch (emInterceptMode_) {
0324     case noIntercept:
0325       if (ncalo_)
0326         ret = hadCaloRegionizer_.step(newEvent, links_hadCalo, out_hadCalo, mux);
0327       if (nem_)
0328         ret = emCaloRegionizer_.step(newEvent, links_emCalo, out_emCalo, mux);
0329       break;
0330     case interceptPreFifo:
0331       // we actually intercept at the links, in the software it's equivalent and it's easier
0332       assert(nem_ > 0 && ncalo_ > 0 && !links_hadCalo.empty() && links_emCalo.empty());
0333       assert(interceptor_.get());
0334       {
0335         std::vector<l1ct::EmCaloObjEmu> intercepted_links;
0336         interceptor_->select_or_clear(links_hadCalo, intercepted_links);
0337         ret = hadCaloRegionizer_.step(newEvent, links_hadCalo, out_hadCalo, mux);
0338         emCaloRegionizer_.step(newEvent, intercepted_links, out_emCalo, mux);
0339       }
0340       break;
0341     case interceptPostFifo:
0342       assert(nem_ > 0 && ncalo_ > 0 && !links_hadCalo.empty() && links_emCalo.empty());
0343       assert(interceptor_.get());
0344       {
0345         if (mux) {
0346           std::vector<l1ct::HadCaloObjEmu> hadNoMux;
0347           hadCaloRegionizer_.step(newEvent, links_hadCalo, hadNoMux, /*mux=*/false);
0348           std::vector<l1ct::EmCaloObjEmu> emNoMux(hadNoMux.size());
0349           interceptor_->select_or_clear(hadNoMux, emNoMux);
0350           ret = hadCaloRegionizer_.muxonly_step(newEvent, /*flush=*/false, hadNoMux, out_hadCalo);
0351           emCaloRegionizer_.muxonly_step(newEvent, /*flush=*/true, emNoMux, out_emCalo);
0352         } else {
0353           ret = hadCaloRegionizer_.step(newEvent, links_hadCalo, out_hadCalo, /*mux=*/false);
0354           interceptor_->select_or_clear(out_hadCalo, out_emCalo);
0355         }
0356       }
0357       break;
0358   }
0359   return ret;
0360 }
0361 
0362 void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock,
0363                                                   const l1ct::RegionizerDecodedInputs& in,
0364                                                   std::vector<l1ct::TkObjEmu>& links) {
0365   if (ntk_ == 0)
0366     return;
0367   links.resize(NTK_SECTORS * NTK_LINKS * (nendcaps_ ? nendcaps_ : 2));
0368   for (unsigned int is = 0, idx = 0; is < NTK_SECTORS * (nendcaps_ ? nendcaps_ : 2); ++is) {  // tf sectors
0369     const l1ct::DetectorSector<l1ct::TkObjEmu>& sec = in.track[is];
0370     for (unsigned int il = 0; il < NTK_LINKS; ++il, ++idx) {
0371       unsigned int ioffs = iclock * NTK_LINKS + il;
0372       if (ioffs < sec.size() && iclock < nclocks_ - 1) {
0373         links[idx] = sec[ioffs];
0374       } else {
0375         links[idx].clear();
0376       }
0377     }
0378   }
0379 }
0380 
0381 template <typename T>
0382 void l1ct::MultififoRegionizerEmulator::fillCaloLinks_(unsigned int iclock,
0383                                                        const std::vector<DetectorSector<T>>& in,
0384                                                        std::vector<T>& links) {
0385   unsigned int NLINKS =
0386       (nendcaps_ ? NCALO_LINKS : (typeid(T) == typeid(l1ct::HadCaloObjEmu) ? HCAL_LINKS : ECAL_LINKS));
0387   links.resize(NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1) * NLINKS);
0388   for (unsigned int is = 0, idx = 0; is < NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1); ++is) {
0389     for (unsigned int il = 0; il < NLINKS; ++il, ++idx) {
0390       unsigned int ioffs = iclock * NLINKS + il;
0391       if (ioffs < in[is].size() && iclock < nclocks_ - 1) {
0392         links[idx] = in[is][ioffs];
0393       } else {
0394         links[idx].clear();
0395       }
0396     }
0397   }
0398 }
0399 
0400 void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock,
0401                                                   const l1ct::RegionizerDecodedInputs& in,
0402                                                   std::vector<l1ct::HadCaloObjEmu>& links) {
0403   if (ncalo_ == 0)
0404     return;
0405   fillCaloLinks_(iclock, in.hadcalo, links);
0406 }
0407 
0408 void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock,
0409                                                   const l1ct::RegionizerDecodedInputs& in,
0410                                                   std::vector<l1ct::EmCaloObjEmu>& links) {
0411   if (nem_ == 0 || emInterceptMode_ != noIntercept)
0412     return;
0413   fillCaloLinks_(iclock, in.emcalo, links);
0414 }
0415 
0416 void l1ct::MultififoRegionizerEmulator::fillLinks(unsigned int iclock,
0417                                                   const l1ct::RegionizerDecodedInputs& in,
0418                                                   std::vector<l1ct::MuObjEmu>& links) {
0419   if (nmu_ == 0)
0420     return;
0421   assert(NMU_LINKS == 1);
0422   links.resize(NMU_LINKS);
0423   if (iclock < in.muon.size() && iclock < nclocks_ - 1) {
0424     links[0] = in.muon[iclock];
0425   } else {
0426     links[0].clear();
0427   }
0428 }
0429 
0430 void l1ct::MultififoRegionizerEmulator::toFirmware(const std::vector<l1ct::TkObjEmu>& emu,
0431                                                    TkObj fw[/*NTK_SECTORS][NTK_LINKS*/]) {
0432   if (ntk_ == 0)
0433     return;
0434   assert(emu.size() == NTK_SECTORS * NTK_LINKS * (nendcaps_ ? nendcaps_ : 2));
0435   for (unsigned int is = 0, idx = 0; is < NTK_SECTORS * (nendcaps_ ? nendcaps_ : 2); ++is) {  // tf sectors
0436     for (unsigned int il = 0; il < NTK_LINKS; ++il, ++idx) {
0437       fw[is * NTK_LINKS + il] = emu[idx];
0438     }
0439   }
0440 }
0441 void l1ct::MultififoRegionizerEmulator::toFirmware(const std::vector<l1ct::HadCaloObjEmu>& emu,
0442                                                    HadCaloObj fw[/*NCALO_SECTORS*NCALO_LINKS*/]) {
0443   if (ncalo_ == 0)
0444     return;
0445   unsigned int NLINKS = (nendcaps_ ? NCALO_LINKS * nendcaps_ : HCAL_LINKS);
0446   assert(emu.size() == NCALO_SECTORS * NLINKS);
0447   for (unsigned int is = 0, idx = 0; is < NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1); ++is) {  // calo sectors
0448     for (unsigned int il = 0; il < NLINKS; ++il, ++idx) {
0449       fw[is * NLINKS + il] = emu[idx];
0450     }
0451   }
0452 }
0453 
0454 void l1ct::MultififoRegionizerEmulator::toFirmware(const std::vector<l1ct::EmCaloObjEmu>& emu,
0455                                                    EmCaloObj fw[/*NCALO_SECTORS*NCALO_LINKS*/]) {
0456   if (nem_ == 0)
0457     return;
0458   unsigned int NLINKS = (nendcaps_ ? NCALO_LINKS * nendcaps_ : ECAL_LINKS);
0459   assert(emu.size() == NCALO_SECTORS * NLINKS);
0460   for (unsigned int is = 0, idx = 0; is < NCALO_SECTORS * (nendcaps_ ? nendcaps_ : 1); ++is) {  // calo sectors
0461     for (unsigned int il = 0; il < NLINKS; ++il, ++idx) {
0462       fw[is * NLINKS + il] = emu[idx];
0463     }
0464   }
0465 }
0466 
0467 void l1ct::MultififoRegionizerEmulator::toFirmware(const std::vector<l1ct::MuObjEmu>& emu, MuObj fw[/*NMU_LINKS*/]) {
0468   if (nmu_ == 0)
0469     return;
0470   assert(emu.size() == NMU_LINKS);
0471   for (unsigned int il = 0, idx = 0; il < NMU_LINKS; ++il, ++idx) {
0472     fw[il] = emu[idx];
0473   }
0474 }
0475 
0476 void l1ct::MultififoRegionizerEmulator::destream(int iclock,
0477                                                  const std::vector<l1ct::TkObjEmu>& tk_out,
0478                                                  const std::vector<l1ct::EmCaloObjEmu>& em_out,
0479                                                  const std::vector<l1ct::HadCaloObjEmu>& calo_out,
0480                                                  const std::vector<l1ct::MuObjEmu>& mu_out,
0481                                                  PFInputRegion& out) {
0482   if (ntk_)
0483     tkRegionizer_.destream(iclock, tk_out, out.track);
0484   if (ncalo_)
0485     hadCaloRegionizer_.destream(iclock, calo_out, out.hadcalo);
0486   if (nem_)
0487     emCaloRegionizer_.destream(iclock, em_out, out.emcalo);
0488   if (nmu_)
0489     muRegionizer_.destream(iclock, mu_out, out.muon);
0490 }
0491 
0492 void l1ct::MultififoRegionizerEmulator::run(const RegionizerDecodedInputs& in, std::vector<PFInputRegion>& out) {
0493   if (!init_)
0494     initSectorsAndRegions(in, out);
0495   tkRegionizer_.reset();
0496   emCaloRegionizer_.reset();
0497   hadCaloRegionizer_.reset();
0498   muRegionizer_.reset();
0499   std::vector<l1ct::TkObjEmu> tk_links_in, tk_out;
0500   std::vector<l1ct::EmCaloObjEmu> em_links_in, em_out;
0501   std::vector<l1ct::HadCaloObjEmu> calo_links_in, calo_out;
0502   std::vector<l1ct::MuObjEmu> mu_links_in, mu_out;
0503 
0504   // read and sort the inputs
0505   for (unsigned int iclock = 0; iclock < nclocks_; ++iclock) {
0506     fillLinks(iclock, in, tk_links_in);
0507     fillLinks(iclock, in, em_links_in);
0508     fillLinks(iclock, in, calo_links_in);
0509     fillLinks(iclock, in, mu_links_in);
0510 
0511     bool newevt = (iclock == 0), mux = true;
0512     step(newevt, tk_links_in, calo_links_in, em_links_in, mu_links_in, tk_out, calo_out, em_out, mu_out, mux);
0513   }
0514 
0515   // set up an empty event
0516   for (auto& l : tk_links_in)
0517     l.clear();
0518   for (auto& l : em_links_in)
0519     l.clear();
0520   for (auto& l : calo_links_in)
0521     l.clear();
0522   for (auto& l : mu_links_in)
0523     l.clear();
0524 
0525   // read and put the inputs in the regions
0526   assert(out.size() == nregions_);
0527   for (unsigned int iclock = 0; iclock < nclocks_; ++iclock) {
0528     bool newevt = (iclock == 0), mux = true;
0529     step(newevt, tk_links_in, calo_links_in, em_links_in, mu_links_in, tk_out, calo_out, em_out, mu_out, mux);
0530 
0531     unsigned int ireg = iclock / (outii_ + pauseii_);
0532     if ((iclock % (outii_ + pauseii_)) >= outii_)
0533       continue;
0534     if (ireg >= nregions_)
0535       break;
0536 
0537     if (streaming_) {
0538       destream(iclock, tk_out, em_out, calo_out, mu_out, out[ireg]);
0539     } else {
0540       if (iclock % outii_ == 0) {
0541         out[ireg].track = tk_out;
0542         out[ireg].emcalo = em_out;
0543         out[ireg].hadcalo = calo_out;
0544         out[ireg].muon = mu_out;
0545       }
0546     }
0547   }
0548 
0549   tkRegionizer_.reset();
0550   emCaloRegionizer_.reset();
0551   hadCaloRegionizer_.reset();
0552   muRegionizer_.reset();
0553 }