File indexing completed on 2024-04-06 12:21:42
0001 #include "L1Trigger/TrackerDTC/interface/DTC.h"
0002
0003 #include <vector>
0004 #include <iterator>
0005 #include <algorithm>
0006 #include <numeric>
0007
0008 using namespace std;
0009 using namespace edm;
0010 using namespace tt;
0011
0012 namespace trackerDTC {
0013
0014 DTC::DTC(const ParameterSet& iConfig,
0015 const Setup* setup,
0016 const LayerEncoding* layerEncoding,
0017 int dtcId,
0018 const std::vector<std::vector<TTStubRef>>& stubsDTC)
0019 : setup_(setup),
0020 enableTruncation_(iConfig.getParameter<bool>("EnableTruncation")),
0021 region_(dtcId / setup->numDTCsPerRegion()),
0022 board_(dtcId % setup->numDTCsPerRegion()),
0023 modules_(setup->dtcModules(dtcId)),
0024 input_(setup->dtcNumRoutingBlocks(), Stubss(setup->dtcNumModulesPerRoutingBlock())),
0025 lost_(setup->numOverlappingRegions()) {
0026
0027 auto acc = [](int sum, const vector<TTStubRef>& stubsModule) { return sum + stubsModule.size(); };
0028 const int nStubs = accumulate(stubsDTC.begin(), stubsDTC.end(), 0, acc);
0029 stubs_.reserve(nStubs);
0030
0031 for (int modId = 0; modId < setup->numModulesPerDTC(); modId++) {
0032 const vector<TTStubRef>& ttStubRefs = stubsDTC[modId];
0033 if (ttStubRefs.empty())
0034 continue;
0035
0036 SensorModule* module = modules_.at(modId);
0037
0038 const int blockId = modId / setup->dtcNumModulesPerRoutingBlock();
0039
0040 const int channelId = modId % setup->dtcNumModulesPerRoutingBlock();
0041
0042 Stubs& stubs = input_[blockId][channelId];
0043 for (const TTStubRef& ttStubRef : ttStubRefs) {
0044 stubs_.emplace_back(iConfig, setup, layerEncoding, module, ttStubRef);
0045 Stub& stub = stubs_.back();
0046 if (stub.valid())
0047
0048 stubs.push_back(&stub);
0049 }
0050
0051 sort(stubs.begin(), stubs.end(), [](Stub* lhs, Stub* rhs) { return abs(lhs->bend()) < abs(rhs->bend()); });
0052
0053 if (!enableTruncation_ || (int)stubs.size() <= setup->numFramesFE())
0054 continue;
0055
0056 const auto limit = next(stubs.begin(), setup->numFramesFE());
0057
0058 for (int region = 0; region < setup->numOverlappingRegions(); region++)
0059 copy_if(
0060 limit, stubs.end(), back_inserter(lost_[region]), [region](Stub* stub) { return stub->inRegion(region); });
0061
0062 stubs.erase(limit, stubs.end());
0063 }
0064 }
0065
0066
0067 void DTC::produce(TTDTC& productAccepted, TTDTC& productLost) {
0068
0069 Stubs lost;
0070 Stubss blockStubs(setup_->dtcNumRoutingBlocks());
0071 for (int routingBlock = 0; routingBlock < setup_->dtcNumRoutingBlocks(); routingBlock++)
0072 merge(input_[routingBlock], blockStubs[routingBlock], lost);
0073
0074 for (int region = 0; region < setup_->numOverlappingRegions(); region++) {
0075 auto inRegion = [region](Stub* stub) { return stub->inRegion(region); };
0076 copy_if(lost.begin(), lost.end(), back_inserter(lost_[region]), inRegion);
0077 }
0078
0079 Stubss regionStubs(setup_->numOverlappingRegions());
0080 split(blockStubs, regionStubs);
0081
0082 produce(regionStubs, productAccepted);
0083 produce(lost_, productLost);
0084 }
0085
0086
0087 void DTC::merge(Stubss& inputs, Stubs& output, Stubs& lost) {
0088
0089 Stubss stacks(inputs.size());
0090
0091 while (!all_of(inputs.begin(), inputs.end(), [](const Stubs& channel) { return channel.empty(); }) or
0092 !all_of(stacks.begin(), stacks.end(), [](const Stubs& channel) { return channel.empty(); })) {
0093
0094 for (int iInput = 0; iInput < (int)inputs.size(); iInput++) {
0095 Stubs& input = inputs[iInput];
0096 Stubs& stack = stacks[iInput];
0097 if (input.empty())
0098 continue;
0099 Stub* stub = pop_front(input);
0100 if (stub) {
0101 if (enableTruncation_ && (int)stack.size() == setup_->dtcDepthMemory() - 1)
0102
0103 lost.push_back(pop_front(stack));
0104 stack.push_back(stub);
0105 }
0106 }
0107
0108 bool nothingToRoute(true);
0109 for (int iInput = inputs.size() - 1; iInput >= 0; iInput--) {
0110 Stubs& stack = stacks[iInput];
0111 if (stack.empty())
0112 continue;
0113 nothingToRoute = false;
0114 output.push_back(pop_front(stack));
0115
0116 break;
0117 }
0118
0119 if (nothingToRoute)
0120 output.push_back(nullptr);
0121 }
0122
0123 if (enableTruncation_ && (int)output.size() > setup_->numFramesIO()) {
0124 const auto limit = next(output.begin(), setup_->numFramesIO());
0125 copy_if(limit, output.end(), back_inserter(lost), [](Stub* stub) { return stub; });
0126 output.erase(limit, output.end());
0127 }
0128
0129 for (auto it = output.end(); it != output.begin();)
0130 it = (*--it) ? output.begin() : output.erase(it);
0131 }
0132
0133
0134 void DTC::split(Stubss& inputs, Stubss& outputs) {
0135 int region(0);
0136 auto regionMask = [®ion](Stub* stub) { return stub && stub->inRegion(region) ? stub : nullptr; };
0137 for (Stubs& output : outputs) {
0138
0139 Stubss streams(inputs.size());
0140 int i(0);
0141 for (Stubs& input : inputs) {
0142 Stubs& stream = streams[i++];
0143 transform(input.begin(), input.end(), back_inserter(stream), regionMask);
0144 for (auto it = stream.end(); it != stream.begin();)
0145 it = (*--it) ? stream.begin() : stream.erase(it);
0146 }
0147 merge(streams, output, lost_[region++]);
0148 }
0149 }
0150
0151
0152 void DTC::produce(const Stubss& stubss, TTDTC& product) {
0153 int channel(0);
0154 auto toFrame = [&channel](Stub* stub) {
0155 return stub ? make_pair(stub->ttStubRef(), stub->frame(channel)) : FrameStub();
0156 };
0157 for (const Stubs& stubs : stubss) {
0158 StreamStub stream;
0159 stream.reserve(stubs.size());
0160 transform(stubs.begin(), stubs.end(), back_inserter(stream), toFrame);
0161 product.setStream(region_, board_, channel++, stream);
0162 }
0163 }
0164
0165
0166 Stub* DTC::pop_front(Stubs& deque) {
0167 Stub* stub = deque.front();
0168 deque.pop_front();
0169 return stub;
0170 }
0171
0172 }