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
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
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
0215 bool step(bool newEvent, const std::vector<T>& links, std::vector<T>& out, bool mux = true);
0216
0217
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 }
0239 }
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
0270
0271
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