File indexing completed on 2025-06-03 00:12:16
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 namespace trackerTFP {
0010
0011 GeometricProcessor::GeometricProcessor(const tt::Setup* setup,
0012 const DataFormats* dataFormats,
0013 const LayerEncoding* layerEncoding,
0014 std::vector<StubGP>& stubs)
0015 : setup_(setup), dataFormats_(dataFormats), layerEncoding_(layerEncoding), stubs_(stubs) {
0016 numChannelIn_ = dataFormats_->numChannel(Process::pp);
0017 numChannelOut_ = dataFormats_->numChannel(Process::gp);
0018 }
0019
0020
0021 void GeometricProcessor::produce(const std::vector<std::vector<StubPP*>>& streamsIn,
0022 std::vector<std::deque<StubGP*>>& streamsOut) {
0023 for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) {
0024
0025 const int phiT = channelOut % setup_->gpNumBinsPhiT() - setup_->gpNumBinsPhiT() / 2;
0026 const int zT = channelOut / setup_->gpNumBinsPhiT() - setup_->gpNumBinsZT() / 2;
0027 auto valid = [phiT, zT](StubPP* stub) {
0028 const bool phiTValid = stub && phiT >= stub->phiTMin() && phiT <= stub->phiTMax();
0029 const bool zTValid = stub && zT >= stub->zTMin() && zT <= stub->zTMax();
0030 return (phiTValid && zTValid) ? stub : nullptr;
0031 };
0032
0033 std::vector<std::deque<StubPP*>> inputs(numChannelIn_);
0034 for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) {
0035 const std::vector<StubPP*>& streamIn = streamsIn[channelIn];
0036 std::transform(streamIn.begin(), streamIn.end(), std::back_inserter(inputs[channelIn]), valid);
0037 }
0038
0039 std::vector<std::deque<StubGP*>> stacks(streamsIn.size());
0040
0041 std::deque<StubGP*>& output = streamsOut[channelOut];
0042
0043 while (
0044 !std::all_of(inputs.begin(), inputs.end(), [](const std::deque<StubPP*>& stubs) { return stubs.empty(); }) ||
0045 !std::all_of(stacks.begin(), stacks.end(), [](const std::deque<StubGP*>& stubs) { return stubs.empty(); })) {
0046
0047 for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) {
0048 std::deque<StubGP*>& stack = stacks[channelIn];
0049 StubPP* stub = pop_front(inputs[channelIn]);
0050 if (stub) {
0051
0052 StubGP* stubGP = produce(*stub, phiT, zT);
0053
0054 if (setup_->enableTruncation() && static_cast<int>(stack.size()) == setup_->gpDepthMemory() - 1)
0055 pop_front(stack);
0056 stack.push_back(stubGP);
0057 }
0058 }
0059
0060 bool nothingToRoute(true);
0061 for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) {
0062 StubGP* stub = pop_front(stacks[channelIn]);
0063 if (stub) {
0064 nothingToRoute = false;
0065 output.push_back(stub);
0066 break;
0067 }
0068 }
0069 if (nothingToRoute)
0070 output.push_back(nullptr);
0071 }
0072
0073 if (setup_->enableTruncation() && static_cast<int>(output.size()) > setup_->numFramesHigh())
0074 output.resize(setup_->numFramesHigh());
0075
0076 for (auto it = output.end(); it != output.begin();)
0077 it = (*--it) ? output.begin() : output.erase(it);
0078 }
0079 }
0080
0081
0082 StubGP* GeometricProcessor::produce(const StubPP& stub, int phiT, int zT) {
0083 const DataFormat& dfPhiT = dataFormats_->format(Variable::phiT, Process::gp);
0084 const DataFormat& dfZT = dataFormats_->format(Variable::zT, Process::gp);
0085 const DataFormat& dfCot = dataFormats_->format(Variable::cot, Process::gp);
0086 const DataFormat& dfR = dataFormats_->format(Variable::r, Process::gp);
0087 const DataFormat& dfL = dataFormats_->format(Variable::layer, Process::gp);
0088 const double cot = dfCot.digi(dfZT.floating(zT) / setup_->chosenRofZ());
0089
0090 const std::vector<int>& le = layerEncoding_->layerEncoding(zT);
0091 const int layerId = setup_->layerId(stub.frame().first);
0092 const auto it = std::find(le.begin(), le.end(), layerId);
0093 const int kfLayerId = std::min(static_cast<int>(std::distance(le.begin(), it)), setup_->numLayers() - 1);
0094
0095 const double r = stub.r();
0096 const double phi = stub.phi() - dfPhiT.floating(phiT);
0097 const double z = stub.z() - (stub.r() + dfR.digi(setup_->chosenRofPhi())) * cot;
0098 TTBV layer(kfLayerId, dfL.width());
0099 if (stub.layer()[4]) {
0100 layer.set(5);
0101 if (stub.layer()[3])
0102 layer.set(3);
0103 if (stub.layer().val(3) < 3)
0104 layer.set(4);
0105 } else if (stub.layer()[3])
0106 layer.set(4);
0107 const int inv2RMin = stub.inv2RMin();
0108 const int inv2RMax = stub.inv2RMax();
0109 stubs_.emplace_back(stub, r, phi, z, layer, inv2RMin, inv2RMax);
0110 return &stubs_.back();
0111 }
0112
0113
0114 template <class T>
0115 T* GeometricProcessor::pop_front(std::deque<T*>& ts) const {
0116 T* t = nullptr;
0117 if (!ts.empty()) {
0118 t = ts.front();
0119 ts.pop_front();
0120 }
0121 return t;
0122 }
0123
0124 }