File indexing completed on 2024-09-07 04:36:57
0001 #include "L1Trigger/L1TMuonEndCap/interface/BestTrackSelection.h"
0002
0003 #include "helper.h" // to_hex, to_binary
0004
0005 void BestTrackSelection::configure(int verbose,
0006 int endcap,
0007 int sector,
0008 int bx,
0009 int bxWindow,
0010 int maxRoadsPerZone,
0011 int maxTracks,
0012 bool useSecondEarliest,
0013 bool bugSameSectorPt0) {
0014 verbose_ = verbose;
0015 endcap_ = endcap;
0016 sector_ = sector;
0017 bx_ = bx;
0018
0019 bxWindow_ = bxWindow;
0020 maxRoadsPerZone_ = maxRoadsPerZone;
0021 maxTracks_ = maxTracks;
0022 useSecondEarliest_ = useSecondEarliest;
0023 bugSameSectorPt0_ = bugSameSectorPt0;
0024 }
0025
0026 void BestTrackSelection::process(const std::deque<EMTFTrackCollection>& extended_best_track_cands,
0027 EMTFTrackCollection& best_tracks) const {
0028 int num_cands = 0;
0029 for (const auto& cands : extended_best_track_cands) {
0030 for (const auto& cand : cands) {
0031 if (cand.Rank() > 0) {
0032 num_cands += 1;
0033 }
0034 }
0035 }
0036 bool early_exit = (num_cands == 0);
0037
0038 if (early_exit)
0039 return;
0040
0041 if (!useSecondEarliest_) {
0042 cancel_one_bx(extended_best_track_cands, best_tracks);
0043 } else {
0044 cancel_multi_bx(extended_best_track_cands, best_tracks);
0045 }
0046
0047 if (verbose_ > 0) {
0048 for (const auto& track : best_tracks) {
0049 std::cout << "track: " << track.Winner() << " rank: " << to_hex(track.Rank())
0050 << " ph_deltas: " << array_as_string(track.PtLUT().delta_ph)
0051 << " th_deltas: " << array_as_string(track.PtLUT().delta_th) << " phi: " << track.Phi_fp()
0052 << " theta: " << track.Theta_fp() << " cpat: " << array_as_string(track.PtLUT().cpattern)
0053 << " bx: " << track.BX() << std::endl;
0054 for (int i = 0; i < emtf::NUM_STATIONS + 1; ++i) {
0055 if (track.PtLUT().bt_vi[i] != 0)
0056 std::cout << ".. track segments: st: " << i << " v: " << track.PtLUT().bt_vi[i]
0057 << " h: " << track.PtLUT().bt_hi[i] << " c: " << track.PtLUT().bt_ci[i]
0058 << " s: " << track.PtLUT().bt_si[i] << std::endl;
0059 }
0060 }
0061 }
0062 }
0063
0064 void BestTrackSelection::cancel_one_bx(const std::deque<EMTFTrackCollection>& extended_best_track_cands,
0065 EMTFTrackCollection& best_tracks) const {
0066 const int max_z = emtf::NUM_ZONES;
0067 const int max_n = maxRoadsPerZone_;
0068 const int max_zn = max_z * max_n;
0069 emtf_assert(maxTracks_ <= max_zn);
0070
0071
0072 typedef std::array<int, 3> segment_ref_t;
0073 std::vector<std::vector<segment_ref_t> > segments(max_zn,
0074 std::vector<segment_ref_t>());
0075
0076 std::vector<std::vector<bool> > larger(max_zn, std::vector<bool>(max_zn, false));
0077 std::vector<std::vector<bool> > winner(max_zn, std::vector<bool>(max_zn, false));
0078
0079 std::vector<bool> exists(max_zn, false);
0080 std::vector<bool> killed(max_zn, false);
0081 std::vector<int> rank(max_zn, 0);
0082
0083
0084
0085 for (int z = 0; z < max_z; ++z) {
0086 const EMTFTrackCollection& tracks = extended_best_track_cands.at(z);
0087 const int ntracks = tracks.size();
0088 emtf_assert(ntracks <= max_n);
0089
0090 for (int n = 0; n < ntracks; ++n) {
0091 const int zn = (n * max_z) + z;
0092 const EMTFTrack& track = tracks.at(n);
0093
0094 rank.at(zn) = track.Rank();
0095
0096 for (const auto& conv_hit : track.Hits()) {
0097 emtf_assert(conv_hit.Valid());
0098
0099
0100 const segment_ref_t segment = {{conv_hit.PC_station() * 9 + conv_hit.PC_chamber(),
0101 (conv_hit.PC_segment() % 2),
0102 0}};
0103
0104
0105
0106
0107 segments.at(zn).push_back(segment);
0108 }
0109 }
0110 }
0111
0112
0113 int i = 0, j = 0, ri = 0, rj = 0, gt = 0, eq = 0, sum = 0;
0114
0115 for (i = 0; i < max_zn; ++i) {
0116 for (j = 0; j < max_zn; ++j) {
0117 larger[i][j] = false;
0118 }
0119 larger[i][i] = true;
0120
0121 ri = rank[i];
0122
0123 for (j = 0; j < max_zn; ++j) {
0124
0125
0126
0127
0128 rj = rank[j];
0129 gt = ri > rj;
0130 eq = ri == rj;
0131 if ((i < j && (gt || eq)) || (i > j && gt))
0132 larger[i][j] = true;
0133 }
0134
0135
0136
0137 exists[i] = (ri != 0);
0138 }
0139
0140
0141 for (i = 0; i < max_zn - 1; ++i) {
0142 for (j = i + 1; j < max_zn; ++j) {
0143 int shared_segs = 0;
0144
0145
0146 for (const auto& isegment : segments.at(i)) {
0147 for (const auto& jsegment : segments.at(j)) {
0148 if (isegment == jsegment) {
0149 shared_segs += 1;
0150 }
0151 }
0152 }
0153
0154 if (shared_segs > 0) {
0155
0156 if (larger[i][j])
0157 killed[j] = true;
0158 else
0159 killed[i] = true;
0160 }
0161 }
0162 }
0163
0164
0165
0166 for (i = 0; i < max_zn; ++i) {
0167 exists[i] = exists[i] && (!killed[i]);
0168 }
0169
0170 bool anything_exists = (std::find(exists.begin(), exists.end(), 1) != exists.end());
0171 if (!anything_exists)
0172 return;
0173
0174
0175 for (i = 0; i < max_zn; ++i) {
0176 for (j = 0; j < max_zn; ++j) {
0177
0178
0179 if (exists[i])
0180 larger[i][j] = larger[i][j] || (!exists[j]);
0181 else
0182 larger[i][j] = false;
0183 }
0184 }
0185
0186 if (verbose_ > 0) {
0187 std::cout << "exists: ";
0188 for (i = max_zn - 1; i >= 0; --i) {
0189 std::cout << exists[i];
0190 }
0191 std::cout << std::endl;
0192 std::cout << "killed: ";
0193 for (i = max_zn - 1; i >= 0; --i) {
0194 std::cout << killed[i];
0195 }
0196 std::cout << std::endl;
0197 for (j = 0; j < max_zn; ++j) {
0198 std::cout << "larger: ";
0199 for (i = max_zn - 1; i >= 0; --i) {
0200 std::cout << larger[j][i];
0201 }
0202 std::cout << std::endl;
0203 }
0204 }
0205
0206
0207
0208 for (i = 0; i < max_zn; ++i) {
0209 sum = 0;
0210 for (j = 0; j < max_zn; ++j) {
0211 if (larger[i][j] == 0)
0212 sum += 1;
0213 }
0214
0215 if (sum < maxTracks_) {
0216 winner[sum][i] = true;
0217 }
0218
0219 if (sum < maxTracks_ && bugSameSectorPt0_ && sum > 0) {
0220
0221 winner[sum][i] = false;
0222 }
0223 }
0224
0225
0226 best_tracks.clear();
0227
0228 for (int o = 0; o < maxTracks_; ++o) {
0229 int z = 0, n = 0;
0230 for (i = 0; i < max_zn; ++i) {
0231 if (winner[o][i]) {
0232 n = i / max_z;
0233 z = i % max_z;
0234
0235 const EMTFTrackCollection& tracks = extended_best_track_cands.at(z);
0236 const EMTFTrack& track = tracks.at(n);
0237 best_tracks.push_back(track);
0238
0239
0240 best_tracks.back().set_track_num(best_tracks.size() - 1);
0241 best_tracks.back().set_winner(o);
0242 best_tracks.back().set_bx(best_tracks.back().First_BX());
0243 }
0244 }
0245 }
0246 }
0247
0248 void BestTrackSelection::cancel_multi_bx(const std::deque<EMTFTrackCollection>& extended_best_track_cands,
0249 EMTFTrackCollection& best_tracks) const {
0250 const int max_h = bxWindow_;
0251 const int max_z = emtf::NUM_ZONES;
0252 const int max_n = maxRoadsPerZone_;
0253 const int max_zn = max_z * max_n;
0254 const int max_hzn = max_h * max_zn;
0255 emtf_assert(maxTracks_ <= max_hzn);
0256
0257 const int delayBX = bxWindow_ - 1;
0258 const int num_h = extended_best_track_cands.size() / max_z;
0259
0260
0261 typedef std::array<int, 3> segment_ref_t;
0262 std::vector<std::vector<segment_ref_t> > segments(max_hzn,
0263 std::vector<segment_ref_t>());
0264
0265 std::vector<std::vector<bool> > larger(max_hzn, std::vector<bool>(max_hzn, false));
0266 std::vector<std::vector<bool> > winner(max_hzn, std::vector<bool>(max_hzn, false));
0267
0268 std::vector<bool> exists(max_hzn, false);
0269 std::vector<bool> killed(max_hzn, false);
0270 std::vector<int> rank(max_hzn, 0);
0271 std::vector<int> good_bx(max_hzn, 0);
0272
0273
0274 for (int h = 0; h < num_h; ++h) {
0275
0276
0277
0278
0279 for (int z = 0; z < max_z; ++z) {
0280 const EMTFTrackCollection& tracks = extended_best_track_cands.at(h * max_z + z);
0281 const int ntracks = tracks.size();
0282 emtf_assert(ntracks <= max_n);
0283
0284 for (int n = 0; n < ntracks; ++n) {
0285 const int hzn = (h * max_z * max_n) + (n * max_z) + z;
0286 const EMTFTrack& track = tracks.at(n);
0287 int cand_bx = track.Second_BX();
0288 cand_bx -= (bx_ - delayBX);
0289
0290 rank.at(hzn) = track.Rank();
0291 if (cand_bx == 0)
0292 good_bx.at(hzn) = 1;
0293
0294 for (const auto& conv_hit : track.Hits()) {
0295 emtf_assert(conv_hit.Valid());
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 const segment_ref_t segment = {{conv_hit.PC_station() * 9 + conv_hit.PC_chamber(),
0309 (conv_hit.PC_segment() % 2),
0310 conv_hit.BX()}};
0311
0312
0313
0314
0315 segments.at(hzn).push_back(segment);
0316 }
0317 }
0318 }
0319 }
0320
0321
0322 int i = 0, j = 0, ri = 0, rj = 0, sum = 0;
0323
0324 for (i = 0; i < max_hzn; ++i) {
0325
0326
0327
0328 larger[i][i] = true;
0329
0330 ri = rank[i];
0331
0332 for (j = i + 1; j < max_hzn; ++j) {
0333
0334
0335 rj = rank[j];
0336 if (ri >= rj)
0337 larger[i][j] = true;
0338 else
0339 larger[j][i] = true;
0340 }
0341
0342
0343
0344 exists[i] = (ri != 0);
0345 }
0346
0347
0348 for (i = 0; i < max_hzn - 1; ++i) {
0349 for (j = i + 1; j < max_hzn; ++j) {
0350 int shared_segs = 0;
0351
0352
0353 for (const auto& isegment : segments.at(i)) {
0354 for (const auto& jsegment : segments.at(j)) {
0355 if (isegment == jsegment) {
0356 shared_segs += 1;
0357 }
0358 }
0359 }
0360
0361 if (shared_segs > 0) {
0362
0363 if (larger[i][j])
0364 killed[j] = true;
0365 else
0366 killed[i] = true;
0367 }
0368 }
0369 }
0370
0371
0372
0373 for (i = 0; i < max_hzn; ++i) {
0374 exists[i] = exists[i] && (!killed[i]);
0375 }
0376
0377
0378
0379 for (i = 0; i < max_hzn; ++i) {
0380 exists[i] = exists[i] & good_bx[i];
0381 }
0382
0383 bool anything_exists = (std::find(exists.begin(), exists.end(), 1) != exists.end());
0384 if (!anything_exists)
0385 return;
0386
0387
0388 for (i = 0; i < max_hzn; ++i) {
0389 for (j = 0; j < max_hzn; ++j) {
0390
0391
0392 if (exists[i])
0393 larger[i][j] = larger[i][j] || (!exists[j]);
0394 else
0395 larger[i][j] = false;
0396 }
0397 }
0398
0399 if (verbose_ > 0) {
0400 std::cout << "exists: ";
0401 for (i = max_hzn - 1; i >= 0; --i) {
0402 std::cout << exists[i];
0403 if ((i % max_zn) == 0 && i != 0)
0404 std::cout << "_";
0405 }
0406 std::cout << std::endl;
0407 std::cout << "killed: ";
0408 for (i = max_hzn - 1; i >= 0; --i) {
0409 std::cout << killed[i];
0410 if ((i % max_zn) == 0 && i != 0)
0411 std::cout << "_";
0412 }
0413 std::cout << std::endl;
0414 for (j = 0; j < max_hzn; ++j) {
0415 std::cout << "larger: ";
0416 for (i = max_hzn - 1; i >= 0; --i) {
0417 std::cout << larger[j][i];
0418 if ((i % max_zn) == 0 && i != 0)
0419 std::cout << "_";
0420 }
0421 std::cout << std::endl;
0422 }
0423 }
0424
0425
0426 for (i = 0; i < max_hzn; ++i) {
0427 sum = 0;
0428 for (j = 0; j < max_hzn; ++j) {
0429 if (larger[i][j] == 0)
0430 sum += 1;
0431 }
0432
0433 if (sum < maxTracks_) {
0434 winner[sum][i] = true;
0435 }
0436
0437 if (sum < maxTracks_ && bugSameSectorPt0_ && sum > 0) {
0438
0439 winner[sum][i] = false;
0440 }
0441 }
0442
0443
0444 best_tracks.clear();
0445
0446 for (int o = 0; o < maxTracks_; ++o) {
0447 int h = 0, n = 0, z = 0;
0448 for (i = 0; i < max_hzn; ++i) {
0449 if (winner[o][i]) {
0450 h = (i / max_z / max_n);
0451 n = (i / max_z) % max_n;
0452 z = i % max_z;
0453
0454 const EMTFTrackCollection& tracks = extended_best_track_cands.at(h * max_z + z);
0455 const EMTFTrack& track = tracks.at(n);
0456 best_tracks.push_back(track);
0457
0458
0459 best_tracks.back().set_track_num(best_tracks.size() - 1);
0460 best_tracks.back().set_winner(o);
0461 best_tracks.back().set_bx(best_tracks.back().Second_BX());
0462 }
0463 }
0464 }
0465 }