CMS 3D CMS Logo

MuxHToutputs.cc
Go to the documentation of this file.
1 //--- Note that the word "link" appearing in the C++ or comments in this class actually corresponds
2 //--- to a pair of links in the hardware.
3 
7 
9 
10 #include <sstream>
11 #include <mutex>
12 
13 using namespace std;
14 
15 namespace tmtt {
16 
17  //=== Initialize constants from configuration parameters.
18 
19  MuxHToutputs::MuxHToutputs(const Settings* settings)
20  : settings_(settings),
21  muxOutputsHT_(static_cast<MuxAlgoName>(settings_->muxOutputsHT())),
22  numPhiNonants_(settings_->numPhiNonants()),
23  numPhiSectors_(settings_->numPhiSectors()),
24  numPhiSecPerNon_(numPhiSectors_ / numPhiNonants_),
25  numEtaRegions_(settings_->numEtaRegions()),
26  busySectorKill_(settings_->busySectorKill()), // Kill excess tracks flowing out of HT?
27  busySectorNumStubs_(settings_->busySectorNumStubs()), // Max. num. of stubs that can be sent within TM period
28  busySectorMbinRanges_(
29  settings_->busySectorMbinRanges()), // Individual m bin (=q/Pt) ranges to be output to opto-links.
30  busySectorUseMbinRanges_(not busySectorMbinRanges_.empty()) // m bin ranges option disabled if vector empty.
31  {
32  // Implemented MUX algorithm relies on same number of sectors per nonant.
33  if (numPhiSectors_ % numPhiNonants_ != 0)
34  throw cms::Exception("BadConfig")
35  << "MuxHToutputs: Number of phi sectors is not a multiple of number of nonants!";
36 
38  throw cms::Exception("BadConfig") << "MuxHToutputs: The implemented MUX algorithm requires you to be using the "
39  "busySectorMbinRanges cfg option!";
40 
41  // Check that the MUX algorithm implemented in linkID() is not obviously wrong.
42  this->sanityCheck();
43 
44  std::stringstream text;
45  text << "=== The R-PHI HT output is multiplexed onto " << this->numLinksPerNonant()
46  << " pairs of opto-links per nonant.";
47  static std::once_flag printOnce;
48  std::call_once(
49  printOnce, [](string t) { PrintL1trk() << t; }, text.str());
50  }
51 
52  //=== Determine which tracks are transmitted on each HT output optical link, taking into account the multiplexing
53  //=== of multiple (eta,phi) sectors onto single links and the truncation of the tracks caused by the requirement
54  //=== to output all the tracks within the time-multiplexed period.
55  //=== This function replaces the 2D track collection in the r-phi HT with the subset surviving the TM cut.
56 
57  void MuxHToutputs::exec(Array2D<unique_ptr<HTrphi>>& mHtRphis) const {
58  // As this loops over sectors in order of increasing sector number, this MUX algorithm always transmits tracks
59  // from the lowest sector numbers on each link first. So the highest sector numbers are more likely to be
60  // truncated by the TM period. The algorithm assumes that two or more m-bin ranges from the same sector will never
61  // be transmitted down the same link, as if this happens, it does not predict the order in which they will be
62  // transmitted.
63 
64  for (unsigned int iPhiNon = 0; iPhiNon < numPhiNonants_; iPhiNon++) {
65  vector<unsigned int> numStubsPerLink(this->numLinksPerNonant(), 0);
66 
67  for (unsigned int iSecInNon = 0; iSecInNon < numPhiSecPerNon_; iSecInNon++) {
68  unsigned int iPhiSec = iPhiNon * numPhiSecPerNon_ + iSecInNon;
69 
70  for (unsigned int iEtaReg = 0; iEtaReg < numEtaRegions_; iEtaReg++) {
71  HTrphi* htRphi = mHtRphis(iPhiSec, iEtaReg).get(); // Get a mutable version of the r-phi HT.
72 
73  list<L1track2D> keptTracks;
74  const list<L1track2D>& tracks = htRphi->trackCands2D();
75 
76  for (const L1track2D& trk : tracks) {
77  L1track2D trkTmp = trk;
78  unsigned int nStubs = trkTmp.numStubs(); // #stubs on this track.
79  unsigned int mBinRange = htRphi->getMbinRange(trkTmp); // Which m bin range is this track in?
80  // Get the output optical link corresponding to this sector & m-bin range.
81  unsigned int link = this->linkID(iSecInNon, iEtaReg, mBinRange);
82  // Make a note of opto-link number inside track object.
83  trkTmp.setOptoLinkID(link);
84 
85  numStubsPerLink[link] += nStubs;
86  // Check if this track can be output within the time-multiplexed period.
87  bool keep = ((not busySectorKill_) || (numStubsPerLink[link] <= busySectorNumStubs_));
88  // FIX: with 2 GeV threshold, this causes significant truncation.
89  // Consider using one output link for each phi sector in nonant
90  if (keep)
91  keptTracks.push_back(trkTmp);
92  }
93 
94  // Replace the collection of 2D tracks in the r-phi HT with the subset of them surviving the TM cut.
95  htRphi->replaceTrackCands2D(keptTracks);
96  }
97  }
98  }
99  }
100 
101  //=== Define the number of (eta,phi) sectors that each output opto-link takes tracks from. (Depends on MUX scheme).
102 
103  unsigned int MuxHToutputs::muxFactor() const {
106  } else {
107  throw cms::Exception("BadConfig") << "MuxHToutputs: Unknown MuxOutputsHT configuration option!";
108  }
109  }
110 
111  //=== Define the MUX algorithm by which tracks from the specified m-bin range in the HT for a given (phi,eta)
112  //=== sector within a phi nonant are multiplexed onto a single output optical link.
113 
114  unsigned int MuxHToutputs::linkID(unsigned int iSecInNon, unsigned int iEtaReg, unsigned int mBinRange) const {
115  unsigned int link;
116 
118  //--- This is the Sept. 2019 Mux for the transverse HT readout organised by m-bin. (Each m bin in entire nonant goes to a different link).
119 
120  link = 0;
121  link += mBinRange;
122 
123  } else {
124  throw cms::Exception("BadConfig") << "MuxHToutputs: Unknown MuxOutputsHT configuration option!";
125  }
126 
127  if (link >= this->numLinksPerNonant())
128  throw cms::Exception("LogicError") << "MuxHToutputs: Calculated link ID exceeded expected number of links! "
129  << link << " " << this->numLinksPerNonant();
130  return link;
131  }
132 
133  //=== Do sanity check of the MUX algorithm implemented in linkID().
134 
136  if (numPhiSecPerNon_ * numEtaRegions_ % this->muxFactor() != 0)
137  throw cms::Exception("LogicError")
138  << "MuxHToutputs: Number of sectors per phi nonant is not a multiple of muxFactor().";
139 
140  vector<unsigned int> nObsElementsPerLink(this->numLinksPerNonant(), 0);
141  for (unsigned int iSecInNon = 0; iSecInNon < numPhiSecPerNon_; iSecInNon++) {
142  for (unsigned int iEtaReg = 0; iEtaReg < numEtaRegions_; iEtaReg++) {
143  unsigned int iCorr = (settings_->miniHTstage()) ? 1 : 0;
144  for (unsigned int mBinRange = 0; mBinRange < busySectorMbinRanges_.size() - iCorr; mBinRange++) {
145  unsigned int link = this->linkID(iSecInNon, iEtaReg, mBinRange);
146  nObsElementsPerLink[link] += 1;
147  }
148  }
149  }
150  }
151 
152 } // namespace tmtt
bool miniHTstage() const
Definition: Settings.h:149
unsigned int numEtaRegions_
Definition: MuxHToutputs.h:66
unsigned int numStubs() const override
Definition: L1track2D.h:59
void setOptoLinkID(unsigned int linkID)
Definition: L1track2D.h:95
void exec(Array2D< std::unique_ptr< HTrphi >> &mHtRphis) const
Definition: MuxHToutputs.cc:57
unsigned int busySectorNumStubs_
Definition: MuxHToutputs.h:68
std::vector< unsigned int > busySectorMbinRanges_
Definition: MuxHToutputs.h:69
unsigned int numLinksPerNonant() const
Definition: MuxHToutputs.h:42
unsigned int numPhiNonants_
Definition: MuxHToutputs.h:63
bool busySectorUseMbinRanges_
Definition: MuxHToutputs.h:70
unsigned int numPhiSecPerNon_
Definition: MuxHToutputs.h:65
unsigned int muxFactor() const
=== This is the base class for the linearised chi-squared track fit algorithms.
Definition: Array2D.h:16
virtual void replaceTrackCands2D(const std::list< L1track2D > &newTracks)
Definition: HTbase.h:70
virtual const std::list< L1track2D > & trackCands2D() const
Definition: HTbase.h:54
unsigned int getMbinRange(const L1track2D &trk) const
Definition: HTrphi.cc:317
unsigned int linkID(unsigned int iSecInNon, unsigned int iEtaReg, unsigned int mBinRange) const
unsigned int numPhiSectors_
Definition: MuxHToutputs.h:64
const Settings * settings_
Definition: MuxHToutputs.h:59
MuxAlgoName muxOutputsHT_
Definition: MuxHToutputs.h:62