File indexing completed on 2024-04-06 12:21:45
0001 #include "L1Trigger/TrackerTFP/interface/HoughTransform.h"
0002
0003 #include <numeric>
0004 #include <algorithm>
0005 #include <iterator>
0006 #include <deque>
0007 #include <vector>
0008 #include <set>
0009 #include <utility>
0010 #include <cmath>
0011
0012 using namespace std;
0013 using namespace edm;
0014 using namespace tt;
0015
0016 namespace trackerTFP {
0017
0018 HoughTransform::HoughTransform(const ParameterSet& iConfig,
0019 const Setup* setup,
0020 const DataFormats* dataFormats,
0021 int region)
0022 : enableTruncation_(iConfig.getParameter<bool>("EnableTruncation")),
0023 setup_(setup),
0024 dataFormats_(dataFormats),
0025 inv2R_(dataFormats_->format(Variable::inv2R, Process::ht)),
0026 phiT_(dataFormats_->format(Variable::phiT, Process::ht)),
0027 region_(region),
0028 input_(dataFormats_->numChannel(Process::ht), vector<deque<StubGP*>>(dataFormats_->numChannel(Process::gp))) {}
0029
0030
0031 void HoughTransform::consume(const StreamsStub& streams) {
0032 const int offset = region_ * dataFormats_->numChannel(Process::gp);
0033 auto validFrame = [](int sum, const FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
0034 int nStubsGP(0);
0035 for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++) {
0036 const StreamStub& stream = streams[offset + sector];
0037 nStubsGP += accumulate(stream.begin(), stream.end(), 0, validFrame);
0038 }
0039 stubsGP_.reserve(nStubsGP);
0040 for (int sector = 0; sector < dataFormats_->numChannel(Process::gp); sector++) {
0041 const int sectorPhi = sector % setup_->numSectorsPhi();
0042 const int sectorEta = sector / setup_->numSectorsPhi();
0043 for (const FrameStub& frame : streams[offset + sector]) {
0044
0045 StubGP* stub = nullptr;
0046 if (frame.first.isNonnull()) {
0047 stubsGP_.emplace_back(frame, dataFormats_, sectorPhi, sectorEta);
0048 stub = &stubsGP_.back();
0049 }
0050 for (int binInv2R = 0; binInv2R < dataFormats_->numChannel(Process::ht); binInv2R++)
0051 input_[binInv2R][sector].push_back(stub && stub->inInv2RBin(binInv2R) ? stub : nullptr);
0052 }
0053 }
0054
0055 for (vector<deque<StubGP*>>& input : input_)
0056 for (deque<StubGP*>& stubs : input)
0057 for (auto it = stubs.end(); it != stubs.begin();)
0058 it = (*--it) ? stubs.begin() : stubs.erase(it);
0059 auto validStub = [](int sum, StubGP* stub) { return sum + (stub ? 1 : 0); };
0060 int nStubsHT(0);
0061 for (const vector<deque<StubGP*>>& binInv2R : input_)
0062 for (const deque<StubGP*>& sector : binInv2R)
0063 nStubsHT += accumulate(sector.begin(), sector.end(), 0, validStub);
0064 stubsHT_.reserve(nStubsHT);
0065 }
0066
0067
0068 void HoughTransform::produce(StreamsStub& accepted, StreamsStub& lost) {
0069 for (int binInv2R = 0; binInv2R < dataFormats_->numChannel(Process::ht); binInv2R++) {
0070 const int inv2R = inv2R_.toSigned(binInv2R);
0071 deque<StubHT*> acceptedAll;
0072 deque<StubHT*> lostAll;
0073 for (deque<StubGP*>& inputSector : input_[binInv2R]) {
0074 const int size = inputSector.size();
0075 vector<StubHT*> acceptedSector;
0076 vector<StubHT*> lostSector;
0077 acceptedSector.reserve(size);
0078 lostSector.reserve(size);
0079
0080 fillIn(inv2R, inputSector, acceptedSector, lostSector);
0081
0082 acceptedSector.erase(remove(acceptedSector.begin(), acceptedSector.end(), nullptr), acceptedSector.end());
0083
0084 readOut(acceptedSector, lostSector, acceptedAll, lostAll);
0085 }
0086
0087 const auto limit = enableTruncation_
0088 ? next(acceptedAll.begin(), min(setup_->numFrames(), (int)acceptedAll.size()))
0089 : acceptedAll.end();
0090 copy_if(limit, acceptedAll.end(), back_inserter(lostAll), [](StubHT* stub) { return stub; });
0091 acceptedAll.erase(limit, acceptedAll.end());
0092
0093 auto put = [](const deque<StubHT*>& stubs, StreamStub& stream) {
0094 stream.reserve(stubs.size());
0095 for (StubHT* stub : stubs)
0096 stream.emplace_back(stub ? stub->frame() : FrameStub());
0097 };
0098 const int offset = region_ * dataFormats_->numChannel(Process::ht);
0099 put(acceptedAll, accepted[offset + binInv2R]);
0100
0101 put(lostAll, lost[offset + binInv2R]);
0102 }
0103 }
0104
0105
0106 void HoughTransform::fillIn(int inv2R,
0107 deque<StubGP*>& inputSector,
0108 vector<StubHT*>& acceptedSector,
0109 vector<StubHT*>& lostSector) {
0110
0111 deque<StubHT*> stack;
0112
0113 while (!inputSector.empty() || !stack.empty()) {
0114 StubHT* stubHT = nullptr;
0115 StubGP* stubGP = pop_front(inputSector);
0116 if (stubGP) {
0117 const double phiT = stubGP->phi() - inv2R_.floating(inv2R) * stubGP->r();
0118 const int major = phiT_.integer(phiT);
0119 if (phiT_.inRange(major)) {
0120
0121
0122 stubsHT_.emplace_back(*stubGP, major, inv2R);
0123 stubHT = &stubsHT_.back();
0124 }
0125 const double chi = phiT - phiT_.floating(major);
0126 if (abs(stubGP->r() * inv2R_.base()) + 2. * abs(chi) >= phiT_.base()) {
0127
0128 const int minor = chi >= 0. ? major + 1 : major - 1;
0129 if (phiT_.inRange(minor)) {
0130
0131 stubsHT_.emplace_back(*stubGP, minor, inv2R);
0132 if (enableTruncation_ && (int)stack.size() == setup_->htDepthMemory() - 1)
0133
0134 lostSector.push_back(pop_front(stack));
0135
0136 stack.push_back(&stubsHT_.back());
0137 }
0138 }
0139 }
0140
0141 acceptedSector.push_back(stubHT ? stubHT : pop_front(stack));
0142 }
0143
0144 const auto limit = enableTruncation_
0145 ? next(acceptedSector.begin(), min(setup_->numFrames(), (int)acceptedSector.size()))
0146 : acceptedSector.end();
0147 copy_if(limit, acceptedSector.end(), back_inserter(lostSector), [](StubHT* stub) { return stub; });
0148 acceptedSector.erase(limit, acceptedSector.end());
0149 }
0150
0151
0152 void HoughTransform::readOut(const vector<StubHT*>& acceptedSector,
0153 const vector<StubHT*>& lostSector,
0154 deque<StubHT*>& acceptedAll,
0155 deque<StubHT*>& lostAll) const {
0156
0157 TTBV trkFoundPhiTs(0, setup_->htNumBinsPhiT());
0158
0159 vector<TTBV> patternHits(setup_->htNumBinsPhiT(), TTBV(0, setup_->numLayers()));
0160
0161 vector<int> binsPhiT;
0162
0163 vector<vector<StubHT*>> tracks(setup_->htNumBinsPhiT());
0164 for (int binPhiT = 0; binPhiT < setup_->htNumBinsPhiT(); binPhiT++) {
0165 const int phiT = phiT_.toSigned(binPhiT);
0166 auto samePhiT = [phiT](int sum, StubHT* stub) { return sum + (stub->phiT() == phiT); };
0167 const int numAccepted = accumulate(acceptedSector.begin(), acceptedSector.end(), 0, samePhiT);
0168 const int numLost = accumulate(lostSector.begin(), lostSector.end(), 0, samePhiT);
0169 tracks[binPhiT].reserve(numAccepted + numLost);
0170 }
0171 for (StubHT* stub : acceptedSector) {
0172 const int binPhiT = phiT_.toUnsigned(stub->phiT());
0173 TTBV& pattern = patternHits[binPhiT];
0174 pattern.set(stub->layer());
0175 tracks[binPhiT].push_back(stub);
0176 if (pattern.count() >= setup_->htMinLayers() && !trkFoundPhiTs[binPhiT]) {
0177
0178 trkFoundPhiTs.set(binPhiT);
0179 binsPhiT.push_back(binPhiT);
0180 }
0181 }
0182
0183 for (int binPhiT : binsPhiT) {
0184 const vector<StubHT*>& track = tracks[binPhiT];
0185 acceptedAll.insert(acceptedAll.end(), track.begin(), track.end());
0186 }
0187
0188 for (StubHT* stub : lostSector) {
0189 const int binPhiT = phiT_.toUnsigned(stub->phiT());
0190 if (!trkFoundPhiTs[binPhiT])
0191 tracks[binPhiT].push_back(stub);
0192 }
0193 for (int binPhiT : trkFoundPhiTs.ids(false)) {
0194 const vector<StubHT*>& track = tracks[binPhiT];
0195 set<int> layers;
0196 auto toLayer = [](StubHT* stub) { return stub->layer(); };
0197 transform(track.begin(), track.end(), inserter(layers, layers.begin()), toLayer);
0198 if ((int)layers.size() >= setup_->htMinLayers())
0199 lostAll.insert(lostAll.end(), track.begin(), track.end());
0200 }
0201 }
0202
0203
0204 template <class T>
0205 T* HoughTransform::pop_front(deque<T*>& ts) const {
0206 T* t = nullptr;
0207 if (!ts.empty()) {
0208 t = ts.front();
0209 ts.pop_front();
0210 }
0211 return t;
0212 }
0213
0214 }