Back to home page

Project CMSSW displayed by LXR

 
 

    


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 // PIPE ENTRY AND BUFFER
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   // shift one over
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 // BUFFER ENTRY AND BUFFER
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   // dupNum is the duplicate number of this buffer (int range 0 to ndup_-1)
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 // explicit for tracks
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     // throwout
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     // no more SRs for current front
0113     pop();
0114   } else {
0115     if (debug) {
0116       dbgCout() << "Remain on same object, nextSR = " << front().nextSR() << std::endl;
0117     }
0118     // this is a processing_stall, but throwouts that follow can still be dropped
0119     // due to the pipeline have to look two ticks back
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 // REGIONIZER
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   // we need a mapping of physical (what's in the sectors variable) to logical,
0168   // but it's easier to create the inverse, first
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   // now invert the invsectormap_
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 // this function is for sorting small regions
0217 // in eta first, then in phi
0218 template <typename T>
0219 bool l1ct::tdr_regionizer::Regionizer<T>::sortRegionsRegular(size_t a, size_t b) const {
0220   // first do eta
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 // this function is for sorting small regions
0229 // in eta first, then in phi
0230 template <typename T>
0231 bool l1ct::tdr_regionizer::Regionizer<T>::sortRegionsHelper(int etaa, int etab, int phia, int phib) const {
0232   // first do eta
0233   if (etaa < etab) {
0234     return true;
0235   } else if (etaa > etab) {
0236     return false;
0237   }
0238 
0239   // if here, then etaa == etab, move to phi
0240   if (bigRegionMax_ < bigRegionMin_) {
0241     // the wraparound case
0242     if (phia > bigRegionMin_ && phib < bigRegionMax_) {
0243       return true;
0244     } else if (phib > bigRegionMin_ && phia < bigRegionMax_) {
0245       return false;
0246     }
0247   }
0248   // regular phi
0249   if (phia < phib) {
0250     return true;
0251   } else {
0252     return false;
0253   }
0254 }
0255 
0256 // this function is for sorting the sectors
0257 // in eta first, then in phi
0258 template <typename T>
0259 bool l1ct::tdr_regionizer::Regionizer<T>::sortSectors(size_t a, size_t b) const {
0260   // first do eta
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     // the wraparound case
0294     return phi > bigRegionMin_ || phi < bigRegionMax_;
0295   } else {
0296     // the normal case
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     // the wraparound case
0308     return phi > brmin || phi < brmax;
0309   } else {
0310     // the normal case
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     // the wraparound case
0322     return phi > brmin || phi < brmax;
0323   } else {
0324     // the normal case
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;  // the signal regions this object should go into
0332 
0333   // only iterate over regions covered by board
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     // add a special check to not have 3 eta regions
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   // In a silly convention, the order of these nneds to be modified if there are 4.
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   // get the SR indices that this object should go into
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     // if (debug_) {
0372     //   dbgCout() << "Buffer " << buffer << " dupNum " << dupNum << ": add obj, index " << i << " with pt = " << objvec[i].intPt() << std::endl;
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     // in small region, the relative eta and phi are based on a different center, so need to update
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   // first event doesn't have a delayed start
0412   int startTime = firstEvent_ ? 0 : DELAY_TO_START;
0413   firstEvent_ = false;
0414 
0415   for (int currTime = startTime; currTime < 972 + startTime;
0416        currTime++) {  //this is the max allowable if nothing ever blocks
0417                       // not positive where 972 comes from. It seems to be 162 * 6
0418 
0419     // to exit early
0420     bool processedAll = true;  // to be overwritten if not the case
0421 
0422     // handle the fifo buffers
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         // time to handle the buffer entry
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           // throwout or SR full, just get rid of object
0438           buffer.popEntry(currTime, debug_);
0439         } else {
0440           const auto logicBufIdx = logicBuffIndex(bufIdx);
0441           if (pipes_.valid(nextSR, logicBufIdx)) {
0442             // The pipe already has an entry, so wait till space is available
0443             buffer.updateNextObjectTime(currTime);
0444           } else {
0445             // put the value in the pipe
0446             pipes_.addEntry(nextSR, logicBufIdx, buffer.popEntry(currTime, debug_));
0447           }
0448         }
0449       }
0450     }
0451 
0452     if (debug_)
0453       printDebug(currTime);
0454 
0455     // add the small regions
0456     for (size_t i = 0; i < pipes_.size(); i++) {
0457       addToSmallRegion(pipes_.popEntry(i));
0458     }
0459 
0460     // check ot see if you have processed all
0461     if (processedAll) {
0462       // first clear the pipes
0463       for (size_t tap = 0; tap < pipes_.numTaps(); tap++) {
0464         // add the small regions
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   }  //end main loop
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 // returns 2D arrays, sectors (links) first dimension, objects second
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   //one link per sector
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 }