File indexing completed on 2023-10-25 09:55:54
0001 #include <stdexcept>
0002
0003 #include "L1Trigger/Phase2L1ParticleFlow/interface/regionizer/tdr_regionizer_elements_ref.h"
0004
0005
0006 template <typename T>
0007 l1ct::tdr_regionizer::PipeEntry<T> l1ct::tdr_regionizer::Pipe<T>::popEntry() {
0008 assert(pipe_.size() > 0);
0009 auto last = pipe_.back();
0010
0011 for (size_t i = pipe_.size() - 1; i > 0; --i) {
0012 pipe_[i] = pipe_[i - 1];
0013 }
0014 pipe_[0].setInvalid();
0015 return last;
0016 }
0017
0018 template <typename T>
0019 void l1ct::tdr_regionizer::Pipe<T>::reset() {
0020 for (auto& pe : pipe_) {
0021 pe.setInvalid();
0022 }
0023 }
0024
0025 template <typename T>
0026 void l1ct::tdr_regionizer::Pipes<T>::reset() {
0027 for (auto& pipe : pipes_) {
0028 pipe.reset();
0029 }
0030 }
0031
0032 template <typename T>
0033 void l1ct::tdr_regionizer::Pipes<T>::setTaps(size_t taps) {
0034 for (auto& pipe : pipes_) {
0035 pipe.setTaps(taps);
0036 }
0037 }
0038
0039
0040 template <typename T>
0041 l1ct::tdr_regionizer::BufferEntry<T>::BufferEntry(
0042 const T& obj, std::vector<size_t> srIndices, int glbeta, int glbphi, unsigned int clk)
0043 : obj_(obj), srIndices_(srIndices), glbeta_(glbeta), glbphi_(glbphi), linkobjclk_(clk) {
0044 objcount_ = 0;
0045 }
0046
0047 template <typename T>
0048 inline void l1ct::tdr_regionizer::Buffer<T>::addEntry(
0049 const T& obj, std::vector<size_t> srIndices, int glbeta, int glbphi, unsigned int dupNum, unsigned int ndup) {
0050
0051 auto objClk = nextObjClk(ndup);
0052 data_.emplace_back(obj, srIndices, glbeta, glbphi, objClk);
0053 if (timeOfNextObject_ < 0) {
0054 timeOfNextObject_ = objClk;
0055 }
0056 }
0057
0058 template <typename T>
0059 void l1ct::tdr_regionizer::Buffer<T>::updateNextObjectTime(int currTime) {
0060 if (data_.size() > 0) {
0061 timeOfNextObject_ = std::max(front().clock(), static_cast<unsigned int>(currTime + 1));
0062 } else {
0063 timeOfNextObject_ = -1;
0064 }
0065 }
0066
0067 template <typename T>
0068 inline unsigned int l1ct::tdr_regionizer::Buffer<T>::nextObjClk(unsigned int ndup) {
0069 unsigned int nextVal = std::max(clkindex360_, clkindex240_) / 3;
0070
0071 clkindex360_ += 2 * ndup;
0072 clkindex240_ += 3;
0073
0074 return nextVal;
0075 }
0076
0077
0078 template <>
0079 inline unsigned int l1ct::tdr_regionizer::Buffer<l1ct::TkObjEmu>::nextObjClk(unsigned int ndup) {
0080 if (ndup != 1) {
0081 throw std::invalid_argument("Only ndup==1 is currently supported for the TkObjEmu buffers.");
0082 }
0083
0084 unsigned int nextVal = std::max(clkindex360_, clkindex240_) / 3;
0085
0086 clkindex360_ += 2;
0087 if ((clkindex360_ - INIT360) % 6 == 4) {
0088 clkindex360_ += 2;
0089 }
0090
0091 clkindex240_ += 3;
0092
0093 return nextVal;
0094 }
0095
0096 template <typename T>
0097 l1ct::tdr_regionizer::PipeEntry<T> l1ct::tdr_regionizer::Buffer<T>::popEntry(int currTime, bool debug) {
0098 if (front().nextSR() < 0) {
0099
0100 pop();
0101 if (debug) {
0102 dbgCout() << "updating time clock = " << front().clock() << ", currTime = " << currTime << std::endl;
0103 }
0104 updateNextObjectTime(currTime);
0105 return l1ct::tdr_regionizer::PipeEntry<T>();
0106 }
0107
0108 auto pipeEntry =
0109 l1ct::tdr_regionizer::PipeEntry<T>(front().obj(), front().nextSR(), front().glbEta(), front().glbPhi());
0110 front().incSR();
0111 if (front().nextSR() < 0) {
0112
0113 pop();
0114 } else {
0115 if (debug) {
0116 dbgCout() << "Remain on same object, nextSR = " << front().nextSR() << std::endl;
0117 }
0118
0119
0120 if (numEntries() > 1 && data_[1].nextSR() == -1 && static_cast<int>(data_[1].clock()) == currTime + 2) {
0121 if (debug) {
0122 dbgCout() << "removing a following throwout with time " << data_[1].clock() << std::endl;
0123 }
0124 data_.erase(data_.begin() + 1);
0125 } else if (numEntries() > 2 && data_[2].nextSR() == -1 && static_cast<int>(data_[2].clock()) <= currTime + 2) {
0126 if (debug) {
0127 dbgCout() << "removing the two-back throwout with time " << data_[2].clock() << std::endl;
0128 }
0129 data_.erase(data_.begin() + 2);
0130 }
0131 }
0132 if (debug) {
0133 dbgCout() << "updating time clock = " << front().clock() << ", currTime = " << currTime << std::endl;
0134 }
0135
0136 updateNextObjectTime(currTime);
0137 return pipeEntry;
0138 }
0139
0140
0141 template <typename T>
0142 l1ct::tdr_regionizer::Regionizer<T>::Regionizer(unsigned int neta,
0143 unsigned int nphi,
0144 unsigned int maxobjects,
0145 int bigRegionMin,
0146 int bigRegionMax,
0147 unsigned int nclocks,
0148 unsigned int ndup,
0149 bool debug)
0150 : neta_(neta),
0151 nphi_(nphi),
0152 maxobjects_(maxobjects),
0153 nsectors_(0),
0154 bigRegionMin_(bigRegionMin),
0155 bigRegionMax_(bigRegionMax),
0156 nclocks_(nclocks),
0157 ndup_(ndup),
0158 pipes_(neta * nphi),
0159 smallRegionObjects_(neta * nphi),
0160 firstEvent_(true),
0161 debug_(debug) {}
0162
0163 template <typename T>
0164 void l1ct::tdr_regionizer::Regionizer<T>::initSectors(const std::vector<DetectorSector<T>>& sectors) {
0165 assert(nsectors_ == 0);
0166
0167
0168
0169
0170 for (const auto& sector : sectors) {
0171 if (isInBigRegionLoose(sector.region)) {
0172 invsectormap_.push_back(sectors_.size());
0173 sectors_.push_back(sector.region);
0174 }
0175 }
0176 nsectors_ = sectors_.size();
0177 buffers_.resize(nsectors_ * ndup_);
0178 if (debug_) {
0179 dbgCout() << "Number of sectors: " << nsectors_ << std::endl;
0180 }
0181
0182 std::sort(invsectormap_.begin(), invsectormap_.end(), [this](size_t a, size_t b) { return this->sortSectors(a, b); });
0183
0184
0185 sectormap_.resize(invsectormap_.size());
0186 for (size_t i = 0; i < invsectormap_.size(); ++i) {
0187 sectormap_[invsectormap_[i]] = i;
0188 }
0189
0190 pipes_.setTaps(nsectors_ * ndup_);
0191 }
0192
0193 template <typename T>
0194 void l1ct::tdr_regionizer::Regionizer<T>::initSectors(const DetectorSector<T>& sector) {
0195 assert(nsectors_ == 0);
0196 nsectors_ = 1;
0197 sectors_.push_back(sector.region);
0198 sectormap_.push_back(0);
0199 buffers_.resize(nsectors_ * ndup_);
0200 if (debug_) {
0201 dbgCout() << "Number of sectors: " << nsectors_ << std::endl;
0202 }
0203 pipes_.setTaps(nsectors_ * ndup_);
0204 }
0205
0206 template <typename T>
0207 void l1ct::tdr_regionizer::Regionizer<T>::fillBuffers(const std::vector<DetectorSector<T>>& sectors) {
0208 setBuffers(fillLinks(sectors));
0209 }
0210
0211 template <typename T>
0212 void l1ct::tdr_regionizer::Regionizer<T>::fillBuffers(const DetectorSector<T>& sector) {
0213 setBuffers(fillLinks(sector));
0214 }
0215
0216
0217
0218 template <typename T>
0219 bool l1ct::tdr_regionizer::Regionizer<T>::sortRegionsRegular(size_t a, size_t b) const {
0220
0221 auto etaa = regions_[a].intEtaCenter();
0222 auto etab = regions_[b].intEtaCenter();
0223 auto phia = regions_[a].intPhiCenter();
0224 auto phib = regions_[b].intPhiCenter();
0225 return sortRegionsHelper(etaa, etab, phia, phib);
0226 }
0227
0228
0229
0230 template <typename T>
0231 bool l1ct::tdr_regionizer::Regionizer<T>::sortRegionsHelper(int etaa, int etab, int phia, int phib) const {
0232
0233 if (etaa < etab) {
0234 return true;
0235 } else if (etaa > etab) {
0236 return false;
0237 }
0238
0239
0240 if (bigRegionMax_ < bigRegionMin_) {
0241
0242 if (phia > bigRegionMin_ && phib < bigRegionMax_) {
0243 return true;
0244 } else if (phib > bigRegionMin_ && phia < bigRegionMax_) {
0245 return false;
0246 }
0247 }
0248
0249 if (phia < phib) {
0250 return true;
0251 } else {
0252 return false;
0253 }
0254 }
0255
0256
0257
0258 template <typename T>
0259 bool l1ct::tdr_regionizer::Regionizer<T>::sortSectors(size_t a, size_t b) const {
0260
0261 auto etaa = sectors_[a].intEtaCenter();
0262 auto etab = sectors_[b].intEtaCenter();
0263 auto phia = sectors_[a].intPhiCenter();
0264 auto phib = sectors_[b].intPhiCenter();
0265 return sortRegionsHelper(etaa, etab, phia, phib);
0266 }
0267
0268 template <typename T>
0269 void l1ct::tdr_regionizer::Regionizer<T>::initRegions(const std::vector<PFInputRegion>& regions) {
0270 regions_.resize(regions.size());
0271 for (unsigned int i = 0; i < regions.size(); ++i) {
0272 regions_[i] = regions[i].region;
0273 if (debug_) {
0274 dbgCout() << "region eta/phi: " << regions_[i].intEtaCenter() << " " << regions_[i].intPhiCenter()
0275 << ", eta half width = " << regions_[i].hwEtaHalfWidth.to_int()
0276 << ", phi half width = " << regions_[i].hwPhiHalfWidth.to_int()
0277 << ", eta extra = " << regions_[i].hwEtaExtra.to_int()
0278 << ", phi extra = " << regions_[i].hwPhiExtra.to_int() << std::endl;
0279 }
0280 if (isInBigRegion(regions_[i])) {
0281 regionmap_.push_back(i);
0282 }
0283 }
0284 assert(regionmap_.size() == neta_ * nphi_);
0285 std::sort(
0286 regionmap_.begin(), regionmap_.end(), [this](size_t a, size_t b) { return this->sortRegionsRegular(a, b); });
0287 }
0288
0289 template <typename T>
0290 bool l1ct::tdr_regionizer::Regionizer<T>::isInBigRegion(const PFRegionEmu& reg) const {
0291 auto phi = reg.intPhiCenter();
0292 if (bigRegionMax_ < bigRegionMin_) {
0293
0294 return phi > bigRegionMin_ || phi < bigRegionMax_;
0295 } else {
0296
0297 return phi > bigRegionMin_ && phi < bigRegionMax_;
0298 }
0299 }
0300
0301 template <typename T>
0302 bool l1ct::tdr_regionizer::Regionizer<T>::isInBigRegionLoose(const PFRegionEmu& reg) const {
0303 auto phi = reg.intPhiCenter();
0304 auto brmax = phi_wrap(bigRegionMax_ + reg.hwPhiHalfWidth.to_int() + reg.hwPhiExtra.to_int());
0305 auto brmin = phi_wrap(bigRegionMin_ - reg.hwPhiHalfWidth.to_int() - reg.hwPhiExtra.to_int());
0306 if (brmax < brmin) {
0307
0308 return phi > brmin || phi < brmax;
0309 } else {
0310
0311 return phi > brmin && phi < brmax;
0312 }
0313 }
0314
0315 template <>
0316 inline bool l1ct::tdr_regionizer::Regionizer<l1ct::TkObjEmu>::isInBigRegionLoose(const PFRegionEmu& reg) const {
0317 auto phi = reg.intPhiCenter();
0318 auto brmax = phi_wrap(bigRegionMax_ + 2 * reg.hwPhiHalfWidth.to_int());
0319 auto brmin = phi_wrap(bigRegionMin_ - 2 * reg.hwPhiHalfWidth.to_int());
0320 if (brmax < brmin) {
0321
0322 return phi > brmin || phi < brmax;
0323 } else {
0324
0325 return phi > brmin && phi < brmax;
0326 }
0327 }
0328
0329 template <typename T>
0330 std::vector<size_t> l1ct::tdr_regionizer::Regionizer<T>::getSmallRegions(int glbeta, int glbphi) const {
0331 std::vector<size_t> srIndices;
0332
0333
0334 for (size_t i = 0; i < regionmap_.size(); i++) {
0335 auto regionidx = regionIndex(i);
0336 int regphi = phi_wrap(glbphi - regions_[regionidx].intPhiCenter());
0337 int regeta = glbeta - regions_[regionidx].intEtaCenter();
0338
0339
0340 if (regions_[regionidx].isInside(regeta, regphi) &&
0341 !((glbeta == 57 && regeta == -115) || (glbeta == -57 && regeta == 115))) {
0342 srIndices.push_back(i);
0343 }
0344 }
0345
0346
0347 if (srIndices.size() == 4) {
0348 auto ent1 = srIndices[1];
0349 srIndices[1] = srIndices[2];
0350 srIndices[2] = ent1;
0351 }
0352 return srIndices;
0353 }
0354
0355 template <typename T>
0356 void l1ct::tdr_regionizer::Regionizer<T>::addToBuffer(const T& obj, unsigned int buffer, unsigned int dupNum) {
0357 assert(buffer < numBuffers());
0358 const unsigned int sector = buffer / ndup_;
0359 auto glbphi = sectors_[sector].hwGlbPhiOf(obj).to_int();
0360 auto glbeta = sectors_[sector].hwGlbEtaOf(obj).to_int();
0361
0362 buffers_[buffer].addEntry(obj, getSmallRegions(glbeta, glbphi), glbeta, glbphi, dupNum, ndup_);
0363 }
0364
0365 template <typename T>
0366 void l1ct::tdr_regionizer::Regionizer<T>::setBuffer(const std::vector<T>& objvec, unsigned int buffer) {
0367 assert(buffer < numBuffers());
0368 buffers_[buffer].reset();
0369 unsigned int dupNum = buffer % ndup_;
0370 for (unsigned int i = dupNum; i < objvec.size(); i += ndup_) {
0371
0372
0373
0374 addToBuffer(objvec[i], buffer, dupNum);
0375 }
0376 }
0377
0378 template <typename T>
0379 void l1ct::tdr_regionizer::Regionizer<T>::setBuffers(const std::vector<std::vector<T>>&& objvecvec) {
0380 assert(numBuffers() == objvecvec.size() * ndup_);
0381 for (unsigned int buffer = 0; buffer < numBuffers(); buffer++) {
0382 setBuffer(objvecvec[buffer / ndup_], buffer);
0383 }
0384 }
0385
0386 template <typename T>
0387 void l1ct::tdr_regionizer::Regionizer<T>::addToSmallRegion(l1ct::tdr_regionizer::PipeEntry<T>&& pipeEntry) {
0388 if (pipeEntry.valid()) {
0389 auto rawObj = pipeEntry.obj();
0390
0391
0392 auto realRegIdx = regionIndex(pipeEntry.sr());
0393 auto etaC = regions_[realRegIdx].intEtaCenter();
0394 auto phiC = regions_[realRegIdx].intPhiCenter();
0395
0396 int locEta = pipeEntry.glbEta() - etaC;
0397 int locPhi = phi_wrap(pipeEntry.glbPhi() - phiC);
0398
0399 rawObj.hwEta = locEta;
0400 rawObj.hwPhi = locPhi;
0401
0402 smallRegionObjects_[pipeEntry.sr()].push_back(rawObj);
0403 }
0404 }
0405
0406 template <typename T>
0407 void l1ct::tdr_regionizer::Regionizer<T>::run() {
0408 if (debug_)
0409 printDebug(-1);
0410
0411
0412 int startTime = firstEvent_ ? 0 : DELAY_TO_START;
0413 firstEvent_ = false;
0414
0415 for (int currTime = startTime; currTime < 972 + startTime;
0416 currTime++) {
0417
0418
0419
0420 bool processedAll = true;
0421
0422
0423 for (size_t bufIdx = 0; bufIdx < buffers_.size(); ++bufIdx) {
0424 auto& buffer = buffers_[bufIdx];
0425 if (buffer.timeOfNextObject() >= 0) {
0426 processedAll = false;
0427 }
0428 if (buffer.timeOfNextObject() == currTime) {
0429
0430 const auto nextSR = buffer.front().nextSR();
0431 if (debug_) {
0432 dbgCout() << "Current time " << currTime << ", handling bufIdx " << bufIdx << " object with SR = " << nextSR
0433 << ", pt = " << buffer.pt() << ", glbeta = " << buffer.glbEta() << ", glbphi = " << buffer.glbPhi()
0434 << std::endl;
0435 }
0436 if (nextSR < 0 || buffer.pt() == 0 || smallRegionObjects_[nextSR].size() == maxobjects_) {
0437
0438 buffer.popEntry(currTime, debug_);
0439 } else {
0440 const auto logicBufIdx = logicBuffIndex(bufIdx);
0441 if (pipes_.valid(nextSR, logicBufIdx)) {
0442
0443 buffer.updateNextObjectTime(currTime);
0444 } else {
0445
0446 pipes_.addEntry(nextSR, logicBufIdx, buffer.popEntry(currTime, debug_));
0447 }
0448 }
0449 }
0450 }
0451
0452 if (debug_)
0453 printDebug(currTime);
0454
0455
0456 for (size_t i = 0; i < pipes_.size(); i++) {
0457 addToSmallRegion(pipes_.popEntry(i));
0458 }
0459
0460
0461 if (processedAll) {
0462
0463 for (size_t tap = 0; tap < pipes_.numTaps(); tap++) {
0464
0465 for (size_t i = 0; i < pipes_.size(); i++) {
0466 addToSmallRegion(pipes_.popEntry(i));
0467 }
0468 }
0469 if (debug_)
0470 printDebug(2000);
0471 break;
0472 }
0473 }
0474 }
0475
0476 template <typename T>
0477 void l1ct::tdr_regionizer::Regionizer<T>::reset() {
0478 for (auto& buffer : buffers_) {
0479 buffer.reset();
0480 }
0481 pipes_.reset();
0482 for (auto& smallRegionObject : smallRegionObjects_) {
0483 smallRegionObject.clear();
0484 }
0485 firstEvent_ = true;
0486 }
0487
0488 template <typename T>
0489 std::map<size_t, std::vector<T>> l1ct::tdr_regionizer::Regionizer<T>::fillRegions(bool doSort) {
0490 std::map<size_t, std::vector<T>> srMap;
0491 for (size_t sr = 0; sr < smallRegionObjects_.size(); sr++) {
0492 srMap[regionIndex(sr)] = smallRegionObjects_[sr];
0493 if (doSort) {
0494 std::sort(srMap[regionIndex(sr)].begin(), srMap[regionIndex(sr)].end(), std::greater<>());
0495 }
0496 }
0497 return srMap;
0498 }
0499
0500 template <typename T>
0501 size_t l1ct::tdr_regionizer::Regionizer<T>::logicBuffIndex(size_t bufIdx) const {
0502 const unsigned int sector = bufIdx / ndup_;
0503 auto logSector = sectormap_[sector];
0504 return logSector * ndup_ + bufIdx % ndup_;
0505 }
0506
0507 template <typename T>
0508 void l1ct::tdr_regionizer::Regionizer<T>::printDebug(int count) const {
0509 dbgCout() << "BUFFERS, (for " << numBuffers() << " buffers)" << std::endl;
0510 dbgCout() << count << "\tbuffer\tlogical\titem\tpt\teta\tphi\tclock" << std::endl;
0511 for (auto sector : invsectormap_) {
0512 for (unsigned int dup = 0; dup < ndup_; dup++) {
0513 const unsigned int buffer = sector * ndup_ + dup;
0514 for (unsigned int j = 0; j < numEntries(buffer); j++) {
0515 dbgCout() << "\t" << buffer << "\t" << logicBuffIndex(buffer) << "\t" << j << "\t" << buffers_[buffer].pt(j)
0516 << "\t" << buffers_[buffer].glbEta(j) << "\t" << buffers_[buffer].glbPhi(j) << "\t"
0517 << buffers_[buffer].clock(j) << std::endl;
0518 }
0519 dbgCout() << "-------------------------------" << std::endl;
0520 }
0521 }
0522 dbgCout() << "PIPES, (for " << pipes_.size() << " pipes)" << std::endl;
0523 dbgCout() << count << "\tpipe\ttap\tsr\tpt\teta\tphi" << std::endl;
0524 for (size_t pipe = 0; pipe < pipes_.size(); pipe++) {
0525 for (size_t tap = 0; tap < pipes_.numTaps(); tap++) {
0526 auto entry = pipes_.entry(pipe, tap);
0527 dbgCout() << "\t" << pipe << "\t" << tap << "\t" << entry.sr() << "\t" << entry.pt() << "\t" << entry.glbEta()
0528 << "\t" << entry.glbPhi() << std::endl;
0529 }
0530 dbgCout() << "-------------------------------" << std::endl;
0531 }
0532
0533 dbgCout() << "SMALL REGIONS" << std::endl;
0534 for (unsigned int region = 0; region < neta_ * nphi_; region++) {
0535 dbgCout() << count << "\tregion\t\titem\tpt\tloceta\tlocphi" << std::endl;
0536 auto realRegIdx = regionIndex(region);
0537 auto etaC = regions_[realRegIdx].intEtaCenter();
0538 auto phiC = regions_[realRegIdx].intPhiCenter();
0539 for (unsigned int j = 0; j < smallRegionObjects_[region].size(); j++) {
0540 dbgCout() << "\t" << region << " (" << etaC << ", " << phiC << ")\t" << j << "\t"
0541 << smallRegionObjects_[region][j].intPt() << "\t" << smallRegionObjects_[region][j].intEta() << "\t"
0542 << smallRegionObjects_[region][j].intPhi() << std::endl;
0543 }
0544 dbgCout() << "-------------------------------" << std::endl;
0545 }
0546 dbgCout() << "TIMES" << std::endl;
0547 for (unsigned int i = 0; i < numBuffers(); i++) {
0548 dbgCout() << " " << buffers_[i].timeOfNextObject();
0549 }
0550 dbgCout() << "\n-------------------------------" << std::endl;
0551 }
0552
0553
0554 template <typename T>
0555 std::vector<std::vector<T>> l1ct::tdr_regionizer::Regionizer<T>::fillLinks(
0556 const std::vector<DetectorSector<T>>& sectors) const {
0557 std::vector<std::vector<T>> links;
0558
0559 if (maxobjects_ == 0) {
0560 return links;
0561 }
0562
0563 for (const auto& sector : sectors) {
0564 if (isInBigRegionLoose(sector.region)) {
0565 links.emplace_back();
0566 for (unsigned int io = 0; io < sector.size() && io < nclocks_; io++) {
0567 links.back().push_back(sector[io]);
0568 }
0569 }
0570 }
0571 return links;
0572 }
0573
0574 template <typename T>
0575 std::vector<std::vector<T>> l1ct::tdr_regionizer::Regionizer<T>::fillLinks(const DetectorSector<T>& sector) const {
0576 std::vector<std::vector<T>> links;
0577
0578 if (maxobjects_ == 0) {
0579 return links;
0580 }
0581
0582 links.emplace_back();
0583 for (unsigned int io = 0; io < sector.size() && io < nclocks_; io++) {
0584 links.back().push_back(sector[io]);
0585 }
0586 return links;
0587 }