Skip to content

Commit

Permalink
Merge pull request cms-sw#112 from jmitrevs/barrel_emu
Browse files Browse the repository at this point in the history
Update the TDR regionizer to be segmented in phi instead of eta.
  • Loading branch information
gpetruc authored Mar 13, 2023
2 parents 1340dc6 + 0024ec8 commit e2d295b
Show file tree
Hide file tree
Showing 5 changed files with 404 additions and 427 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#include "DataFormats/L1TParticleFlow/interface/layer1_emulator.h"

#include <list>
#include <vector>
#include <map>
#include <cassert>
#include <algorithm>

Expand All @@ -25,58 +25,32 @@ namespace l1ct {
return local_phi;
}

struct RegionInfo {
RegionInfo(unsigned int idx, int regphi, int regeta) : index(idx), phi(regphi), eta(regeta) {}
unsigned int index;
int phi;
int eta;
};

inline bool sortRegionInfo(RegionInfo& a, RegionInfo& b) {
if (a.phi < b.phi)
return true;
if (a.phi > b.phi)
return false;
if (a.eta < b.eta)
return true;
if (a.eta > b.eta)
return false;
return false;
}

// These are done per-sector (= per-input link)
template <typename T>
class PipeObject {
public:
PipeObject() {}
PipeObject(const T& obj,
unsigned int phiindex,
unsigned int etaindex,
bool phioverlap,
bool etaoverlap,
int glbphi,
int glbeta,
unsigned int clk);

const unsigned int getClock() { return linkobjclk_; }
PipeObject(const T& obj, std::vector<size_t> srIndices, int glbphi, int glbeta, unsigned int clk);

unsigned int getClock() const { return linkobjclk_; }
void setClock(unsigned int clock) { linkobjclk_ = clock; }
const unsigned int getPhi() { return phiindex_; }
const unsigned int getEta() { return etaindex_; }
const bool getPhiOverlap() { return phioverlap_; }
const bool getEtaOverlap() { return etaoverlap_; }
const unsigned int getCount() { return objcount_; }
unsigned int getCountAndInc() { return objcount_++; }
const std::vector<size_t>& getSRIndices() const { return srIndices_; }
size_t getNextSRIndex() const { return srIndices_.at(objcount_); }
unsigned int getCount() const { return objcount_; }
void incCount() { objcount_++; }
const int getPt() { return obj_.hwPt.to_int(); }
const int getGlbPhi() { return glbphi_; }
const int getGlbEta() { return glbeta_; }
int getPt() const { return obj_.hwPt.to_int(); }
int getGlbPhi() const { return glbphi_; }
int getGlbEta() const { return glbeta_; }

T getObj() { return obj_; }
T& getRawObj() { return obj_; }
const T& getRawObj() const { return obj_; }

private:
T obj_;
unsigned int phiindex_, etaindex_;
bool phioverlap_, etaoverlap_;
int glbphi_, glbeta_;
/// the SR linearized indices (can index regionmap_) where this object needs to go
std::vector<size_t> srIndices_;
/// The global eta and phi of the object (somewhat redundant with obj_)
int glbeta_, glbphi_;
unsigned int linkobjclk_, objcount_;
};

