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(printOnce, [](string t) { PrintL1trk() << t; }, text.str());
49  }
50 
51  //=== Determine which tracks are transmitted on each HT output optical link, taking into account the multiplexing
52  //=== of multiple (eta,phi) sectors onto single links and the truncation of the tracks caused by the requirement
53  //=== to output all the tracks within the time-multiplexed period.
54  //=== This function replaces the 2D track collection in the r-phi HT with the subset surviving the TM cut.
55 
56  void MuxHToutputs::exec(Array2D<unique_ptr<HTrphi>>& mHtRphis) const {
57  // As this loops over sectors in order of increasing sector number, this MUX algorithm always transmits tracks
58  // from the lowest sector numbers on each link first. So the highest sector numbers are more likely to be
59  // truncated by the TM period. The algorithm assumes that two or more m-bin ranges from the same sector will never
60  // be transmitted down the same link, as if this happens, it does not predict the order in which they will be
61  // transmitted.
62 
63  for (unsigned int iPhiNon = 0; iPhiNon < numPhiNonants_; iPhiNon++) {
64  vector<unsigned int> numStubsPerLink(this->numLinksPerNonant(), 0);
65 
66  for (unsigned int iSecInNon = 0; iSecInNon < numPhiSecPerNon_; iSecInNon++) {
67  unsigned int iPhiSec = iPhiNon * numPhiSecPerNon_ + iSecInNon;
68 
69  for (unsigned int iEtaReg = 0; iEtaReg < numEtaRegions_; iEtaReg++) {
70  HTrphi* htRphi = mHtRphis(iPhiSec, iEtaReg).get(); // Get a mutable version of the r-phi HT.
71 
72  list<L1track2D> keptTracks;
73  const list<L1track2D>& tracks = htRphi->trackCands2D();
74 
75  for (const L1track2D& trk : tracks) {
76  L1track2D trkTmp = trk;
77  unsigned int nStubs = trkTmp.numStubs(); // #stubs on this track.
78  unsigned int mBinRange = htRphi->getMbinRange(trkTmp); // Which m bin range is this track in?
79  // Get the output optical link corresponding to this sector & m-bin range.
80  unsigned int link = this->linkID(iSecInNon, iEtaReg, mBinRange);
81  // Make a note of opto-link number inside track object.
82  trkTmp.setOptoLinkID(link);
83 
84  numStubsPerLink[link] += nStubs;
85  // Check if this track can be output within the time-multiplexed period.
86  bool keep = ((not busySectorKill_) || (numStubsPerLink[link] <= busySectorNumStubs_));
87  // FIX: with 2 GeV threshold, this causes significant truncation.
88  // Consider using one output link for each phi sector in nonant
89  if (keep)
90  keptTracks.push_back(trkTmp);
91  }
92 
93  // Replace the collection of 2D tracks in the r-phi HT with the subset of them surviving the TM cut.
94  htRphi->replaceTrackCands2D(keptTracks);
95  }
96  }
97  }
98  }
99 
100  //=== Define the number of (eta,phi) sectors that each output opto-link takes tracks from. (Depends on MUX scheme).
101 
102  unsigned int MuxHToutputs::muxFactor() const {
105  } else {
106  throw cms::Exception("BadConfig") << "MuxHToutputs: Unknown MuxOutputsHT configuration option!";
107  }
108  }
109 
110  //=== Define the MUX algorithm by which tracks from the specified m-bin range in the HT for a given (phi,eta)
111  //=== sector within a phi nonant are multiplexed onto a single output optical link.
112 
113  unsigned int MuxHToutputs::linkID(unsigned int iSecInNon, unsigned int iEtaReg, unsigned int mBinRange) const {
114  unsigned int link;
115 
117  //--- 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).
118 
119  link = 0;
120  link += mBinRange;
121 
122  } else {
123  throw cms::Exception("BadConfig") << "MuxHToutputs: Unknown MuxOutputsHT configuration option!";
124  }
125 
126  if (link >= this->numLinksPerNonant())
127  throw cms::Exception("LogicError") << "MuxHToutputs: Calculated link ID exceeded expected number of links! "
128  << link << " " << this->numLinksPerNonant();
129  return link;
130  }
131 
132  //=== Do sanity check of the MUX algorithm implemented in linkID().
133 
135  if (numPhiSecPerNon_ * numEtaRegions_ % this->muxFactor() != 0)
136  throw cms::Exception("LogicError")
137  << "MuxHToutputs: Number of sectors per phi nonant is not a multiple of muxFactor().";
138 
139  vector<unsigned int> nObsElementsPerLink(this->numLinksPerNonant(), 0);
140  for (unsigned int iSecInNon = 0; iSecInNon < numPhiSecPerNon_; iSecInNon++) {
141  for (unsigned int iEtaReg = 0; iEtaReg < numEtaRegions_; iEtaReg++) {
142  unsigned int iCorr = (settings_->miniHTstage()) ? 1 : 0;
143  for (unsigned int mBinRange = 0; mBinRange < busySectorMbinRanges_.size() - iCorr; mBinRange++) {
144  unsigned int link = this->linkID(iSecInNon, iEtaReg, mBinRange);
145  nObsElementsPerLink[link] += 1;
146  }
147  }
148  }
149  }
150 
151 } // 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:56
Trktree trk
Definition: Trktree.cc:2
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:316
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