File indexing completed on 2025-06-03 00:12:22
0001 #include "L1Trigger/TrackFindingTracklet/interface/DuplicateRemoval.h"
0002
0003 #include <vector>
0004 #include <numeric>
0005 #include <algorithm>
0006
0007 namespace trklet {
0008
0009 DuplicateRemoval::DuplicateRemoval(const tt::Setup* setup,
0010 const trackerTFP::LayerEncoding* layerEncoding,
0011 const DataFormats* dataFormats,
0012 const ChannelAssignment* channelAssignment,
0013 int region)
0014 : setup_(setup),
0015 layerEncoding_(layerEncoding),
0016 dataFormats_(dataFormats),
0017 channelAssignment_(channelAssignment),
0018 region_(region) {
0019 const DataFormat& r = dataFormats_->format(Variable::r, Process::dr);
0020 const int width = setup_->widthAddrBRAM18() - 1;
0021 const double base = r.base() * pow(2., r.width() - width);
0022 const double range = r.range();
0023 r_ = DataFormat(true, width, base, range);
0024 tmNumLayers_ = channelAssignment_->tmNumLayers();
0025 phi_ = dataFormats_->format(Variable::phi, Process::dr);
0026 }
0027
0028
0029 void DuplicateRemoval::consume(const tt::StreamsTrack& streamsTrack, const tt::StreamsStub& streamsStub) {
0030 auto nonNullTrack = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
0031 auto nonNullStub = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
0032
0033 int sizeStubs(0);
0034 const int offset = region_ * tmNumLayers_;
0035 const tt::StreamTrack& streamTrack = streamsTrack[region_];
0036 input_.reserve(streamTrack.size());
0037 const int sizeTracks = std::accumulate(streamTrack.begin(), streamTrack.end(), 0, nonNullTrack);
0038 for (int layer = 0; layer < tmNumLayers_; layer++) {
0039 const tt::StreamStub& streamStub = streamsStub[offset + layer];
0040 sizeStubs += std::accumulate(streamStub.begin(), streamStub.end(), 0, nonNullStub);
0041 }
0042 tracks_.reserve(sizeTracks);
0043 stubs_.reserve(sizeStubs);
0044
0045 for (int frame = 0; frame < static_cast<int>(streamTrack.size()); frame++) {
0046 const tt::FrameTrack& frameTrack = streamTrack[frame];
0047 if (frameTrack.first.isNull()) {
0048 input_.push_back(nullptr);
0049 continue;
0050 }
0051
0052 const TrackTM track(frameTrack, dataFormats_);
0053 const double inv2R = abs(track.inv2R());
0054 const double zT = abs(track.zT());
0055 const double cot = zT / setup_->chosenRofZ();
0056 const std::vector<int>& layerEncoding = layerEncoding_->layerEncoding(zT);
0057 std::vector<Stub*> stubs(tmNumLayers_, nullptr);
0058 TTBV hitPattern(0, setup_->numLayers());
0059 for (int layer = 0; layer < tmNumLayers_; layer++) {
0060 const tt::FrameStub& frameStub = streamsStub[offset + layer][frame];
0061 const TTStubRef& ttStubRef = frameStub.first;
0062 if (ttStubRef.isNull())
0063 continue;
0064
0065 const int decodedLayerId =
0066 layer + setup_->offsetLayerId() +
0067 (layer < setup_->numBarrelLayer() ? 0 : setup_->offsetLayerDisks() - setup_->numBarrelLayer());
0068 const auto it = std::find(layerEncoding.begin(), layerEncoding.end(), decodedLayerId);
0069 const int encodedLayerId =
0070 std::min(static_cast<int>(std::distance(layerEncoding.begin(), it)), setup_->numLayers() - 1);
0071
0072 if (hitPattern.test(encodedLayerId))
0073 continue;
0074 hitPattern.set(encodedLayerId);
0075 const StubTM stubTM(frameStub, dataFormats_);
0076 const int stubId = stubTM.stubId() / 2;
0077 const bool psTilt = stubTM.stubId() % 2 == 1;
0078
0079 static constexpr int numBarrelPSLayer = 3;
0080 const bool barrel = layer < setup_->numBarrelLayer();
0081 const bool ps = barrel ? layer < numBarrelPSLayer : psTilt;
0082 const bool tilt = barrel && psTilt;
0083 const double length = .5 * (ps ? setup_->pitchColPS() : setup_->pitchCol2S());
0084 const double pitch = .5 * (ps ? setup_->pitchRowPS() : setup_->pitchRow2S());
0085 const double pitchOverR = phi_.digi(pitch / (r_.digi(stubTM.r()) + setup_->chosenRofPhi()));
0086 double lengthZ = length;
0087 double lengthR = 0.;
0088 if (!barrel) {
0089 lengthZ = length * cot;
0090 lengthR = length;
0091 } else if (tilt) {
0092 lengthZ = length * (setup_->tiltApproxSlope() * cot + setup_->tiltApproxIntercept());
0093 lengthR = .5 * setup_->tiltUncertaintyR();
0094 }
0095 const double dR = lengthR + .5 * setup_->scattering();
0096 const double dZ = lengthZ;
0097 const double dPhi = phi_.digi(dR * inv2R) + pitchOverR;
0098 const StubDR stubDR(stubTM, stubTM.r(), stubTM.phi(), stubTM.z(), dPhi, dZ);
0099 stubs_.emplace_back(stubDR.frame(), stubId, encodedLayerId);
0100 stubs[layer] = &stubs_.back();
0101 }
0102
0103 if (hitPattern.count() < setup_->kfMinLayers()) {
0104 input_.push_back(nullptr);
0105 continue;
0106 }
0107 tracks_.emplace_back(frameTrack, stubs);
0108 input_.push_back(&tracks_.back());
0109 }
0110
0111 for (auto it = input_.end(); it != input_.begin();)
0112 it = (*--it) ? input_.begin() : input_.erase(it);
0113 }
0114
0115
0116 void DuplicateRemoval::produce(tt::StreamsTrack& streamsTrack, tt::StreamsStub& streamsStub) {
0117 const int offset = region_ * setup_->numLayers();
0118
0119 std::vector<Track*> cms(channelAssignment_->numComparisonModules(), nullptr);
0120 for (Track*& track : input_) {
0121 if (!track)
0122
0123 continue;
0124 for (Track*& trackCM : cms) {
0125 if (!trackCM) {
0126
0127 trackCM = track;
0128 break;
0129 }
0130 if (equalEnough(track, trackCM)) {
0131
0132 track = nullptr;
0133 break;
0134 }
0135 }
0136 }
0137
0138 for (auto it = input_.end(); it != input_.begin();)
0139 it = (*--it) ? input_.begin() : input_.erase(it);
0140
0141 tt::StreamTrack& streamTrack = streamsTrack[region_];
0142 streamTrack.reserve(input_.size());
0143 for (int layer = 0; layer < setup_->numLayers(); layer++)
0144 streamsStub[offset + layer].reserve(input_.size());
0145 for (Track* track : input_) {
0146 if (!track) {
0147 streamTrack.emplace_back(tt::FrameTrack());
0148 for (int layer = 0; layer < setup_->numLayers(); layer++)
0149 streamsStub[offset + layer].emplace_back(tt::FrameStub());
0150 continue;
0151 }
0152 streamTrack.push_back(track->frame_);
0153 TTBV hitPattern(0, setup_->numLayers());
0154 for (Stub* stub : track->stubs_) {
0155 if (!stub)
0156 continue;
0157 hitPattern.set(stub->layer_);
0158 streamsStub[offset + stub->layer_].emplace_back(stub->frame_);
0159 }
0160 for (int layer : hitPattern.ids(false))
0161 streamsStub[offset + layer].emplace_back(tt::FrameStub());
0162 }
0163 }
0164
0165
0166 bool DuplicateRemoval::equalEnough(Track* t0, Track* t1) const {
0167 int same(0);
0168 for (int layer = 0; layer < channelAssignment_->tmNumLayers(); layer++) {
0169 Stub* s0 = t0->stubs_[layer];
0170 Stub* s1 = t1->stubs_[layer];
0171 if (s0 && s1 && s0->stubId_ == s1->stubId_)
0172 same++;
0173 }
0174 return same >= channelAssignment_->minIdenticalStubs();
0175 }
0176
0177 }