Expand All @@ -85,29 +59,25 @@ namespace l1ct {
public:
Pipe(unsigned int nphi = 9) : clkindex_(0), nphi_(nphi) {}

void addObj(
T obj, unsigned int phiindex, unsigned int etaindex, bool phioverlap, bool etaoverlap, int glbphi, int glbeta);
PipeObject<T>& getObj(unsigned int index) { return data_[index]; }
T getRawObj(unsigned int index) { return data_[index].getObj(); }
void addObj(T obj, std::vector<size_t> srs, int glbeta, int glbphi);

unsigned int getClock(unsigned int index = 0) { return getObj(index).getClock(); }
PipeObject<T>& getObj(unsigned int index = 0) { return data_[index]; }
const PipeObject<T>& getObj(unsigned int index = 0) const { return data_[index]; }

unsigned int getClock(unsigned int index = 0) const { return getObj(index).getClock(); }
void setClock(unsigned int clock, unsigned int index = 0) { return getObj(index).setClock(clock); }
unsigned int getPhi(unsigned int index = 0) { return getObj(index).getPhi(); }
unsigned int getEta(unsigned int index = 0) { return getObj(index).getEta(); }
bool getPhiOverlap(unsigned int index = 0) { return getObj(index).getPhiOverlap(); }
bool getEtaOverlap(unsigned int index = 0) { return getObj(index).getEtaOverlap(); }
unsigned int getCount(unsigned int index = 0) { return getObj(index).getCount(); }
unsigned int getCountAndInc(unsigned int index = 0) { return getObj(index).getCountAndInc(); }
unsigned int getCount(unsigned int index = 0) const { return getObj(index).getCount(); }
void incCount(unsigned int index = 0) { getObj(index).incCount(); }
void erase(unsigned int index = 0) { data_.erase(data_.begin() + index); }
int getPt(unsigned int index = 0) { return getObj(index).getPt(); }
int getGlbPhi(unsigned int index = 0) { return getObj(index).getGlbPhi(); }
int getGlbEta(unsigned int index = 0) { return getObj(index).getGlbEta(); }
int getPt(unsigned int index = 0) const { return getObj(index).getPt(); }
int getGlbPhi(unsigned int index = 0) const { return getObj(index).getGlbPhi(); }
int getGlbEta(unsigned int index = 0) const { return getObj(index).getGlbEta(); }

int getClosedIndexForObject(unsigned int index = 0);
int getPipeIndexForObject(unsigned int index = 0);
/// This returns the hardware pipe index (since there are one per SR pair)
size_t getPipeIndexForObject(unsigned int index = 0);

unsigned int getSize() { return data_.size(); }
unsigned int getPipeSize() const { return data_.size(); }

void reset() {
clkindex_ = 0;
Expand All @@ -123,85 +93,110 @@ namespace l1ct {
class Regionizer {
public:
Regionizer() {}
Regionizer(
unsigned int neta, unsigned int nregions, unsigned int maxobjects, int etaoffset, int etawidth, int nclocks);
Regionizer(unsigned int neta,
unsigned int nphi, //the number of eta and phi SRs in a big region (board)
unsigned int nregions, // The total number of small regions in the full barrel
unsigned int maxobjects,
int bigRegionMin,
int bigRegionMax, // the phi range covered by this board
int nclocks);

void initSectors(const std::vector<DetectorSector<T>>& sectors);
void initSectors(const DetectorSector<T>& sector);
void initRegions(const std::vector<PFInputRegion>& regions);

unsigned int getSize() { return pipes_.size(); }
unsigned int getPipeSize(unsigned int index) { return getPipe(index).getSize(); }
// is the given small region in the big region
bool isInBigRegion(const PFRegionEmu& reg) const;

unsigned int getSize() const { return pipes_.size(); }
unsigned int getPipeSize(unsigned int linkIndex) const { return pipes_[linkIndex].getPipeSize(); }

bool setIndicesOverlaps(const T& obj,
unsigned int& phiindex,
unsigned int& etaindex,
bool& phioverlap,
bool& etaoverlap,
int& glbphi,
int& glbeta,
unsigned int index);
std::vector<size_t> getSmallRegions(int glbeta, int glbphi) const;

void addToPipe(const T& obj, unsigned int index);
void setPipe(const std::vector<T>& objvec, unsigned int index);
void setPipes(const std::vector<std::vector<T>>& objvecvec);
Pipe<T>& getPipe(unsigned int index) { return pipes_[index]; }

// linkIndex == sector
int getPipeTime(int linkIndex, int linkTimeOfObject, int linkAlgoClockRunningTime);

/// This either removes the next object on the link or inrements the count; It returns the next time
int popLinkObject(int linkIndex, int currentTimeOfObject);
int timeNextFromIndex(unsigned int index, int time) { return getPipeTime(index, pipes_[index].getClock(), time); }
int timeNextFromIndex(unsigned int linkIndex, int time) {
return getPipeTime(linkIndex, pipes_[linkIndex].getClock(), time);
}

void initTimes();

int getClosedIndexForObject(unsigned int linknum, unsigned int index = 0) {
return pipes_[linknum].getClosedIndexForObject(index);
}
int getPipeIndexForObject(unsigned int linknum, unsigned int index = 0) {

/// This retruns the linearized small region associated with the given item
size_t getPipeIndexForObject(unsigned int linknum, unsigned int index = 0) {
return pipes_[linknum].getPipeIndexForObject(index);
}

/// This returns the hardware pipe number of the item. Generally two SRs share a pipe
size_t getHardwarePipeIndexForObject(unsigned int linknum, unsigned int index = 0) {
return getHardwarePipeIndex(getPipeIndexForObject(linknum, index));
}

/// 'put' object in small region
void addToSmallRegion(unsigned int linkNum, unsigned int index = 0);

void run(bool debug = false);

void reset();

std::vector<T> getSmallRegion(unsigned int index);

void printDebug(int count) {
dbgCout() << count << "\tindex\tpt\teta\tphi" << std::endl;
dbgCout() << "PIPES" << std::endl;
for (unsigned int i = 0; i < getSize(); i++) {
for (unsigned int j = 0; j < getPipeSize(i); j++) {
dbgCout() << "\t" << i << " " << j << "\t" << getPipe(i).getPt(j) << "\t" << getPipe(i).getGlbEta(j) << "\t"
<< getPipe(i).getGlbPhi(j) << std::endl;
}
dbgCout() << "-------------------------------" << std::endl;
}
dbgCout() << "SMALL REGIONS" << std::endl;
for (unsigned int i = 0; i < nregions_; i++) {
for (unsigned int j = 0; j < smallRegionObjects_[i].size(); j++) {
dbgCout() << "\t" << i << " " << j << "\t" << smallRegionObjects_[i][j].hwPt.to_int() << "\t"
<< smallRegionObjects_[i][j].hwEta.to_int() + regionmap_[i].eta << "\t"
<< smallRegionObjects_[i][j].hwPhi.to_int() + regionmap_[i].phi << std::endl;
}
dbgCout() << "-------------------------------" << std::endl;
}
dbgCout() << "TIMES" << std::endl;
for (unsigned int i = 0; i < timeOfNextObject_.size(); i++) {
dbgCout() << " " << timeOfNextObject_[i];
}
dbgCout() << "\n-------------------------------" << std::endl;
}
/// Return a map of of the SRs indexed by SR index (covering only those from board)
std::map<size_t, std::vector<T>> fillRegions(bool doSort);

void printDebug(int count) const;

private:
unsigned int neta_, nregions_, maxobjects_, nsectors_;
int etaoffset_, etawidth_, nclocks_;
/// SRs share RAMs (and hardware pipes)
static size_t constexpr SRS_PER_RAM = 2;

/// Because some SRs share pipes, this determines the pipe index for a linearize SR index
/// (This is based on the VHDL function, get_target_pipe_index_subindex)
size_t getHardwarePipeIndex(size_t srIndex) const { return srIndex / SRS_PER_RAM; }

// this function is for sorting small regions first in phi and then in eta.
// It takes regions_ indices
bool sortRegionsRegular(size_t a, size_t b) const;

/// The numbers of eta and phi in a big region (board)
unsigned int neta_, nphi_;
/// The total number of small regions in the barrel (not just in the board)
unsigned int nregions_;
/// The maximum number of objects to output per small region
unsigned int maxobjects_;
/// The number of input sectors for this type of device
unsigned int nsectors_;
/// the minimumum phi of this board
int bigRegionMin_;
/// the maximum phi of this board
int bigRegionMax_;
/// the number of clocks to receive one event
int nclocks_;

/// the region information assopciated with each input sector
std::vector<l1ct::PFRegionEmu> sectors_;

/// the region information associated with each SR
std::vector<l1ct::PFRegionEmu> regions_;
std::vector<RegionInfo> regionmap_;

/// indices of regions that are in the big region (board)
std::vector<size_t> regionmap_;

/// One pipe per each sector (link). These do not correspond to the firmware pipes
std::vector<Pipe<T>> pipes_;
/// One entry per sector (= link = pipe). If the pipe is empty, this is always -1
std::vector<int> timeOfNextObject_;
std::vector<std::vector<T>> smallRegionObjects_; //keep count to see if small region is full

/// The objects in each small region handled in board; Indexing corresponds to that in regionmap_
std::vector<std::vector<T>> smallRegionObjects_;
};

} // namespace tdr_regionizer
Expand Down
Loading

0 comments on commit e2d295b

Please sign in to comment.