CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DTC.cc
Go to the documentation of this file.
2 
3 #include <vector>
4 #include <iterator>
5 #include <algorithm>
6 #include <numeric>
7 
8 using namespace std;
9 using namespace edm;
10 
11 namespace trackerDTC {
12 
13  DTC::DTC(const ParameterSet& iConfig,
14  const Setup& setup,
15  int dtcId,
16  const std::vector<std::vector<TTStubRef>>& stubsDTC)
17  : setup_(&setup),
18  enableTruncation_(iConfig.getParameter<bool>("EnableTruncation")),
19  region_(dtcId / setup.numDTCsPerRegion()),
20  board_(dtcId % setup.numDTCsPerRegion()),
21  modules_(setup.dtcModules(dtcId)),
22  input_(setup.dtcNumRoutingBlocks(), Stubss(setup.dtcNumModulesPerRoutingBlock())),
23  lost_(setup.numOverlappingRegions()) {
24  // count number of stubs on this dtc
25  auto acc = [](int& sum, const vector<TTStubRef>& stubsModule) { return sum += stubsModule.size(); };
26  const int nStubs = accumulate(stubsDTC.begin(), stubsDTC.end(), 0, acc);
27  stubs_.reserve(nStubs);
28  // convert and assign Stubs to DTC routing block channel
29  for (int modId = 0; modId < setup.numModulesPerDTC(); modId++) {
30  const vector<TTStubRef>& ttStubRefs = stubsDTC[modId];
31  if (ttStubRefs.empty())
32  continue;
33  // Module which produced this ttStubRefs
34  SensorModule* module = modules_.at(modId);
35  // DTC routing block id [0-1]
36  const int blockId = modId / setup.dtcNumModulesPerRoutingBlock();
37  // DTC routing blockc channel id [0-35]
38  const int channelId = modId % setup.dtcNumModulesPerRoutingBlock();
39  // convert TTStubs and fill input channel
40  Stubs& stubs = input_[blockId][channelId];
41  for (const TTStubRef& ttStubRef : ttStubRefs) {
42  stubs_.emplace_back(iConfig, setup, module, ttStubRef);
43  Stub& stub = stubs_.back();
44  if (stub.valid())
45  // passed pt and eta cut
46  stubs.push_back(&stub);
47  }
48  // sort stubs by bend
49  sort(stubs.begin(), stubs.end(), [](Stub* lhs, Stub* rhs) { return abs(lhs->bend()) < abs(rhs->bend()); });
50  // truncate stubs if desired
51  if (!enableTruncation_ || (int)stubs.size() <= setup.numFramesFE())
52  continue;
53  // begin of truncated stubs
54  const auto limit = next(stubs.begin(), setup.numFramesFE());
55  // copy truncated stubs into lost output channel
56  for (int region = 0; region < setup.numOverlappingRegions(); region++)
57  copy_if(
58  limit, stubs.end(), back_inserter(lost_[region]), [region](Stub* stub) { return stub->inRegion(region); });
59  // remove truncated stubs form input channel
60  stubs.erase(limit, stubs.end());
61  }
62  }
63 
64  // board level routing in two steps and products filling
65  void DTC::produce(TTDTC& productAccepted, TTDTC& productLost) {
66  // router step 1: merges stubs of all modules connected to one routing block into one stream
67  Stubs lost;
68  Stubss blockStubs(setup_->dtcNumRoutingBlocks());
69  for (int routingBlock = 0; routingBlock < setup_->dtcNumRoutingBlocks(); routingBlock++)
70  merge(input_[routingBlock], blockStubs[routingBlock], lost);
71  // copy lost stubs during merge into lost output channel
72  for (int region = 0; region < setup_->numOverlappingRegions(); region++) {
73  auto inRegion = [region](Stub* stub) { return stub->inRegion(region); };
74  copy_if(lost.begin(), lost.end(), back_inserter(lost_[region]), inRegion);
75  }
76  // router step 2: merges stubs of all routing blocks and splits stubs into one stream per overlapping region
77  Stubss regionStubs(setup_->numOverlappingRegions());
78  split(blockStubs, regionStubs);
79  // fill products
80  produce(regionStubs, productAccepted);
81  produce(lost_, productLost);
82  }
83 
84  // router step 1: merges stubs of all modules connected to one routing block into one stream
86  // for each input one fifo
87  Stubss stacks(inputs.size());
88  // clock accurate firmware emulation, each while trip describes one clock tick
89  while (!all_of(inputs.begin(), inputs.end(), [](const Stubs& channel) { return channel.empty(); }) or
90  !all_of(stacks.begin(), stacks.end(), [](const Stubs& channel) { return channel.empty(); })) {
91  // fill fifos
92  for (int iInput = 0; iInput < (int)inputs.size(); iInput++) {
93  Stubs& input = inputs[iInput];
94  Stubs& stack = stacks[iInput];
95  if (input.empty())
96  continue;
97  Stub* stub = pop_front(input);
98  if (stub) {
99  if (enableTruncation_ && (int)stack.size() == setup_->dtcDepthMemory() - 1)
100  // kill current first stub when fifo overflows
101  lost.push_back(pop_front(stack));
102  stack.push_back(stub);
103  }
104  }
105  // route stub from a fifo to output if possible
106  bool nothingToRoute(true);
107  for (int iInput = inputs.size() - 1; iInput >= 0; iInput--) {
108  Stubs& stack = stacks[iInput];
109  if (stack.empty())
110  continue;
111  nothingToRoute = false;
112  output.push_back(pop_front(stack));
113  // only one stub can be routed to output per clock tick
114  break;
115  }
116  // each clock tick output will grow by one, if no stub is available then by a gap
117  if (nothingToRoute)
118  output.push_back(nullptr);
119  }
120  // truncate if desired
121  if (enableTruncation_ && (int)output.size() > setup_->numFramesIO()) {
122  const auto limit = next(output.begin(), setup_->numFramesIO());
123  copy_if(limit, output.end(), back_inserter(lost), [](Stub* stub) { return stub; });
124  output.erase(limit, output.end());
125  }
126  // remove all gaps between end and last stub
127  for (auto it = output.end(); it != output.begin();)
128  it = (*--it) ? output.begin() : output.erase(it);
129  }
130 
131  // router step 2: merges stubs of all routing blocks and splits stubs into one stream per overlapping region
132  void DTC::split(Stubss& inputs, Stubss& outputs) {
133  int region(0);
134  auto regionMask = [&region](Stub* stub) { return stub && stub->inRegion(region) ? stub : nullptr; };
135  for (Stubs& output : outputs) {
136  // copy of masked inputs for each output
137  Stubss streams(inputs.size());
138  int i(0);
139  for (Stubs& input : inputs) {
140  Stubs& stream = streams[i++];
141  transform(input.begin(), input.end(), back_inserter(stream), regionMask);
142  for (auto it = stream.end(); it != stream.begin();)
143  it = (*--it) ? stream.begin() : stream.erase(it);
144  }
145  merge(streams, output, lost_[region++]);
146  }
147  }
148 
149  // conversion from Stubss to TTDTC
150  void DTC::produce(const Stubss& stubss, TTDTC& product) {
151  int channel(0);
152  auto toFrame = [&channel](Stub* stub) {
153  return stub ? make_pair(stub->ttStubRef(), stub->frame(channel)) : TTDTC::Frame();
154  };
155  for (const Stubs& stubs : stubss) {
157  stream.reserve(stubs.size());
158  transform(stubs.begin(), stubs.end(), back_inserter(stream), toFrame);
159  product.setStream(region_, board_, channel++, stream);
160  }
161  }
162 
163  // pop_front function which additionally returns copy of deleted front
165  Stub* stub = deque.front();
166  deque.pop_front();
167  return stub;
168  }
169 
170 } // namespace trackerDTC
int numModulesPerDTC() const
Definition: Setup.h:225
int dtcNumRoutingBlocks() const
Definition: Setup.h:227
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void produce(TTDTC &accepted, TTDTC &lost)
Definition: DTC.cc:65
void split(Stubss &inputs, Stubss &outputs)
Definition: DTC.cc:132
std::vector< Stub > stubs_
Definition: DTC.h:49
std::vector< Frame > Stream
Definition: TTDTC.h:24
std::vector< Stubs > Stubss
Definition: DTC.h:16
Stub * pop_front(Stubs &stubs)
Definition: DTC.cc:164
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
bool enableTruncation_
Definition: DTC.h:41
static std::string const input
Definition: EdmProvDump.cc:47
std::vector< SensorModule * > modules_
Definition: DTC.h:47
int dtcDepthMemory() const
Definition: Setup.h:229
Stubss lost_
Definition: DTC.h:53
stack
Definition: svgfig.py:559
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int dtcNumModulesPerRoutingBlock() const
Definition: Setup.h:249
int region_
Definition: DTC.h:43
Class to process and provide run-time constants used by Track Trigger emulators.
Definition: Setup.h:41
std::pair< TTStubRef, BV > Frame
Definition: TTDTC.h:22
int numFramesFE() const
Definition: Setup.h:94
int bend() const
Definition: Stub.h:22
Class to store hardware like structured TTStub Collection used by Track Trigger emulators.
Definition: TTDTC.h:17
void setStream(int dtcRegion, int dtcBoard, int dtcChannel, const Stream &stream)
Definition: TTDTC.cc:23
Stubsss input_
Definition: DTC.h:51
int numFramesIO() const
Definition: Setup.h:92
const Setup * setup_
Definition: DTC.h:39
int numOverlappingRegions() const
Definition: Setup.h:221
int board_
Definition: DTC.h:45
void merge(Stubss &inputs, Stubs &output, Stubs &lost)
Definition: DTC.cc:85
std::deque< Stub * > Stubs
Definition: DTC.h:15
tuple module
Definition: callgraph.py:69
bool valid() const
Definition: Stub.h:20
unsigned transform(const HcalDetId &id, unsigned transformCode)