File indexing completed on 2025-06-03 00:12:24
0001 #include "L1Trigger/TrackFindingTracklet/interface/TrackFindingProcessor.h"
0002 #include "L1Trigger/TrackTrigger/interface/StubPtConsistency.h"
0003
0004 #include <numeric>
0005 #include <algorithm>
0006 #include <iterator>
0007 #include <deque>
0008 #include <vector>
0009
0010 namespace trklet {
0011
0012 TrackFindingProcessor::TrackFindingProcessor(const tt::Setup* setup,
0013 const DataFormats* dataFormats,
0014 const trackerTFP::TrackQuality* trackQuality)
0015 : setup_(setup), dataFormats_(dataFormats), trackQuality_(trackQuality) {
0016 bfield_ = setup_->bField();
0017 }
0018
0019
0020 TrackFindingProcessor::Track::Track(const tt::FrameTrack& frameTrack,
0021 const tt::Frame& frameTQ,
0022 const std::vector<TTStubRef>& ttStubRefs,
0023 const DataFormats* df,
0024 const trackerTFP::TrackQuality* tq)
0025 : ttTrackRef_(frameTrack.first), ttStubRefs_(ttStubRefs), valid_(true) {
0026 partials_.reserve(partial_in);
0027 const double rangeInvR = -2. * TTTrack_TrackWord::minRinv;
0028 const double rangePhi0 = -2. * TTTrack_TrackWord::minPhi0;
0029 const double rangeCot = -2. * TTTrack_TrackWord::minTanl;
0030 const double rangeZ0 = -2. * TTTrack_TrackWord::minZ0;
0031 const double rangeD0 = -2. * TTTrack_TrackWord::minD0;
0032 const double baseInvR = rangeInvR / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kRinvSize);
0033 const double basePhi0 = rangePhi0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kPhiSize);
0034 const double baseCot = rangeCot / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kTanlSize);
0035 const double baseZ0 = rangeZ0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kZ0Size);
0036 const double baseD0 = rangeD0 / std::pow(2., TTTrack_TrackWord::TrackBitWidths::kD0Size);
0037 const int nLayers = TTTrack_TrackWord::TrackBitWidths::kHitPatternSize;
0038 const TTBV other_MVAs = TTBV(0, 2 * TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize);
0039 const TTBV chi2bend = TTBV(0, TTTrack_TrackWord::TrackBitWidths::kBendChi2Size);
0040 const TTBV valid = TTBV(1, TTTrack_TrackWord::TrackBitWidths::kValidSize);
0041
0042 const tt::Setup* setup = df->setup();
0043 const TrackKF track(frameTrack, df);
0044 inv2R_ = track.inv2R();
0045 phiT_ = track.phiT();
0046 cot_ = track.cot();
0047 zT_ = track.zT();
0048 const double d0 = std::max(std::min(ttTrackRef_->d0(), -TTTrack_TrackWord::minD0), TTTrack_TrackWord::minD0);
0049 TTBV ttBV = TTBV(frameTQ);
0050 tq->format(trackerTFP::VariableTQ::chi2rz).extract(ttBV, chi2rz_);
0051 tq->format(trackerTFP::VariableTQ::chi2rphi).extract(ttBV, chi2rphi_);
0052 mva_ = TTBV(ttBV, trackerTFP::widthMVA_).val();
0053 ttBV >>= trackerTFP::widthMVA_;
0054 hitPattern_ = TTBV(ttBV, setup->numLayers());
0055 channel_ = cot_ < 0. ? 0 : 1;
0056
0057 const double z0 = zT_ - cot_ * setup->chosenRofZ();
0058 const double phi0 = phiT_ - inv2R_ * setup->chosenRofPhi();
0059 double invR = -2. * inv2R_;
0060 if (invR < TTTrack_TrackWord::minRinv)
0061 invR = TTTrack_TrackWord::minRinv + df->format(Variable::inv2R, Process::dr).base();
0062 else if (invR > -TTTrack_TrackWord::minRinv)
0063 invR = -TTTrack_TrackWord::minRinv - df->format(Variable::inv2R, Process::dr).base();
0064 const double chi2rphi = chi2rphi_ / (hitPattern_.count() - 2);
0065 const double chi2rz = chi2rz_ / (hitPattern_.count() - 2);
0066 int chi2rphiBin(-1);
0067 for (double d : TTTrack_TrackWord::chi2RPhiBins)
0068 if (chi2rphi >= d)
0069 chi2rphiBin++;
0070 else
0071 break;
0072 int chi2rzBin(-1);
0073 for (double d : TTTrack_TrackWord::chi2RZBins)
0074 if (chi2rz >= d)
0075 chi2rzBin++;
0076 else
0077 break;
0078 if (std::abs(invR) > rangeInvR / 2.)
0079 valid_ = false;
0080 if (std::abs(phi0) > rangePhi0 / 2.)
0081 valid_ = false;
0082 if (std::abs(cot_) > rangeCot / 2.)
0083 valid_ = false;
0084 if (std::abs(z0) > rangeZ0 / 2.)
0085 valid_ = false;
0086 if (std::abs(d0) > rangeD0 / 2.)
0087 valid_ = false;
0088 if (!valid_)
0089 return;
0090 const TTBV MVA_quality(mva_, TTTrack_TrackWord::TrackBitWidths::kMVAQualitySize);
0091 const TTBV hit_pattern(hitPattern_.resize(nLayers).val(), nLayers);
0092 const TTBV D0(d0, baseD0, TTTrack_TrackWord::TrackBitWidths::kD0Size, true);
0093 const TTBV Chi2rz(chi2rzBin, TTTrack_TrackWord::TrackBitWidths::kChi2RZSize);
0094 const TTBV Z0(z0, baseZ0, TTTrack_TrackWord::TrackBitWidths::kZ0Size, true);
0095 const TTBV tanL(cot_, baseCot, TTTrack_TrackWord::TrackBitWidths::kTanlSize, true);
0096 const TTBV Chi2rphi(chi2rphiBin, TTTrack_TrackWord::TrackBitWidths::kChi2RPhiSize);
0097 const TTBV Phi0(phi0, basePhi0, TTTrack_TrackWord::TrackBitWidths::kPhiSize, true);
0098 const TTBV InvR(invR, baseInvR, TTTrack_TrackWord::TrackBitWidths::kRinvSize, true);
0099 partials_.emplace_back((valid + InvR + Phi0 + Chi2rphi).str());
0100 partials_.emplace_back((tanL + Z0 + Chi2rz).str());
0101 partials_.emplace_back((D0 + chi2bend + hit_pattern + MVA_quality + other_MVAs).str());
0102 }
0103
0104
0105 void TrackFindingProcessor::produce(const tt::StreamsTrack& inputs,
0106 const tt::Streams& inputsAdd,
0107 const tt::StreamsStub& stubs,
0108 tt::TTTracks& ttTracks,
0109 tt::StreamsTrack& outputs) {
0110
0111 std::vector<std::deque<Track*>> streams(outputs.size());
0112 consume(inputs, inputsAdd, stubs, streams);
0113
0114 produce(streams, outputs);
0115
0116 produce(outputs, ttTracks);
0117 }
0118
0119
0120 void TrackFindingProcessor::consume(const tt::StreamsTrack& inputs,
0121 const tt::Streams& inputsAdd,
0122 const tt::StreamsStub& stubs,
0123 std::vector<std::deque<Track*>>& outputs) {
0124
0125 int nTracks(0);
0126 auto valid = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
0127 for (const tt::StreamTrack& tracks : inputs)
0128 nTracks += std::accumulate(tracks.begin(), tracks.end(), 0, valid);
0129 tracks_.reserve(nTracks);
0130
0131 for (int region = 0; region < setup_->numRegions(); region++) {
0132 const int offsetTFP = region * setup_->tfpNumChannel();
0133 const int offsetStub = region * setup_->numLayers();
0134 const tt::StreamTrack& streamKF = inputs[region];
0135 const tt::Stream& streamTQ = inputsAdd[region];
0136 for (int channel = 0; channel < setup_->tfpNumChannel(); channel++)
0137 outputs[offsetTFP + channel] = std::deque<Track*>(streamKF.size(), nullptr);
0138 for (int frame = 0; frame < (int)streamKF.size(); frame++) {
0139 const tt::FrameTrack& frameTrack = streamKF[frame];
0140 const tt::Frame& frameTQ = streamTQ[frame];
0141 if (frameTrack.first.isNull())
0142 continue;
0143 std::vector<TTStubRef> ttStubRefs;
0144 ttStubRefs.reserve(setup_->numLayers());
0145 for (int layer = 0; layer < setup_->numLayers(); layer++) {
0146 const TTStubRef& ttStubRef = stubs[offsetStub + layer][frame].first;
0147 if (ttStubRef.isNonnull())
0148 ttStubRefs.push_back(ttStubRef);
0149 }
0150 tracks_.emplace_back(frameTrack, frameTQ, ttStubRefs, dataFormats_, trackQuality_);
0151 Track& track = tracks_.back();
0152 outputs[offsetTFP + track.channel_][frame] = track.valid_ ? &track : nullptr;
0153 }
0154
0155 for (int channel = 0; channel < setup_->tfpNumChannel(); channel++) {
0156 std::deque<Track*> input = outputs[offsetTFP + channel];
0157 for (auto it = input.end(); it != input.begin();)
0158 it = (*--it) ? input.begin() : input.erase(it);
0159 }
0160 }
0161 }
0162
0163
0164 void TrackFindingProcessor::produce(std::vector<std::deque<Track*>>& inputs, tt::StreamsTrack& outputs) const {
0165 for (int channel = 0; channel < static_cast<int>(inputs.size()); channel++) {
0166 std::deque<Track*>& input = inputs[channel];
0167 std::deque<PartialFrameTrack> stack;
0168 std::deque<tt::FrameTrack> output;
0169
0170 while (!input.empty() || !stack.empty()) {
0171 output.emplace_back(tt::FrameTrack());
0172 tt::FrameTrack& frame = output.back();
0173 Track* track = pop_front(input);
0174 if (track)
0175 for (const PartialFrame& pf : track->partials_)
0176 stack.emplace_back(track->ttTrackRef_, pf);
0177 TTBV ttBV;
0178 for (int i = 0; i < partial_out; i++) {
0179 if (stack.empty()) {
0180 ttBV += TTBV(0, partial_width);
0181 continue;
0182 }
0183 const PartialFrameTrack& pft = stack.front();
0184 frame.first = pft.first;
0185 ttBV += TTBV(pft.second.to_string());
0186 stack.pop_front();
0187 }
0188 frame.second = ttBV.bs();
0189 }
0190
0191 if (setup_->enableTruncation() && static_cast<int>(output.size()) > setup_->numFramesIOHigh())
0192 output.resize(setup_->numFramesIOHigh());
0193 outputs[channel] = tt::StreamTrack(output.begin(), output.end());
0194 }
0195 }
0196
0197
0198 void TrackFindingProcessor::produce(const tt::StreamsTrack& inputs, tt::TTTracks& outputs) const {
0199
0200 std::vector<TTTrackRef> ttTrackRefs;
0201 ttTrackRefs.reserve(tracks_.size());
0202 const TTTrack<Ref_Phase2TrackerDigi_>* last = nullptr;
0203 for (const tt::StreamTrack& stream : inputs) {
0204 for (const tt::FrameTrack& frame : stream) {
0205 const TTTrackRef& ttTrackRef = frame.first;
0206 if (frame.first.isNull() || last == ttTrackRef.get())
0207 continue;
0208 last = ttTrackRef.get();
0209 ttTrackRefs.push_back(ttTrackRef);
0210 }
0211 }
0212
0213 outputs.reserve(ttTrackRefs.size());
0214 for (const TTTrackRef& ttTrackRef : ttTrackRefs) {
0215 auto match = [&ttTrackRef](const Track& track) { return track.ttTrackRef_ == ttTrackRef; };
0216 const auto it = std::find_if(tracks_.begin(), tracks_.end(), match);
0217
0218 const int region = ttTrackRef->phiSector();
0219 const double aRinv = -2. * it->inv2R_;
0220 const double aphi = tt::deltaPhi(it->phiT_ - it->inv2R_ * setup_->chosenRofPhi() + region * setup_->baseRegion());
0221 const double aTanLambda = it->cot_;
0222 const double az0 = it->zT_ - it->cot_ * setup_->chosenRofZ();
0223 const double ad0 = -ttTrackRef->d0();
0224 const double aChi2xyfit = it->chi2rphi_;
0225 const double aChi2zfit = it->chi2rz_;
0226 const double trkMVA1 = (TTTrack_TrackWord::tqMVABins[it->mva_]);
0227 static constexpr double trkMVA2 = 0.;
0228 static constexpr double trkMVA3 = 0.;
0229 const unsigned int aHitpattern = it->hitPattern_.val();
0230 const unsigned int nPar = ttTrackRef->nFitPars();
0231 outputs.emplace_back(aRinv,
0232 aphi,
0233 aTanLambda,
0234 az0,
0235 ad0,
0236 aChi2xyfit,
0237 aChi2zfit,
0238 trkMVA1,
0239 trkMVA2,
0240 trkMVA3,
0241 aHitpattern,
0242 nPar,
0243 bfield_);
0244 TTTrack<Ref_Phase2TrackerDigi_>& ttTrack = outputs.back();
0245 ttTrack.setPhiSector(region);
0246 ttTrack.setEtaSector(ttTrackRef->etaSector());
0247 ttTrack.setTrackSeedType(ttTrackRef->trackSeedType());
0248 ttTrack.setStubRefs(it->ttStubRefs_);
0249 ttTrack.setStubPtConsistency(StubPtConsistency::getConsistency(
0250 ttTrack, setup_->trackerGeometry(), setup_->trackerTopology(), bfield_, nPar));
0251 }
0252 }
0253
0254
0255 void TrackFindingProcessor::produce(const std::vector<TTTrackRef>& inputs, tt::StreamsTrack& outputs) const {
0256 int iTrk(-1);
0257 const TTTrack<Ref_Phase2TrackerDigi_>* last = nullptr;
0258 for (tt::StreamTrack& stream : outputs) {
0259 for (tt::FrameTrack& frame : stream) {
0260 const TTTrackRef& ttTrackRef = frame.first;
0261 if (ttTrackRef.isNull())
0262 continue;
0263 if (last != ttTrackRef.get())
0264 iTrk++;
0265 last = ttTrackRef.get();
0266 frame.first = inputs[iTrk];
0267 }
0268 }
0269 }
0270
0271
0272 template <class T>
0273 T* TrackFindingProcessor::pop_front(std::deque<T*>& ts) const {
0274 T* t = nullptr;
0275 if (!ts.empty()) {
0276 t = ts.front();
0277 ts.pop_front();
0278 }
0279 return t;
0280 }
0281
0282 }