File indexing completed on 2024-09-07 04:36:58
0001 #include "L1Trigger/L1TMuonEndCap/interface/PrimitiveMatching.h"
0002 #include "DataFormats/L1TMuon/interface/L1TMuonSubsystems.h"
0003
0004 #include "helper.h" // to_hex, to_binary, merge_sort3
0005
0006 namespace {
0007 const int bw_fph = 13;
0008 const int bpow = 7;
0009 const int invalid_ph_diff = 0x1ff;
0010 }
0011
0012 void PrimitiveMatching::configure(int verbose,
0013 int endcap,
0014 int sector,
0015 int bx,
0016 bool fixZonePhi,
0017 bool useNewZones,
0018 bool bugSt2PhDiff,
0019 bool bugME11Dupes) {
0020 verbose_ = verbose;
0021 endcap_ = endcap;
0022 sector_ = sector;
0023 bx_ = bx;
0024
0025 fixZonePhi_ = fixZonePhi;
0026 useNewZones_ = useNewZones;
0027 bugSt2PhDiff_ = bugSt2PhDiff;
0028 bugME11Dupes_ = bugME11Dupes;
0029 }
0030
0031 void PrimitiveMatching::process(const std::deque<EMTFHitCollection>& extended_conv_hits,
0032 const emtf::zone_array<EMTFRoadCollection>& zone_roads,
0033 emtf::zone_array<EMTFTrackCollection>& zone_tracks) const {
0034
0035 auto update_fs_history = [](int fs_segment, int this_bx, int hit_bx) {
0036
0037 int fs_history = this_bx - hit_bx;
0038 fs_segment |= ((fs_history & 0x3) << 4);
0039 return fs_segment;
0040 };
0041
0042
0043 auto update_bt_history = [](int bt_segment, int this_bx, int hit_bx) {
0044
0045 int bt_history = this_bx - hit_bx;
0046 bt_segment |= ((bt_history & 0x3) << 5);
0047 return bt_segment;
0048 };
0049
0050
0051 int num_roads = 0;
0052 for (const auto& roads : zone_roads)
0053 num_roads += roads.size();
0054 bool early_exit = (num_roads == 0);
0055
0056 if (early_exit)
0057 return;
0058
0059 if (verbose_ > 0) {
0060 for (const auto& roads : zone_roads) {
0061 for (const auto& road : roads) {
0062 std::cout << "pattern on match input: z: " << road.Zone() - 1 << " r: " << road.Winner()
0063 << " ph_num: " << road.Key_zhit() << " ph_q: " << to_hex(road.Quality_code())
0064 << " ly: " << to_binary(road.Layer_code(), 3) << " str: " << to_binary(road.Straightness(), 3)
0065 << std::endl;
0066 }
0067 }
0068 }
0069
0070
0071 std::array<EMTFHitCollection, emtf::NUM_ZONES * emtf::NUM_STATIONS> zs_conv_hits;
0072
0073 bool use_fs_zone_code = true;
0074
0075 std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_it = extended_conv_hits.begin();
0076 std::deque<EMTFHitCollection>::const_iterator ext_conv_hits_end = extended_conv_hits.end();
0077
0078 for (; ext_conv_hits_it != ext_conv_hits_end; ++ext_conv_hits_it) {
0079 EMTFHitCollection::const_iterator conv_hits_it = ext_conv_hits_it->begin();
0080 EMTFHitCollection::const_iterator conv_hits_end = ext_conv_hits_it->end();
0081
0082 for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
0083 int istation = conv_hits_it->Station() - 1;
0084 int zone_code = conv_hits_it->Zone_code();
0085 if (use_fs_zone_code)
0086 zone_code = conv_hits_it->FS_zone_code();
0087
0088
0089 for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
0090 if (!zone_roads.at(izone).empty()) {
0091 if (zone_code & (1 << izone)) {
0092 const int zs = (izone * emtf::NUM_STATIONS) + istation;
0093 zs_conv_hits.at(zs).push_back(*conv_hits_it);
0094
0095
0096
0097 EMTFHit& conv_hit = zs_conv_hits.at(zs).back();
0098 int old_fs_segment = conv_hit.FS_segment();
0099 int new_fs_segment = update_fs_history(old_fs_segment, bx_, conv_hit.BX());
0100 conv_hit.set_fs_segment(new_fs_segment);
0101
0102 int old_bt_segment = conv_hit.BT_segment();
0103 int new_bt_segment = update_bt_history(old_bt_segment, bx_, conv_hit.BX());
0104 conv_hit.set_bt_segment(new_bt_segment);
0105 }
0106 }
0107 }
0108
0109 }
0110 }
0111
0112 if (verbose_ > 1) {
0113 for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
0114 for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
0115 const int zs = (izone * emtf::NUM_STATIONS) + istation;
0116 for (const auto& conv_hit : zs_conv_hits.at(zs)) {
0117 std::cout << "z: " << izone << " st: " << istation + 1 << " cscid: " << conv_hit.CSC_ID()
0118 << " ph_zone_phi: " << conv_hit.Zone_hit() << " ph_low_prec: " << (conv_hit.Zone_hit() << 5)
0119 << " ph_high_prec: " << conv_hit.Phi_fp()
0120 << " ph_high_low_diff: " << (conv_hit.Phi_fp() - (conv_hit.Zone_hit() << 5)) << std::endl;
0121 }
0122 }
0123 }
0124 }
0125
0126
0127 std::array<std::vector<hit_sort_pair_t>, emtf::NUM_ZONES * emtf::NUM_STATIONS> zs_phi_differences;
0128
0129
0130
0131 for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
0132 for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
0133 const int zs = (izone * emtf::NUM_STATIONS) + istation;
0134
0135
0136
0137
0138 process_single_zone_station(
0139 izone + 1, istation + 1, zone_roads.at(izone), zs_conv_hits.at(zs), zs_phi_differences.at(zs));
0140 emtf_assert(zone_roads.at(izone).size() == zs_phi_differences.at(zs).size());
0141 }
0142 }
0143
0144 if (verbose_ > 1) {
0145 for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
0146 const auto& roads = zone_roads.at(izone);
0147 for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
0148 const auto& road = roads.at(iroad);
0149 for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
0150 const int zs = (izone * emtf::NUM_STATIONS) + istation;
0151 int ph_diff = zs_phi_differences.at(zs).at(iroad).first;
0152 std::cout << "find seg: z: " << road.Zone() - 1 << " r: " << road.Winner() << " st: " << istation
0153 << " ph_diff: " << ph_diff << std::endl;
0154 }
0155 }
0156 }
0157 }
0158
0159
0160 for (int izone = 0; izone < emtf::NUM_ZONES; ++izone) {
0161 const EMTFRoadCollection& roads = zone_roads.at(izone);
0162
0163 for (unsigned iroad = 0; iroad < roads.size(); ++iroad) {
0164 const EMTFRoad& road = roads.at(iroad);
0165
0166
0167 EMTFTrack track;
0168 track.set_endcap(road.Endcap());
0169 track.set_sector(road.Sector());
0170 track.set_sector_idx(road.Sector_idx());
0171 track.set_bx(road.BX());
0172 track.set_zone(road.Zone());
0173 track.set_ph_num(road.Key_zhit());
0174 track.set_ph_q(road.Quality_code());
0175 track.set_rank(road.Quality_code());
0176 track.set_winner(road.Winner());
0177
0178 track.clear_Hits();
0179
0180
0181 for (int istation = 0; istation < emtf::NUM_STATIONS; ++istation) {
0182 const int zs = (izone * emtf::NUM_STATIONS) + istation;
0183
0184 const EMTFHitCollection& conv_hits = zs_conv_hits.at(zs);
0185 int ph_diff = zs_phi_differences.at(zs).at(iroad).first;
0186 hit_ptr_t conv_hit_ptr = zs_phi_differences.at(zs).at(iroad).second;
0187
0188 if (ph_diff != invalid_ph_diff) {
0189
0190
0191 insert_hits(conv_hit_ptr, conv_hits, track);
0192 }
0193 }
0194
0195 if (fixZonePhi_) {
0196 emtf_assert(!track.Hits().empty());
0197 }
0198
0199
0200 zone_tracks.at(izone).push_back(track);
0201
0202 }
0203 }
0204
0205 if (verbose_ > 0) {
0206 for (const auto& tracks : zone_tracks) {
0207 for (const auto& track : tracks) {
0208 for (const auto& hit : track.Hits()) {
0209 std::cout << "match seg: z: " << track.Zone() - 1 << " pat: " << track.Winner() << " st: " << hit.Station()
0210 << " vi: " << to_binary(0b1, 2) << " hi: " << ((hit.FS_segment() >> 4) & 0x3)
0211 << " ci: " << ((hit.FS_segment() >> 1) & 0x7) << " si: " << (hit.FS_segment() & 0x1)
0212 << " ph: " << hit.Phi_fp() << " th: " << hit.Theta_fp() << std::endl;
0213 }
0214 }
0215 }
0216 }
0217 }
0218
0219 void PrimitiveMatching::process_single_zone_station(int zone,
0220 int station,
0221 const EMTFRoadCollection& roads,
0222 const EMTFHitCollection& conv_hits,
0223 std::vector<hit_sort_pair_t>& phi_differences) const {
0224
0225
0226 int max_ph_diff = (station == 1) ? 15 : 7;
0227
0228
0229
0230 if (fixZonePhi_) {
0231 if (station == 1) {
0232 max_ph_diff = 496;
0233
0234
0235 } else if (station == 2) {
0236 if (bugSt2PhDiff_)
0237 max_ph_diff = 16;
0238 else
0239 max_ph_diff = 240;
0240
0241
0242 } else {
0243 max_ph_diff = 240;
0244
0245
0246 }
0247 }
0248
0249 auto abs_diff = [](int a, int b) { return std::abs(a - b); };
0250
0251
0252 struct {
0253 typedef hit_sort_pair_t value_type;
0254 bool operator()(const value_type& lhs, const value_type& rhs) const { return lhs.first <= rhs.first; }
0255 } less_ph_diff_cmp;
0256
0257
0258 struct {
0259 typedef hit_sort_pair_t value_type;
0260 int operator()(const value_type& a, const value_type& b, const value_type& c) const {
0261 int r = 0;
0262 r |= bool(a.first <= b.first);
0263 r <<= 1;
0264 r |= bool(b.first <= c.first);
0265 r <<= 1;
0266 r |= bool(c.first <= a.first);
0267
0268 int rr = 0;
0269 switch (r) {
0270
0271 case 0b001:
0272 rr = 2;
0273 break;
0274 case 0b010:
0275 rr = 1;
0276 break;
0277 case 0b011:
0278 rr = 1;
0279 break;
0280 case 0b100:
0281 rr = 0;
0282 break;
0283 case 0b101:
0284 rr = 2;
0285 break;
0286 case 0b110:
0287 rr = 0;
0288 break;
0289
0290 default:
0291 rr = 0;
0292 break;
0293 }
0294 return rr;
0295 }
0296 } less_ph_diff_cmp3;
0297
0298
0299
0300
0301 EMTFRoadCollection::const_iterator roads_it = roads.begin();
0302 EMTFRoadCollection::const_iterator roads_end = roads.end();
0303
0304 for (; roads_it != roads_end; ++roads_it) {
0305 int ph_pat = roads_it->Key_zhit();
0306 int ph_q = roads_it->Quality_code();
0307 emtf_assert(ph_pat >= 0 && ph_q > 0);
0308
0309 if (fixZonePhi_) {
0310 ph_pat <<= 5;
0311 }
0312
0313 std::vector<hit_sort_pair_t> tmp_phi_differences;
0314
0315 EMTFHitCollection::const_iterator conv_hits_it = conv_hits.begin();
0316 EMTFHitCollection::const_iterator conv_hits_end = conv_hits.end();
0317
0318 for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
0319 int ph_seg = conv_hits_it->Phi_fp();
0320 int ph_seg_red = ph_seg >> (bw_fph - bpow - 1);
0321 emtf_assert(ph_seg >= 0);
0322
0323 if (fixZonePhi_) {
0324 ph_seg_red = ph_seg;
0325 }
0326
0327
0328 int ph_diff = abs_diff(ph_pat, ph_seg_red);
0329 if (ph_diff > max_ph_diff)
0330 ph_diff = invalid_ph_diff;
0331
0332 if (ph_diff != invalid_ph_diff)
0333 tmp_phi_differences.push_back(std::make_pair(ph_diff, conv_hits_it));
0334 }
0335
0336
0337
0338
0339 if (!tmp_phi_differences.empty()) {
0340
0341
0342
0343 bool use_fw_sorting = true;
0344
0345 if (useNewZones_)
0346 use_fw_sorting = false;
0347
0348 if (use_fw_sorting) {
0349
0350
0351 const int max_drift = 3;
0352 const int zone_cham = ((zone == 1 && (2 <= station && station <= 4)) || (zone == 2 && station == 2)) ? 4 : 7;
0353 const int seg_ch = 2;
0354 const int tot_diff =
0355 (max_drift * zone_cham * seg_ch) + ((zone_cham == 4) ? 3 : 12);
0356
0357 std::vector<hit_sort_pair_t> fw_sort_array(tot_diff, std::make_pair(invalid_ph_diff, conv_hits_end));
0358
0359
0360 std::vector<hit_sort_pair_t>::const_iterator phdiffs_it = tmp_phi_differences.begin();
0361 std::vector<hit_sort_pair_t>::const_iterator phdiffs_end = tmp_phi_differences.end();
0362
0363 for (; phdiffs_it != phdiffs_end; ++phdiffs_it) {
0364
0365 int fs_segment = phdiffs_it->second->FS_segment();
0366
0367
0368 int fs_history = ((fs_segment >> 4) & 0x3);
0369 int fs_chamber = ((fs_segment >> 1) & 0x7);
0370 fs_segment = (fs_segment & 0x1);
0371 unsigned fw_sort_array_index = (fs_history * zone_cham * seg_ch) + (fs_chamber * seg_ch) + fs_segment;
0372
0373 emtf_assert(fs_history < max_drift && fs_chamber < zone_cham && fs_segment < seg_ch);
0374 emtf_assert(fw_sort_array_index < fw_sort_array.size());
0375 fw_sort_array.at(fw_sort_array_index) = *phdiffs_it;
0376 }
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391
0392 merge_sort3_with_hint(fw_sort_array.begin(),
0393 fw_sort_array.end(),
0394 less_ph_diff_cmp,
0395 less_ph_diff_cmp3,
0396 ((tot_diff == 54) ? tot_diff / 2 : tot_diff / 3));
0397
0398
0399 phi_differences.push_back(fw_sort_array.front());
0400
0401
0402
0403
0404
0405
0406
0407 } else {
0408 struct {
0409 typedef hit_sort_pair_t value_type;
0410 bool operator()(const value_type& lhs, const value_type& rhs) const {
0411
0412 if (lhs.second->Subsystem() != rhs.second->Subsystem())
0413 return (lhs.second->Subsystem() == L1TMuon::kCSC);
0414 else
0415 return lhs.first <= rhs.first;
0416 }
0417 } tmp_less_ph_diff_cmp;
0418
0419
0420 std::stable_sort(tmp_phi_differences.begin(), tmp_phi_differences.end(), tmp_less_ph_diff_cmp);
0421
0422
0423 phi_differences.push_back(tmp_phi_differences.front());
0424 }
0425
0426 } else {
0427
0428 phi_differences.push_back(std::make_pair(invalid_ph_diff, conv_hits_end));
0429 }
0430
0431 }
0432 }
0433
0434 void PrimitiveMatching::insert_hits(hit_ptr_t conv_hit_ptr,
0435 const EMTFHitCollection& conv_hits,
0436 EMTFTrack& track) const {
0437 EMTFHitCollection::const_iterator conv_hits_it = conv_hits.begin();
0438 EMTFHitCollection::const_iterator conv_hits_end = conv_hits.end();
0439
0440 const bool is_csc_me11 = (conv_hit_ptr->Subsystem() == L1TMuon::kCSC) && (conv_hit_ptr->Station() == 1) &&
0441 (conv_hit_ptr->Ring() == 1 || conv_hit_ptr->Ring() == 4);
0442
0443
0444 for (; conv_hits_it != conv_hits_end; ++conv_hits_it) {
0445 const EMTFHit& conv_hit_i = *conv_hits_it;
0446 const EMTFHit& conv_hit_j = *conv_hit_ptr;
0447
0448
0449 if ((conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) && (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
0450 (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
0451 (conv_hit_i.Ring() == conv_hit_j.Ring()) &&
0452 (conv_hit_i.Strip() == conv_hit_j.Strip()) &&
0453
0454 (conv_hit_i.Pattern() == conv_hit_j.Pattern()) && (conv_hit_i.BX() == conv_hit_j.BX()) &&
0455 ((conv_hit_i.Is_RPC() == false) ||
0456 ((conv_hit_i.Strip_low() == conv_hit_j.Strip_low()) && (conv_hit_i.Strip_hi() == conv_hit_j.Strip_hi()) &&
0457 (conv_hit_i.Roll() == conv_hit_j.Roll()) && (conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp()) &&
0458 (conv_hit_i.Theta_fp() == conv_hit_j.Theta_fp()))) &&
0459 true) {
0460
0461 emtf_assert(conv_hit_i.Phi_fp() == conv_hit_j.Phi_fp());
0462
0463 track.push_Hit(conv_hit_i);
0464
0465 } else if ((bugME11Dupes_ &&
0466 is_csc_me11) &&
0467 (conv_hit_i.Subsystem() == conv_hit_j.Subsystem()) &&
0468 (conv_hit_i.PC_station() == conv_hit_j.PC_station()) &&
0469 (conv_hit_i.PC_chamber() == conv_hit_j.PC_chamber()) &&
0470
0471
0472
0473
0474 (conv_hit_i.BX() == conv_hit_j.BX()) &&
0475
0476
0477
0478 true) {
0479
0480 EMTFHit tmp_hit = conv_hit_j;
0481 tmp_hit.set_theta_fp(conv_hit_i.Theta_fp());
0482 track.push_Hit(tmp_hit);
0483 }
0484 }
0485
0486
0487 struct {
0488 typedef EMTFHit value_type;
0489 bool operator()(const value_type& lhs, const value_type& rhs) const { return lhs.Station() < rhs.Station(); }
0490 } less_station_cmp;
0491
0492 EMTFHitCollection tmp_hits = track.Hits();
0493 std::stable_sort(tmp_hits.begin(), tmp_hits.end(), less_station_cmp);
0494 track.set_Hits(tmp_hits);
0495 }