File indexing completed on 2024-04-06 12:21:45
0001 #include "L1Trigger/TrackerTFP/interface/GeometricProcessor.h"
0002
0003 #include <numeric>
0004 #include <algorithm>
0005 #include <iterator>
0006 #include <deque>
0007 #include <vector>
0008
0009 using namespace std;
0010 using namespace edm;
0011 using namespace tt;
0012
0013 namespace trackerTFP {
0014
0015 GeometricProcessor::GeometricProcessor(const ParameterSet& iConfig,
0016 const Setup* setup,
0017 const DataFormats* dataFormats,
0018 int region)
0019 : enableTruncation_(iConfig.getParameter<bool>("EnableTruncation")),
0020 setup_(setup),
0021 dataFormats_(dataFormats),
0022 region_(region),
0023 input_(dataFormats_->numChannel(Process::gp), vector<deque<StubPP*>>(dataFormats_->numChannel(Process::pp))) {}
0024
0025
0026 void GeometricProcessor::consume(const TTDTC& ttDTC) {
0027 auto validFrame = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
0028 int nStubsPP(0);
0029 for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) {
0030 const StreamStub& stream = ttDTC.stream(region_, channel);
0031 nStubsPP += accumulate(stream.begin(), stream.end(), 0, validFrame);
0032 }
0033 stubsPP_.reserve(nStubsPP);
0034 for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) {
0035 for (const FrameStub& frame : ttDTC.stream(region_, channel)) {
0036 StubPP* stub = nullptr;
0037 if (frame.first.isNonnull()) {
0038 stubsPP_.emplace_back(frame, dataFormats_);
0039 stub = &stubsPP_.back();
0040 }
0041 for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++)
0042
0043 input_[sector][channel].push_back(stub && stub->inSector(sector) ? stub : nullptr);
0044 }
0045 }
0046
0047 for (vector<deque<StubPP*>>& input : input_)
0048 for (deque<StubPP*>& stubs : input)
0049 for (auto it = stubs.end(); it != stubs.begin();)
0050 it = (*--it) ? stubs.begin() : stubs.erase(it);
0051 auto validStub = [](int sum, StubPP* stub) { return sum + (stub ? 1 : 0); };
0052 int nStubsGP(0);
0053 for (const vector<deque<StubPP*>>& sector : input_)
0054 for (const deque<StubPP*>& channel : sector)
0055 nStubsGP += accumulate(channel.begin(), channel.end(), 0, validStub);
0056 stubsGP_.reserve(nStubsGP);
0057 }
0058
0059
0060 void GeometricProcessor::produce(StreamsStub& accepted, StreamsStub& lost) {
0061 for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++) {
0062 vector<deque<StubPP*>>& inputs = input_[sector];
0063 vector<deque<StubGP*>> stacks(dataFormats_->numChannel(Process::pp));
0064 const int sectorPhi = sector % setup_->numSectorsPhi();
0065 const int sectorEta = sector / setup_->numSectorsPhi();
0066 auto size = [](int sum, const deque<StubPP*>& stubs) { return sum + stubs.size(); };
0067 const int nStubs = accumulate(inputs.begin(), inputs.end(), 0, size);
0068 vector<StubGP*> acceptedSector;
0069 vector<StubGP*> lostSector;
0070 acceptedSector.reserve(nStubs);
0071 lostSector.reserve(nStubs);
0072
0073 while (!all_of(inputs.begin(), inputs.end(), [](const deque<StubPP*>& stubs) { return stubs.empty(); }) or
0074 !all_of(stacks.begin(), stacks.end(), [](const deque<StubGP*>& stubs) { return stubs.empty(); })) {
0075
0076 for (int channel = 0; channel < dataFormats_->numChannel(Process::pp); channel++) {
0077 deque<StubGP*>& stack = stacks[channel];
0078 StubPP* stub = pop_front(inputs[channel]);
0079 if (stub) {
0080 stubsGP_.emplace_back(*stub, sectorPhi, sectorEta);
0081 if (enableTruncation_ && (int)stack.size() == setup_->gpDepthMemory() - 1)
0082 lostSector.push_back(pop_front(stack));
0083 stack.push_back(&stubsGP_.back());
0084 }
0085 }
0086
0087 bool nothingToRoute(true);
0088 for (int channel = dataFormats_->numChannel(Process::pp) - 1; channel >= 0; channel--) {
0089 StubGP* stub = pop_front(stacks[channel]);
0090 if (stub) {
0091 nothingToRoute = false;
0092 acceptedSector.push_back(stub);
0093 break;
0094 }
0095 }
0096 if (nothingToRoute)
0097 acceptedSector.push_back(nullptr);
0098 }
0099
0100 if (enableTruncation_ && (int)acceptedSector.size() > setup_->numFrames()) {
0101 const auto limit = next(acceptedSector.begin(), setup_->numFrames());
0102 copy_if(limit, acceptedSector.end(), back_inserter(lostSector), [](const StubGP* stub) { return stub; });
0103 acceptedSector.erase(limit, acceptedSector.end());
0104 }
0105
0106 for (auto it = acceptedSector.end(); it != acceptedSector.begin();)
0107 it = (*--it) ? acceptedSector.begin() : acceptedSector.erase(it);
0108
0109 auto put = [](const vector<StubGP*>& stubs, StreamStub& stream) {
0110 auto toFrame = [](StubGP* stub) { return stub ? stub->frame() : FrameStub(); };
0111 stream.reserve(stubs.size());
0112 transform(stubs.begin(), stubs.end(), back_inserter(stream), toFrame);
0113 };
0114 const int index = region_ * dataFormats_->numChannel(Process::gp) + sector;
0115 put(acceptedSector, accepted[index]);
0116 put(lostSector, lost[index]);
0117 }
0118 }
0119
0120
0121 template <class T>
0122 T* GeometricProcessor::pop_front(deque<T*>& ts) const {
0123 T* t = nullptr;
0124 if (!ts.empty()) {
0125 t = ts.front();
0126 ts.pop_front();
0127 }
0128 return t;
0129 }
0130
0131 }