Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-10 01:53:50

0001 template <typename T>
0002 l1ct::tdr_regionizer::PipeObject<T>::PipeObject(const T& obj,
0003                                                 unsigned int phiindex,
0004                                                 unsigned int etaindex,
0005                                                 bool phioverlap,
0006                                                 bool etaoverlap,
0007                                                 int glbphi,
0008                                                 int glbeta,
0009                                                 unsigned int clk)
0010     : obj_(obj),
0011       phiindex_(phiindex),
0012       etaindex_(etaindex),
0013       phioverlap_(phioverlap),
0014       etaoverlap_(etaoverlap),
0015       glbphi_(glbphi),
0016       glbeta_(glbeta),
0017       linkobjclk_(clk) {
0018   objcount_ = 0;
0019 }
0020 
0021 template <typename T>
0022 void l1ct::tdr_regionizer::Pipe<T>::addObj(
0023     T obj, unsigned int phiindex, unsigned int etaindex, bool phioverlap, bool etaoverlap, int glbphi, int glbeta) {
0024   data_.emplace_back(PipeObject<T>(obj, phiindex, etaindex, phioverlap, etaoverlap, glbphi, glbeta, clkindex_++));
0025 }
0026 //explicit for tracker to handle clocking
0027 template <>
0028 inline void l1ct::tdr_regionizer::Pipe<l1ct::TkObjEmu>::addObj(l1ct::TkObjEmu obj,
0029                                                                unsigned int phiindex,
0030                                                                unsigned int etaindex,
0031                                                                bool phioverlap,
0032                                                                bool etaoverlap,
0033                                                                int glbphi,
0034                                                                int glbeta) {
0035   data_.emplace_back(
0036       PipeObject<l1ct::TkObjEmu>(obj, phiindex, etaindex, phioverlap, etaoverlap, glbphi, glbeta, clkindex_++));
0037   if (clkindex_ % 3 == 2)
0038     clkindex_++;  //this is for tracker, could I get this generically maybe?
0039 }
0040 
0041 template <typename T>
0042 int l1ct::tdr_regionizer::Pipe<T>::getClosedIndexForObject(unsigned int index) {
0043   switch (getCount(index)) {
0044     case 0:
0045       return getPhi(index) * 2 + getEta(index);
0046     case 1:
0047       if (getPhiOverlap(index) && !getEtaOverlap(index))
0048         return ((getPhi(index) + 1) % nphi_) * 2 + getEta(index);
0049       else  //eta overlap, or 4-small-region overlap
0050         return getPhi(index) * 2 + getEta(index) + 1;
0051     case 2:
0052       return ((getPhi(index) + 1) % nphi_) * 2 + getEta(index);
0053     case 3:
0054       return ((getPhi(index) + 1) % nphi_) * 2 + getEta(index) + 1;
0055     default:
0056       dbgCout() << "Impossible object count!" << std::endl;
0057       exit(0);
0058   }
0059 }
0060 
0061 template <typename T>
0062 int l1ct::tdr_regionizer::Pipe<T>::getPipeIndexForObject(unsigned int index) {
0063   switch (getCount(index)) {
0064     case 0:
0065       return getPhi(index);
0066     case 1:
0067       if (getPhiOverlap(index) && !getEtaOverlap(index))
0068         return (getPhi(index) + 1) % nphi_;
0069       else
0070         return getPhi(index);
0071     case 2:
0072     case 3:
0073       return (getPhi(index) + 1) % nphi_;
0074     default:
0075       dbgCout() << "Impossible object count!" << std::endl;
0076       exit(0);
0077   }
0078 }
0079 
0080 template <typename T>
0081 l1ct::tdr_regionizer::Regionizer<T>::Regionizer(
0082     unsigned int neta, unsigned int nregions, unsigned int maxobjects, int etaoffset, int etawidth, int nclocks)
0083     : neta_(neta),
0084       nregions_(nregions),
0085       maxobjects_(maxobjects),
0086       nsectors_(0),
0087       etaoffset_(etaoffset),
0088       etawidth_(etawidth),
0089       nclocks_(nclocks) {
0090   smallRegionObjects_.resize(nregions);
0091 }
0092 
0093 template <typename T>
0094 void l1ct::tdr_regionizer::Regionizer<T>::initSectors(const std::vector<DetectorSector<T>>& sectors) {
0095   assert(nsectors_ == 0);
0096   nsectors_ = sectors.size();
0097   sectors_.resize(nsectors_);
0098   pipes_.resize(nsectors_);
0099   for (unsigned int i = 0; i < nsectors_; ++i) {
0100     sectors_[i] = sectors[i].region;
0101   }
0102 }
0103 
0104 template <typename T>
0105 void l1ct::tdr_regionizer::Regionizer<T>::initSectors(const DetectorSector<T>& sector) {
0106   assert(nsectors_ == 0);
0107   nsectors_ = 1;
0108   sectors_.resize(1, sector.region);
0109   pipes_.resize(nsectors_);
0110 }
0111 
0112 template <typename T>
0113 void l1ct::tdr_regionizer::Regionizer<T>::initRegions(const std::vector<PFInputRegion>& regions) {
0114   regions_.resize(regions.size());
0115   regionmap_.clear();
0116   for (unsigned int i = 0; i < regions.size(); ++i) {
0117     regions_[i] = regions[i].region;
0118     if (etaoffset_ - etawidth_ <= regions_[i].intEtaCenter() && regions_[i].intEtaCenter() < etaoffset_ + etawidth_) {
0119       regionmap_.emplace_back(i, regions_[i].intPhiCenter(), regions_[i].intEtaCenter());
0120     }
0121   }
0122   assert(regionmap_.size() == nregions_);
0123   std::sort(regionmap_.begin(), regionmap_.end(), sortRegionInfo);
0124 }
0125 
0126 template <typename T>
0127 bool l1ct::tdr_regionizer::Regionizer<T>::setIndicesOverlaps(const T& obj,
0128                                                              unsigned int& phiindex,
0129                                                              unsigned int& etaindex,
0130                                                              bool& phioverlap,
0131                                                              bool& etaoverlap,
0132                                                              int& glbphi,
0133                                                              int& glbeta,
0134                                                              unsigned int index) {
0135   glbphi = sectors_[index].hwGlbPhiOf(obj).to_int();
0136   glbeta = sectors_[index].hwGlbEtaOf(obj).to_int();
0137   phiindex = nregions_;
0138   etaindex = nregions_;
0139   phioverlap = false;
0140   etaoverlap = false;
0141   bool isset = false;
0142   for (unsigned int i = 0; i < nregions_; i++) {
0143     int regphi = dphi_wrap(glbphi - regionmap_[i].phi);
0144     int regeta = glbeta - regionmap_[i].eta;
0145 
0146     if (regions_[regionmap_[i].index].isInside(regeta, regphi)) {
0147       if (isset) {
0148         if (i / neta_ != phiindex)
0149           phioverlap = true;
0150         if (i % neta_ != etaindex)
0151           etaoverlap = true;
0152       }
0153       if (i / neta_ < phiindex || (i > (nregions_ - neta_) && phiindex == 0)) {
0154         phiindex = i / neta_;
0155       }
0156       if (i % neta_ < etaindex) {
0157         etaindex = i % neta_;
0158         isset = true;  //only need to check eta to set since there is full coverage in each board in phi
0159       }
0160     }
0161   }
0162   if (isset && etaindex == 1 && etaoverlap) {
0163     etaoverlap = false;
0164   }
0165   return isset;
0166 }
0167 
0168 template <typename T>
0169 void l1ct::tdr_regionizer::Regionizer<T>::addToPipe(const T& obj, unsigned int index) {
0170   assert(index < getSize());
0171   unsigned int phiindex, etaindex;
0172   bool phioverlap, etaoverlap;
0173   int glbphi, glbeta;
0174   bool isset = setIndicesOverlaps(obj, phiindex, etaindex, phioverlap, etaoverlap, glbphi, glbeta, index);
0175   if (isset) {
0176     pipes_[index].addObj(obj, phiindex, etaindex, phioverlap, etaoverlap, glbphi, glbeta);
0177   }
0178 }
0179 
0180 template <typename T>
0181 void l1ct::tdr_regionizer::Regionizer<T>::setPipe(const std::vector<T>& objvec, unsigned int index) {
0182   assert(index < getSize());
0183   pipes_[index].reset();
0184   for (unsigned int i = 0; i < objvec.size(); i++) {
0185     addToPipe(objvec[i], index);
0186   }
0187 }
0188 
0189 template <typename T>
0190 void l1ct::tdr_regionizer::Regionizer<T>::setPipes(const std::vector<std::vector<T>>& objvecvec) {
0191   assert(getSize() == objvecvec.size());
0192   for (unsigned int i = 0; i < getSize(); i++) {
0193     setPipe(objvecvec[i], i);
0194   }
0195 }
0196 
0197 template <typename T>
0198 int l1ct::tdr_regionizer::Regionizer<T>::getPipeTime(int linkIndex,
0199                                                      int linkTimeOfObject,
0200                                                      int linkAlgoClockRunningTime) {
0201   const int LINK_TO_ALGO_CLK_OFFSET = 2;  //13; // in units of algo clock
0202   int linkObjectArrival = (nsectors_ - 1 - linkIndex) + LINK_TO_ALGO_CLK_OFFSET + linkTimeOfObject;
0203 
0204   return (linkAlgoClockRunningTime < 0 || linkObjectArrival > linkAlgoClockRunningTime + 4)
0205              ? linkObjectArrival
0206              : (linkAlgoClockRunningTime + 4);
0207 }
0208 
0209 template <typename T>
0210 int l1ct::tdr_regionizer::Regionizer<T>::popLinkObject(int linkIndex, int currentTimeOfObject) {
0211   pipes_[linkIndex].incCount();
0212 
0213   //determine which object is next and at what time
0214   unsigned int countToBeDone = 1;
0215   if (pipes_[linkIndex].getPhiOverlap() && pipes_[linkIndex].getEtaOverlap())
0216     countToBeDone = 4;
0217   else if (pipes_[linkIndex].getPhiOverlap() || pipes_[linkIndex].getEtaOverlap())
0218     countToBeDone = 2;
0219 
0220   if (countToBeDone == pipes_[linkIndex].getCount()) {
0221     //pop off leading object, done with it
0222     pipes_[linkIndex].erase();
0223 
0224     //get time of next object
0225     if (pipes_[linkIndex].getSize())
0226       return getPipeTime(linkIndex, pipes_[linkIndex].getClock(), currentTimeOfObject);
0227     else  //no more objects on link
0228       return -1;
0229   } else {
0230     //increment time for next overlapped object on this link
0231     return currentTimeOfObject + 1;
0232   }
0233 }
0234 
0235 template <typename T>
0236 void l1ct::tdr_regionizer::Regionizer<T>::initTimes() {
0237   for (unsigned int l = 0; l < getSize(); ++l) {
0238     if (getPipeSize(l)) {
0239       timeOfNextObject_.push_back(timeNextFromIndex(l, -1));
0240     } else {
0241       timeOfNextObject_.push_back(-1);
0242     }
0243   }
0244 }
0245 
0246 template <typename T>
0247 void l1ct::tdr_regionizer::Regionizer<T>::addToSmallRegion(unsigned int linkNum, unsigned int index) {
0248   T theobj = pipes_[linkNum].getRawObj(index);
0249   unsigned int regind = getClosedIndexForObject(linkNum);
0250   theobj.hwPhi = dphi_wrap(pipes_[linkNum].getGlbPhi(index) - regionmap_[regind].phi);
0251   theobj.hwEta = pipes_[linkNum].getGlbEta(index) - regionmap_[regind].eta;
0252   smallRegionObjects_[regind].push_back(theobj);
0253 }
0254 
0255 template <typename T>
0256 void l1ct::tdr_regionizer::Regionizer<T>::run(bool debug) {
0257   unsigned int loopCount = 0;
0258   if (debug)
0259     printDebug(loopCount);
0260   while (loopCount < 972) {  //this is the max allowable if nothing ever blocks
0261     //init min time, pipe, and link index
0262     //      to find the target pipe currently with action
0263     int minp = -1;
0264     int minl = -1;
0265     int minTime = 0;
0266 
0267     //do pipe-full handling
0268     for (unsigned int l = 0; l < getSize(); ++l) {
0269       if (timeOfNextObject_[l] >= 0 && smallRegionObjects_[getClosedIndexForObject(l)].size() == maxobjects_) {
0270         //pipe is full so proceed to next object
0271         //'remove' the selected object from its link
0272         timeOfNextObject_[l] = popLinkObject(l, timeOfNextObject_[l]);
0273       }  //end pipe-full handling loop
0274     }
0275 
0276     //do find object handling
0277     for (unsigned int l = 0; l < getSize(); ++l) {
0278       if (timeOfNextObject_[l] >= 0 && (minl == -1 || timeOfNextObject_[l] < minTime)) {
0279         //found new 'selected' link object and pipe
0280         minp = getPipeIndexForObject(l);
0281         minTime = timeOfNextObject_[l];
0282         minl = l;
0283       } else if (getPipeSize(l) && minl >= 0 && minp == getPipeIndexForObject(l) && timeOfNextObject_[l] == minTime) {
0284         //have pipe conflict, so need to wait a clock
0285         ++timeOfNextObject_[l];
0286       }
0287     }
0288 
0289     if (minl < 0)
0290       break;  //exit case
0291 
0292     //'put' object in small region
0293     addToSmallRegion(minl);
0294 
0295     //'remove' the selected object from its link
0296     int nextTime = popLinkObject(minl, timeOfNextObject_[minl]);
0297     if (nextTime > nclocks_)
0298       break;
0299     timeOfNextObject_[minl] = nextTime;
0300     ++loopCount;
0301   }  //end main loop
0302 
0303   if (debug)
0304     printDebug(loopCount);
0305 }
0306 
0307 template <typename T>
0308 void l1ct::tdr_regionizer::Regionizer<T>::reset() {
0309   for (unsigned int i = 0; i < getSize(); i++) {
0310     pipes_[i].reset();
0311   }
0312   timeOfNextObject_.clear();
0313   for (unsigned int i = 0; i < nregions_; i++) {
0314     smallRegionObjects_[i].clear();
0315   }
0316 }
0317 
0318 template <typename T>
0319 std::vector<T> l1ct::tdr_regionizer::Regionizer<T>::getSmallRegion(unsigned int index) {
0320   for (unsigned int i = 0; i < nregions_; i++) {
0321     if (regionmap_[i].index == index)
0322       return smallRegionObjects_[i];
0323   }
0324   return {};
0325 }