CMS 3D CMS Logo

GeometricProcessor.cc
Go to the documentation of this file.
2 
3 #include <numeric>
4 #include <algorithm>
5 #include <iterator>
6 #include <deque>
7 #include <vector>
8 
9 using namespace std;
10 using namespace edm;
11 using namespace tt;
12 
13 namespace trackerTFP {
14 
16  const Setup* setup,
17  const DataFormats* dataFormats,
18  int region)
19  : enableTruncation_(iConfig.getParameter<bool>("EnableTruncation")),
20  setup_(setup),
21  dataFormats_(dataFormats),
22  region_(region),
23  input_(dataFormats_->numChannel(Process::gp), vector<deque<StubPP*>>(dataFormats_->numChannel(Process::pp))) {}
24 
25  // read in and organize input product (fill vector input_)
26  void GeometricProcessor::consume(const TTDTC& ttDTC) {
27  auto validFrame = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
28  int nStubsPP(0);
29  for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) {
30  const StreamStub& stream = ttDTC.stream(region_, channel);
31  nStubsPP += accumulate(stream.begin(), stream.end(), 0, validFrame);
32  }
33  stubsPP_.reserve(nStubsPP);
34  for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) {
35  for (const FrameStub& frame : ttDTC.stream(region_, channel)) {
36  StubPP* stub = nullptr;
37  if (frame.first.isNonnull()) {
38  stubsPP_.emplace_back(frame, dataFormats_);
39  stub = &stubsPP_.back();
40  }
42  // adding gaps (nullptr) if no stub available or not in sector to emulate f/w
43  input_[sector][channel].push_back(stub && stub->inSector(sector) ? stub : nullptr);
44  }
45  }
46  // remove all gaps between end and last stub
47  for (vector<deque<StubPP*>>& input : input_)
48  for (deque<StubPP*>& stubs : input)
49  for (auto it = stubs.end(); it != stubs.begin();)
50  it = (*--it) ? stubs.begin() : stubs.erase(it);
51  auto validStub = [](int sum, StubPP* stub) { return sum + (stub ? 1 : 0); };
52  int nStubsGP(0);
53  for (const vector<deque<StubPP*>>& sector : input_)
54  for (const deque<StubPP*>& channel : sector)
55  nStubsGP += accumulate(channel.begin(), channel.end(), 0, validStub);
56  stubsGP_.reserve(nStubsGP);
57  }
58 
59  // fill output products
61  for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++) {
62  vector<deque<StubPP*>>& inputs = input_[sector];
63  vector<deque<StubGP*>> stacks(dataFormats_->numChannel(Process::pp));
64  const int sectorPhi = sector % setup_->numSectorsPhi();
65  const int sectorEta = sector / setup_->numSectorsPhi();
66  auto size = [](int sum, const deque<StubPP*>& stubs) { return sum + stubs.size(); };
67  const int nStubs = accumulate(inputs.begin(), inputs.end(), 0, size);
68  vector<StubGP*> acceptedSector;
69  vector<StubGP*> lostSector;
70  acceptedSector.reserve(nStubs);
71  lostSector.reserve(nStubs);
72  // clock accurate firmware emulation, each while trip describes one clock tick, one stub in and one stub out per tick
73  while (!all_of(inputs.begin(), inputs.end(), [](const deque<StubPP*>& stubs) { return stubs.empty(); }) or
74  !all_of(stacks.begin(), stacks.end(), [](const deque<StubGP*>& stubs) { return stubs.empty(); })) {
75  // fill input fifos
76  for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) {
77  deque<StubGP*>& stack = stacks[channel];
78  StubPP* stub = pop_front(inputs[channel]);
79  if (stub) {
80  stubsGP_.emplace_back(*stub, sectorPhi, sectorEta);
81  if (enableTruncation_ && (int)stack.size() == setup_->gpDepthMemory() - 1)
82  lostSector.push_back(pop_front(stack));
83  stack.push_back(&stubsGP_.back());
84  }
85  }
86  // merge input fifos to one stream, prioritizing higher input channel over lower channel
87  bool nothingToRoute(true);
88  for (int channel = dataFormats_->numChannel(Process::pp) - 1; channel >= 0; channel--) {
89  StubGP* stub = pop_front(stacks[channel]);
90  if (stub) {
91  nothingToRoute = false;
92  acceptedSector.push_back(stub);
93  break;
94  }
95  }
96  if (nothingToRoute)
97  acceptedSector.push_back(nullptr);
98  }
99  // truncate if desired
100  if (enableTruncation_ && (int)acceptedSector.size() > setup_->numFrames()) {
101  const auto limit = next(acceptedSector.begin(), setup_->numFrames());
102  copy_if(limit, acceptedSector.end(), back_inserter(lostSector), [](const StubGP* stub) { return stub; });
103  acceptedSector.erase(limit, acceptedSector.end());
104  }
105  // remove all gaps between end and last stub
106  for (auto it = acceptedSector.end(); it != acceptedSector.begin();)
107  it = (*--it) ? acceptedSector.begin() : acceptedSector.erase(it);
108  // fill products
109  auto put = [](const vector<StubGP*>& stubs, StreamStub& stream) {
110  auto toFrame = [](StubGP* stub) { return stub ? stub->frame() : FrameStub(); };
111  stream.reserve(stubs.size());
112  transform(stubs.begin(), stubs.end(), back_inserter(stream), toFrame);
113  };
115  put(acceptedSector, accepted[index]);
116  put(lostSector, lost[index]);
117  }
118  }
119 
120  // remove and return first element of deque, returns nullptr if empty
121  template <class T>
122  T* GeometricProcessor::pop_front(deque<T*>& ts) const {
123  T* t = nullptr;
124  if (!ts.empty()) {
125  t = ts.front();
126  ts.pop_front();
127  }
128  return t;
129  }
130 
131 } // namespace trackerTFP
int numSectorsPhi() const
Definition: Setup.h:409
std::pair< TTStubRef, Frame > FrameStub
Definition: TTTypes.h:60
Class to process and provide run-time constants used by Track Trigger emulators.
Definition: Setup.h:44
std::vector< StreamStub > StreamsStub
Definition: TTTypes.h:66
bool inSector(int sector) const
Definition: DataFormats.h:610
std::vector< FrameStub > StreamStub
Definition: TTTypes.h:63
int numFrames() const
Definition: Setup.h:153
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
static std::string const input
Definition: EdmProvDump.cc:50
void put(edm::Event &evt, double value, const char *instanceName)
int numChannel(Process p) const
Definition: DataFormats.h:498
Definition: TTTypes.h:54
std::vector< std::vector< std::deque< StubPP * > > > input_
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::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
T * pop_front(std::deque< T *> &ts) const
stack
Definition: svgfig.py:559
std::vector< StubPP > stubsPP_
std::vector< StubGP > stubsGP_
void produce(tt::StreamsStub &accepted, tt::StreamsStub &lost)
Class to store hardware like structured TTStub Collection used by Track Trigger emulators.
Definition: TTDTC.h:17
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
HLT enums.
void consume(const TTDTC &ttDTC)
Class to calculate and provide dataformats used by Track Trigger emulator.
Definition: DataFormats.h:216
int gpDepthMemory() const
Definition: Setup.h:415
long double T
const tt::StreamStub & stream(int tfpRegion, int tfpChannel) const
Definition: TTDTC.cc:48
unsigned transform(const HcalDetId &id, unsigned transformCode)