Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-03 00:12:16

0001 #include "L1Trigger/TrackerTFP/interface/DuplicateRemoval.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 namespace trackerTFP {
0013 
0014   DuplicateRemoval::DuplicateRemoval(const tt::Setup* setup,
0015                                      const DataFormats* dataFormats,
0016                                      std::vector<TrackDR>& tracks,
0017                                      std::vector<StubDR>& stubs)
0018       : setup_(setup), dataFormats_(dataFormats), tracks_(tracks), stubs_(stubs) {
0019     numChannel_ = dataFormats_->numChannel(Process::kf);
0020     numLayers_ = setup_->numLayers();
0021     numInv2R_ = setup_->htNumBinsInv2R() + 2;
0022     numPhiT_ = setup_->htNumBinsPhiT() * setup_->gpNumBinsPhiT();
0023     numZT_ = setup_->gpNumBinsZT();
0024   }
0025 
0026   // fill output products
0027   void DuplicateRemoval::produce(const std::vector<std::vector<TrackKF*>>& tracksIn,
0028                                  const std::vector<std::vector<StubKF*>>& stubsIn,
0029                                  std::vector<std::vector<TrackDR*>>& tracksOut,
0030                                  std::vector<std::vector<StubDR*>>& stubsOut) {
0031     int nTracks(0);
0032     for (const std::vector<TrackKF*>& tracks : tracksIn)
0033       nTracks += std::accumulate(
0034           tracks.begin(), tracks.end(), 0, [](int sum, TrackKF* track) { return sum + (track ? 1 : 0); });
0035     std::vector<Track> tracks;
0036     tracks.reserve(nTracks);
0037     std::deque<Track*> stream;
0038     // merge 4 channel to 1
0039     for (int channel = numChannel_ - 1; channel >= 0; channel--) {
0040       const int offset = channel * numLayers_;
0041       const std::vector<TrackKF*>& tracksChannel = tracksIn[channel];
0042       for (int frame = 0; frame < static_cast<int>(tracksChannel.size()); frame++) {
0043         TrackKF* track = tracksChannel[frame];
0044         if (!track) {
0045           stream.push_back(nullptr);
0046           continue;
0047         }
0048         std::vector<StubKF*> stubs;
0049         stubs.reserve(numLayers_);
0050         for (int layer = 0; layer < numLayers_; layer++)
0051           stubs.push_back(stubsIn[offset + layer][frame]);
0052         const bool match = track->match().val();
0053         const int inv2R = dataFormats_->format(Variable::inv2R, Process::ht).integer(track->inv2R()) + numInv2R_ / 2;
0054         const int phiT = dataFormats_->format(Variable::phiT, Process::ht).integer(track->phiT()) + numPhiT_ / 2;
0055         const int zT = dataFormats_->format(Variable::zT, Process::gp).integer(track->zT()) + numZT_ / 2;
0056         tracks.emplace_back(track, stubs, match, inv2R, phiT, zT);
0057         stream.push_back(&tracks.back());
0058       }
0059     }
0060     // truncate if desired
0061     if (setup_->enableTruncation() && static_cast<int>(stream.size()) > setup_->numFramesHigh()) {
0062       const auto limit = std::next(stream.begin(), setup_->numFramesHigh());
0063       stream.erase(limit, stream.end());
0064     }
0065     // remove duplicates
0066     std::vector<Track*> killed;
0067     killed.reserve(stream.size());
0068     std::vector<std::vector<TTBV>> hits(numZT_, std::vector<TTBV>(numInv2R_, TTBV(0, numPhiT_)));
0069     for (Track*& track : stream) {
0070       if (!track)
0071         continue;
0072       if (track->match_) {
0073         hits[track->zT_][track->inv2R_].set(track->phiT_);
0074       } else {
0075         killed.push_back(track);
0076         track = nullptr;
0077       }
0078     }
0079     // restore duplicates
0080     for (Track* track : killed) {
0081       if (hits[track->zT_][track->inv2R_][track->phiT_]) {
0082         stream.push_back(nullptr);
0083         continue;
0084       }
0085       hits[track->zT_][track->inv2R_].set(track->phiT_);
0086       stream.push_back(track);
0087     }
0088     // truncate
0089     if (setup_->enableTruncation() && static_cast<int>(stream.size()) > setup_->numFramesHigh()) {
0090       const auto limit = std::next(stream.begin(), setup_->numFramesHigh());
0091       stream.erase(limit, stream.end());
0092     }
0093     // remove trailing nullptr
0094     for (auto it = stream.end(); it != stream.begin();)
0095       it = (*--it) ? stream.begin() : stream.erase(it);
0096     // convert and store tracks
0097     tracksOut[0].reserve(stream.size());
0098     for (std::vector<StubDR*>& layer : stubsOut)
0099       layer.reserve(stream.size());
0100     for (Track* track : stream) {
0101       if (!track) {
0102         tracksOut[0].push_back(nullptr);
0103         for (std::vector<StubDR*>& layer : stubsOut)
0104           layer.push_back(nullptr);
0105         continue;
0106       }
0107       const DataFormat& gp = dataFormats_->format(Variable::zT, Process::gp);
0108       TrackKF* trackKF = track->track_;
0109       const double inv2R = trackKF->inv2R();
0110       const double phiT = trackKF->phiT();
0111       const double zT = trackKF->zT();
0112       const double cot = trackKF->cot() + gp.digi(zT) / setup_->chosenRofZ();
0113       tracks_.emplace_back(*trackKF, inv2R, phiT, cot, zT);
0114       tracksOut[0].push_back(&tracks_.back());
0115       for (int layer = 0; layer < numLayers_; layer++) {
0116         std::vector<StubDR*>& layerStubs = stubsOut[layer];
0117         StubKF* stub = track->stubs_[layer];
0118         if (!stub) {
0119           layerStubs.push_back(nullptr);
0120           continue;
0121         }
0122         const double r = stub->r();
0123         const double phi = stub->phi();
0124         const double z = stub->z();
0125         const double dPhi = stub->dPhi();
0126         const double dZ = stub->dZ();
0127         stubs_.emplace_back(*stub, r, phi, z, dPhi, dZ);
0128         layerStubs.push_back(&stubs_.back());
0129       }
0130     }
0131   }
0132 
0133 }  // namespace trackerTFP