Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef multififo_regionizer_elements_ref_h
0002 #define multififo_regionizer_elements_ref_h
0003 
0004 #include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h"
0005 
0006 #include <list>
0007 #include <vector>
0008 #include <deque>
0009 #include <cassert>
0010 
0011 namespace l1ct {
0012   namespace multififo_regionizer {
0013     template <typename T>
0014     inline void shift(T& from, T& to) {
0015       to = from;
0016       from.clear();
0017     }
0018     template <typename TL, typename T>
0019     inline void pop_back(TL& from, T& to) {
0020       assert(!from.empty());
0021       to = from.back();
0022       from.pop_back();
0023     }
0024 
0025     inline int dphi_wrap(int local_phi) {
0026       if (local_phi > l1ct::Scales::INTPHI_PI)
0027         local_phi -= l1ct::Scales::INTPHI_TWOPI;
0028       else if (local_phi <= -l1ct::Scales::INTPHI_PI)
0029         local_phi += l1ct::Scales::INTPHI_TWOPI;
0030       return local_phi;
0031     }
0032 
0033     template <typename T>
0034     inline void push_to_fifo(const T& t, int local_eta, int local_phi, std::list<T>& fifo) {
0035       fifo.push_front(t);
0036       fifo.front().hwEta = local_eta;
0037       fifo.front().hwPhi = local_phi;
0038     }
0039 
0040     template <typename T>
0041     inline void maybe_push(const T& t,
0042                            const l1ct::PFRegionEmu& sector,
0043                            const l1ct::PFRegionEmu& region,
0044                            std::list<T>& fifo,
0045                            bool useAlsoVtxCoords);
0046     template <>
0047     inline void maybe_push<l1ct::TkObjEmu>(const l1ct::TkObjEmu& t,
0048                                            const l1ct::PFRegionEmu& sector,
0049                                            const l1ct::PFRegionEmu& region,
0050                                            std::list<l1ct::TkObjEmu>& fifo,
0051                                            bool useAlsoVtxCoords);
0052 
0053     template <typename T>
0054     class RegionBuffer {
0055     public:
0056       RegionBuffer() : nfifos_(0) {}
0057       void initFifos(unsigned int nfifos);
0058       void initRegion(const l1ct::PFRegionEmu& region, bool useAlsoVtxCoords) {
0059         region_ = region;
0060         useAlsoVtxCoords_ = useAlsoVtxCoords;
0061       }
0062       void flush();
0063       void maybe_push(int fifo, const T& t, const l1ct::PFRegionEmu& sector);
0064       T pop();
0065 
0066     private:
0067       unsigned int nfifos_;
0068       bool useAlsoVtxCoords_;
0069       l1ct::PFRegionEmu region_;
0070       std::vector<std::list<T>> fifos_;
0071       std::vector<std::pair<std::vector<T>, std::vector<T>>> queues_;
0072 
0073       T pop_next_trivial_();
0074       void fifos_to_stage_(std::vector<T>& staging_area);
0075       void queue_to_stage_(std::vector<T>& queue, std::vector<T>& staging_area);
0076       void stage_to_queue_(std::vector<T>& staging_area, std::vector<T>& queue);
0077       T pop_queue_(std::vector<T>& queue);
0078     };
0079 
0080     template <typename T>
0081     inline bool local_eta_phi_window(const T& t,
0082                                      const l1ct::glbeta_t& etaMin,
0083                                      const l1ct::glbeta_t& etaMax,
0084                                      const l1ct::glbphi_t& phiMin,
0085                                      const l1ct::glbphi_t& phiMax);
0086     template <>
0087     inline bool local_eta_phi_window<l1ct::TkObjEmu>(const l1ct::TkObjEmu& t,
0088                                                      const l1ct::glbeta_t& etaMin,
0089                                                      const l1ct::glbeta_t& etaMax,
0090                                                      const l1ct::glbphi_t& phiMin,
0091                                                      const l1ct::glbphi_t& phiMax);
0092 
0093     template <typename T>
0094     class EtaPhiBuffer {
0095     public:
0096       EtaPhiBuffer() {}
0097       EtaPhiBuffer(unsigned int maxitems,
0098                    const l1ct::glbeta_t& etaMin = 0,
0099                    const l1ct::glbeta_t& etaMax = 0,
0100                    const l1ct::glbeta_t& etaShift = 0,
0101                    const l1ct::glbphi_t& phiMin = 0,
0102                    const l1ct::glbphi_t& phiMax = 0,
0103                    const l1ct::glbphi_t& phiShift = 0)
0104           : size_(maxitems),
0105             iwrite_(0),
0106             iread_(0),
0107             etaMin_(etaMin),
0108             etaMax_(etaMax),
0109             etaShift_(etaShift),
0110             phiMin_(phiMin),
0111             phiMax_(phiMax),
0112             phiShift_(phiShift) {}
0113       void maybe_push(const T& t);
0114       void writeNewEvent() {
0115         iwrite_ = 1 - iwrite_;
0116         items_[iwrite_].clear();
0117       }
0118       void readNewEvent() { iread_ = 1 - iread_; }
0119       T pop();
0120       unsigned int writeSize() const { return items_[iwrite_].size(); }
0121       unsigned int readSize() const { return items_[iread_].size(); }
0122       unsigned int maxSize() const { return size_; }
0123       void reset();
0124 
0125     private:
0126       unsigned int size_, iwrite_, iread_;
0127       l1ct::glbeta_t etaMin_, etaMax_;
0128       l1ct::glbeta_t etaShift_;
0129       l1ct::glbphi_t phiMin_, phiMax_;
0130       l1ct::glbphi_t phiShift_;
0131       std::deque<T> items_[2];
0132     };
0133 
0134     // forward decl for later
0135     template <typename T>
0136     class RegionMux;
0137 
0138     template <typename T>
0139     class RegionBuilder {
0140     public:
0141       RegionBuilder() {}
0142       RegionBuilder(unsigned int iregion, unsigned int nsort) : iregion_(iregion), sortbuffer_(nsort) {}
0143       void push(const T& in);
0144       void pop(RegionMux<T>& out);
0145 
0146     private:
0147       unsigned int iregion_;
0148       std::vector<T> sortbuffer_;
0149     };
0150 
0151     template <typename T>
0152     class RegionMux {
0153     public:
0154       RegionMux() : nregions_(0) {}
0155       RegionMux(unsigned int nregions,
0156                 unsigned int nsort,
0157                 unsigned int nout,
0158                 bool streaming,
0159                 unsigned int outii = 0,
0160                 unsigned int pauseii = 0)
0161           : nregions_(nregions),
0162             nsort_(nsort),
0163             nout_(nout),
0164             outii_(outii),
0165             pauseii_(pauseii),
0166             streaming_(streaming),
0167             buffer_(nregions * nsort),
0168             iter_(0),
0169             ireg_(nregions) {
0170         assert(streaming ? (outii * nout >= nsort) : (nout == nsort));
0171         for (auto& t : buffer_)
0172           t.clear();
0173       }
0174       void push(unsigned int region, std::vector<T>& in);
0175       bool stream(bool newevt, std::vector<T>& out);
0176 
0177     private:
0178       unsigned int nregions_, nsort_, nout_, outii_, pauseii_;
0179       bool streaming_;
0180       std::vector<T> buffer_;
0181       unsigned int iter_, ireg_;
0182     };
0183 
0184     // out of the Regionizer<T> since it doesn't depend on T and may be shared
0185     struct Route {
0186       unsigned short int sector, link, region, fifo;
0187       Route(unsigned short int from_sector,
0188             unsigned short int from_link,
0189             unsigned short int to_region,
0190             unsigned short int to_fifo)
0191           : sector(from_sector), link(from_link), region(to_region), fifo(to_fifo) {}
0192     };
0193 
0194     template <typename T>
0195     class Regionizer {
0196     public:
0197       Regionizer() {}
0198       Regionizer(unsigned int nsorted,
0199                  unsigned int nout,
0200                  bool streaming,
0201                  unsigned int outii = 0,
0202                  unsigned int pauseii = 0,
0203                  bool useAlsoVtxCoords = false);
0204       void initSectors(const std::vector<DetectorSector<T>>& sectors);
0205       void initSectors(const DetectorSector<T>& sector);
0206       void initRegions(const std::vector<PFInputRegion>& regions);
0207       void initRouting(const std::vector<Route> routes, bool validateRoutes = true);
0208 
0209       void reset() {
0210         flush();
0211         nevt_ = 0;
0212       }
0213 
0214       // single clock emulation
0215       bool step(bool newEvent, const std::vector<T>& links, std::vector<T>& out, bool mux = true);
0216 
0217       // single clock emulation
0218       bool muxonly_step(bool newEvent, bool mayFlush, const std::vector<T>& nomux_out, std::vector<T>& out);
0219 
0220       void destream(int iclock, const std::vector<T>& streams, std::vector<T>& out);
0221 
0222     private:
0223       unsigned int nsectors_, nregions_, nsorted_, nout_, outii_, pauseii_;
0224       bool streaming_, useAlsoVtxCoords_;
0225       std::vector<l1ct::PFRegionEmu> sectors_;
0226       std::vector<RegionBuffer<T>> buffers_;
0227       std::vector<RegionBuilder<T>> builders_;
0228       RegionMux<T> bigmux_;
0229       std::vector<Route> routes_;
0230       unsigned int nevt_;
0231 
0232       void flush() {
0233         for (auto& b : buffers_)
0234           b.flush();
0235       }
0236     };
0237 
0238   }  // namespace  multififo_regionizer
0239 }  // namespace l1ct
0240 
0241 template <typename T>
0242 inline bool l1ct::multififo_regionizer::local_eta_phi_window(const T& t,
0243                                                              const l1ct::glbeta_t& etaMin,
0244                                                              const l1ct::glbeta_t& etaMax,
0245                                                              const l1ct::glbphi_t& phiMin,
0246                                                              const l1ct::glbphi_t& phiMax) {
0247   return (etaMin == etaMax) ||
0248          (etaMin <= t.hwEta && t.hwEta <= etaMax && ((phiMin == phiMax) || (phiMin <= t.hwPhi && t.hwPhi <= phiMax)));
0249 }
0250 template <>
0251 inline bool l1ct::multififo_regionizer::local_eta_phi_window<l1ct::TkObjEmu>(const l1ct::TkObjEmu& t,
0252                                                                              const l1ct::glbeta_t& etaMin,
0253                                                                              const l1ct::glbeta_t& etaMax,
0254                                                                              const l1ct::glbphi_t& phiMin,
0255                                                                              const l1ct::glbphi_t& phiMax) {
0256   return (etaMin == etaMax) ||
0257          (etaMin <= t.hwEta && t.hwEta <= etaMax && ((phiMin == phiMax) || (phiMin <= t.hwPhi && t.hwPhi <= phiMax))) ||
0258          (etaMin <= t.hwVtxEta() && t.hwVtxEta() <= etaMax &&
0259           ((phiMin == phiMax) || (phiMin <= t.hwVtxPhi() && t.hwVtxPhi() <= phiMax)));
0260 }
0261 template <typename T>
0262 void l1ct::multififo_regionizer::EtaPhiBuffer<T>::maybe_push(const T& t) {
0263   if ((t.hwPt != 0) && local_eta_phi_window(t, etaMin_, etaMax_, phiMin_, phiMax_)) {
0264     if (items_[iwrite_].size() < size_) {
0265       items_[iwrite_].push_back(t);
0266       items_[iwrite_].back().hwEta += etaShift_;
0267       items_[iwrite_].back().hwPhi += phiShift_;
0268     } else {
0269       // uncommenting the message below may be useful for debugging
0270       //dbgCout() << "WARNING: sector buffer is full for " << typeid(T).name() << ", pt = " << t.intPt()
0271       //          << ", eta = " << t.intEta() << ", phi = " << t.intPhi() << "\n";
0272     }
0273   }
0274 }
0275 
0276 template <typename T>
0277 T l1ct::multififo_regionizer::EtaPhiBuffer<T>::pop() {
0278   T ret;
0279   ret.clear();
0280   if (!items_[iread_].empty()) {
0281     ret = items_[iread_].front();
0282     items_[iread_].pop_front();
0283   }
0284   return ret;
0285 }
0286 template <typename T>
0287 void l1ct::multififo_regionizer::EtaPhiBuffer<T>::reset() {
0288   iread_ = 0;
0289   iwrite_ = 0;
0290   items_[0].clear();
0291   items_[1].clear();
0292 }
0293 
0294 #endif