File indexing completed on 2024-04-06 12:21:01
0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002
0003 #include "L1Trigger/L1TMuonEndCapPhase2/interface/EMTFContext.h"
0004 #include "L1Trigger/L1TMuonEndCapPhase2/interface/Utils/DataUtils.h"
0005 #include "L1Trigger/L1TMuonEndCapPhase2/interface/Utils/DebugUtils.h"
0006
0007 #include "L1Trigger/L1TMuonEndCapPhase2/interface/Algo/TrackBuildingLayer.h"
0008
0009 using namespace emtf::phase2;
0010 using namespace emtf::phase2::algo;
0011
0012
0013 seg_theta_t TrackBuildingLayer::calc_theta_median(std::vector<seg_theta_t> thetas) {
0014 auto i_last = thetas.size() - 1;
0015
0016
0017
0018 data::mergesort(&thetas[0], thetas.size(), [](seg_theta_t lower_index_value, seg_theta_t larger_index_value) -> int {
0019 return lower_index_value > larger_index_value ? 1 : 0;
0020 });
0021
0022
0023
0024
0025 seg_theta_t invalid_theta = -1;
0026
0027 bool any_invalid = thetas[i_last] == invalid_theta;
0028
0029
0030 if (any_invalid) {
0031
0032 return thetas[0];
0033 } else {
0034
0035 return data::getMedianOfSorted(&thetas[0], thetas.size());
0036 }
0037 }
0038
0039
0040 TrackBuildingLayer::TrackBuildingLayer(const EMTFContext& context) : context_(context) {}
0041
0042 void TrackBuildingLayer::apply(const segment_collection_t& segments,
0043 const std::vector<road_t>& roads,
0044 const bool& displaced_en,
0045 std::vector<track_t>& tracks) const {
0046
0047 for (unsigned int i_road = 0; i_road < roads.size(); ++i_road) {
0048
0049 const auto& road = roads[i_road];
0050 auto& track = tracks.emplace_back();
0051
0052
0053 track.phi = 0;
0054 track.theta = 0;
0055 track.valid = 0;
0056
0057 for (unsigned int site_id = 0; site_id < v3::kNumTrackSites; ++site_id) {
0058 track.site_segs[site_id] = 0;
0059 track.site_mask[site_id] = 0;
0060 track.site_rm_mask[site_id] = 0;
0061 }
0062
0063 for (unsigned int i_feature = 0; i_feature < v3::kNumTrackFeatures; ++i_feature) {
0064 track.features[i_feature] = 0;
0065 }
0066
0067
0068 if (road.quality == 0) {
0069 continue;
0070 }
0071
0072
0073 if (this->context_.config_.verbosity_ > 1) {
0074 if (i_road == 0) {
0075 edm::LogInfo("L1TEMTFpp") << std::endl;
0076 edm::LogInfo("L1TEMTFpp") << "==========================================================================="
0077 << std::endl;
0078 edm::LogInfo("L1TEMTFpp") << "BEGIN TRACK BUILDING" << std::endl;
0079 edm::LogInfo("L1TEMTFpp") << "---------------------------------------------------------------------------"
0080 << std::endl;
0081 }
0082
0083 edm::LogInfo("L1TEMTFpp") << "***************************************************************************"
0084 << std::endl;
0085 edm::LogInfo("L1TEMTFpp") << "Begin building track " << i_road << std::endl;
0086 }
0087
0088
0089 attachSegments(segments, road, displaced_en, track);
0090
0091
0092 if (this->context_.config_.verbosity_ > 1) {
0093 edm::LogInfo("L1TEMTFpp") << "End building track " << i_road << std::endl;
0094
0095 if (i_road == (roads.size() - 1)) {
0096 edm::LogInfo("L1TEMTFpp") << "---------------------------------------------------------------------------"
0097 << std::endl;
0098 edm::LogInfo("L1TEMTFpp") << "END TRACK BUILDING" << std::endl;
0099 edm::LogInfo("L1TEMTFpp") << "==========================================================================="
0100 << std::endl;
0101 }
0102 }
0103 }
0104 }
0105
0106 void TrackBuildingLayer::attachSegments(const segment_collection_t& segments,
0107 const road_t& road,
0108 const bool& displaced_en,
0109 track_t& track) const {
0110
0111
0112
0113 seg_theta_t invalid_theta = -1;
0114
0115
0116
0117
0118
0119
0120
0121
0122 const auto trk_zone = road.zone;
0123 const auto trk_pattern = road.pattern;
0124 const auto trk_quality = road.quality;
0125
0126 int bit_sel_zone = (1u << trk_zone);
0127
0128 const trk_col_t trk_col = road.col + v3::kHitmapCropColStart;
0129 const trk_col_t sector_col = static_cast<trk_col_t>(v3::kHitmapNCols / 2) + v3::kHitmapCropColStart;
0130
0131
0132
0133
0134 std::array<seg_phi_t, v3::kNumTrackSites> trk_seg_phi_diff;
0135 std::array<seg_theta_t, v3::kNumTrackSites> trk_seg_theta;
0136
0137 for (unsigned int site_id = 0; site_id < v3::kNumTrackSites; ++site_id) {
0138 trk_seg_phi_diff[site_id] = 0;
0139 trk_seg_theta[site_id] = 0;
0140 }
0141
0142
0143
0144
0145 const auto& model = context_.model_;
0146 const auto& model_hm = model.zones_[trk_zone].hitmap;
0147 const auto& model_ftc = model.features_;
0148
0149 auto* model_pat = &(model.zones_[trk_zone].prompt_patterns[trk_pattern]);
0150
0151 if (displaced_en) {
0152 model_pat = &(model.zones_[trk_zone].disp_patterns[trk_pattern]);
0153 }
0154
0155
0156
0157
0158
0159
0160 seg_phi_t trk_abs_phi =
0161 (static_cast<seg_phi_t>(trk_col) << v3::kHitmapColFactorLog2) + (1 << (v3::kHitmapColFactorLog2 - 1));
0162 seg_phi_t sector_abs_phi =
0163 (static_cast<seg_phi_t>(sector_col) << v3::kHitmapColFactorLog2) + (1 << (v3::kHitmapColFactorLog2 - 1));
0164
0165
0166
0167 trk_feature_t trk_rel_phi = static_cast<trk_feature_t>(trk_abs_phi) - static_cast<trk_feature_t>(sector_abs_phi);
0168
0169
0170
0171
0172 std::array<trk_col_t, v3::kHitmapNRows> trk_pat_begin;
0173 std::array<trk_col_t, v3::kHitmapNRows> trk_pat_center;
0174 std::array<trk_col_t, v3::kHitmapNRows> trk_pat_end;
0175 std::array<seg_phi_t, v3::kHitmapNRows> trk_pat_phi;
0176
0177 for (unsigned int i_row = 0; i_row < v3::kHitmapNRows; ++i_row) {
0178
0179 const auto& model_pat_row = (*model_pat)[i_row];
0180
0181
0182 trk_pat_begin[i_row] = trk_col + model_pat_row.begin;
0183 trk_pat_center[i_row] = trk_col + model_pat_row.center;
0184 trk_pat_end[i_row] = trk_col + model_pat_row.end;
0185 trk_pat_phi[i_row] = 0;
0186
0187
0188
0189
0190 if (trk_pat_center[i_row] <= v3::kPatternMatchingPadding)
0191 continue;
0192
0193
0194
0195
0196
0197 const auto& temp_trk_pat_center = trk_pat_center[i_row] - v3::kPatternMatchingPadding;
0198
0199
0200 trk_pat_phi[i_row] = (static_cast<seg_phi_t>(temp_trk_pat_center) << v3::kHitmapColFactorLog2) +
0201 (1 << (v3::kHitmapColFactorLog2 - 1));
0202 }
0203
0204
0205
0206
0207
0208
0209 std::vector<std::vector<unsigned int>> site_chambers = {
0210 { 0, 1, 2, 9, 10, 11, 45},
0211 { 3, 4, 5, 12, 13, 14, 46},
0212 { 18, 19, 20, 48, 21, 22, 23, 24, 25, 26, 49},
0213 { 27, 28, 29, 50, 30, 31, 32, 33, 34, 35, 51},
0214 { 36, 37, 38, 52, 39, 40, 41, 42, 43, 44, 53},
0215 { 57, 58, 59, 66, 67, 68, 100},
0216 { 75, 76, 77, 78, 79, 80, 103},
0217 { 81, 82, 83, 104, 84, 85, 86, 87, 88, 89, 105},
0218 { 90, 91, 92, 106, 93, 94, 95, 96, 97, 98, 107},
0219 { 54, 55, 56, 63, 64, 65, 99},
0220 { 72, 73, 74, 102},
0221 {108, 109, 110, 111, 112, 113, 114}
0222 };
0223
0224 std::vector<unsigned int> site_chamber_orders = {
0225 0, 0, 2, 2, 2, 0, 0, 2, 2, 0, 1, 0
0226 };
0227
0228 std::vector<std::vector<int>> chamber_orders = {
0229 {-1, -1, 6, -1, 0, 1, -1, 2, 3, -1, 4, 5},
0230 { 3, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, -1},
0231 { 3, -1, 10, 0, 4, 5, 1, 6, 7, 2, 8, 9}
0232 };
0233
0234
0235 auto n_rows = model_hm.size();
0236
0237 for (unsigned int i_row = 0; i_row < n_rows; ++i_row) {
0238
0239 const auto& model_hm_row = model_hm[i_row];
0240
0241 const auto& trk_pat_row_begin = trk_pat_begin[i_row];
0242 const auto& trk_pat_row_end = trk_pat_end[i_row];
0243 const auto& trk_pat_row_phi = trk_pat_phi[i_row];
0244
0245 if (this->context_.config_.verbosity_ > 2) {
0246 edm::LogInfo("L1TEMTFpp") << "Pattern Row:"
0247 << " row " << i_row << " begin " << trk_pat_row_begin << " end " << trk_pat_row_end
0248 << " phi " << trk_pat_row_phi << std::endl;
0249 }
0250
0251 for (const auto& model_hm_site : model_hm_row) {
0252
0253 const int site_id = static_cast<int>(model_hm_site.id);
0254
0255 auto& site_seg_id = track.site_segs[site_id];
0256 auto& site_bit = track.site_mask[site_id];
0257 auto& site_min_phi_diff = trk_seg_phi_diff[site_id];
0258
0259 const auto& s_chambers = site_chambers[site_id];
0260 const auto& s_chamber_order_id = site_chamber_orders[site_id];
0261 const auto& s_chamber_order = chamber_orders[s_chamber_order_id];
0262
0263 for (const auto& chamber_idx : s_chamber_order) {
0264
0265 if (chamber_idx == -1)
0266 continue;
0267
0268 int chamber_id = s_chambers[chamber_idx];
0269
0270 for (unsigned int i_ch_seg = 0; i_ch_seg < v3::kChamberSegments; ++i_ch_seg) {
0271
0272 const int seg_id = chamber_id * v3::kChamberSegments + i_ch_seg;
0273 const auto& seg = segments[seg_id];
0274
0275
0276 if (!seg.valid) {
0277 continue;
0278 }
0279
0280
0281 if ((seg.zones & bit_sel_zone) != bit_sel_zone) {
0282 continue;
0283 }
0284
0285
0286 const trk_col_t seg_col = (seg.phi >> 4) + v3::kPatternMatchingPadding;
0287
0288 if (!(trk_pat_row_begin <= seg_col && seg_col <= trk_pat_row_end)) {
0289 continue;
0290 }
0291
0292
0293 seg_phi_t diff;
0294
0295 if (trk_pat_row_phi > seg.phi) {
0296 diff = trk_pat_row_phi - seg.phi;
0297 } else {
0298 diff = seg.phi - trk_pat_row_phi;
0299 }
0300
0301 if (this->context_.config_.verbosity_ > 2) {
0302 edm::LogInfo("L1TEMTFpp") << "Site candidate:"
0303 << " site_id " << site_id << " seg_id " << seg_id << " seg_phi " << seg.phi
0304 << " seg_theta1 " << seg.theta1 << " seg_theta2 " << seg.theta2 << " seg_bend "
0305 << seg.bend << std::endl;
0306 }
0307
0308
0309 if (site_bit == 1 && site_min_phi_diff <= diff)
0310 continue;
0311
0312
0313 site_seg_id = seg_id;
0314 site_bit = 1;
0315 site_min_phi_diff = diff;
0316 }
0317
0318 }
0319
0320
0321 if (this->context_.config_.verbosity_ > 2 && site_bit == 1) {
0322 edm::LogInfo("L1TEMTFpp") << "Segment attached:"
0323 << " site_id " << site_id << " seg_id " << site_seg_id << " seg_phi "
0324 << segments[site_seg_id].phi << " seg_theta1 " << segments[site_seg_id].theta1
0325 << " seg_theta2 " << segments[site_seg_id].theta2 << " seg_bend "
0326 << segments[site_seg_id].bend << std::endl;
0327 }
0328 }
0329
0330 }
0331
0332
0333
0334
0335 const auto& model_thmc = model.theta_medians_;
0336
0337 std::vector<seg_theta_t> theta_medians;
0338
0339 for (const auto& model_thm : model_thmc) {
0340
0341 std::vector<seg_theta_t> group_medians;
0342
0343 for (const auto& model_thm_group : model_thm) {
0344
0345 std::vector<seg_theta_t> group;
0346
0347 for (const auto& model_thm_site : model_thm_group) {
0348 int site_id = static_cast<int>(model_thm_site.id);
0349
0350 const auto& site_bit = track.site_mask[site_id];
0351
0352
0353 auto& theta = group.emplace_back(invalid_theta);
0354
0355
0356 if (site_bit == 0)
0357 continue;
0358
0359
0360 const auto& site_seg_id = track.site_segs[site_id];
0361 const auto& site_seg = segments[site_seg_id];
0362
0363 if (model_thm_site.theta_id == theta_id_t::kTheta1) {
0364 theta = site_seg.theta1;
0365 } else if (model_thm_site.theta_id == theta_id_t::kTheta2) {
0366 theta = site_seg.theta2;
0367 }
0368
0369
0370 if (theta == 0) {
0371 theta = invalid_theta;
0372 }
0373 }
0374
0375
0376 if (this->context_.config_.verbosity_ > 2) {
0377 for (const auto& theta : group) {
0378 edm::LogInfo("L1TEMTFpp") << "theta " << theta << std::endl;
0379 }
0380 }
0381
0382 auto group_median = calc_theta_median(group);
0383 group_medians.push_back(group_median);
0384
0385 if (this->context_.config_.verbosity_ > 2) {
0386 edm::LogInfo("L1TEMTFpp") << "group_median " << group_median << std::endl;
0387 }
0388 }
0389
0390
0391 auto theta_median = calc_theta_median(group_medians);
0392 theta_medians.push_back(theta_median);
0393
0394 if (this->context_.config_.verbosity_ > 2) {
0395 edm::LogInfo("L1TEMTFpp") << "theta_median " << theta_median << std::endl;
0396 }
0397 }
0398
0399
0400
0401
0402 seg_theta_t trk_abs_theta;
0403
0404 if (trk_zone != 2) {
0405 trk_abs_theta = theta_medians[0];
0406 } else {
0407 trk_abs_theta = theta_medians[1];
0408 }
0409
0410
0411 if (trk_abs_theta == invalid_theta) {
0412 trk_abs_theta = theta_medians[2];
0413 }
0414
0415
0416 if (trk_abs_theta == invalid_theta) {
0417 trk_abs_theta = 0;
0418 }
0419
0420
0421
0422
0423
0424
0425
0426
0427 std::vector<std::vector<seg_theta_t>> site_theta_window = {
0428 {5, 0, 2, 2, 2, 34, 0, 3, 3, 5, 6, 5},
0429 {5, 9, 5, 4, 5, 14, 7, 7, 7, 7, 7, 4},
0430 {11, 6, 5, 6, 6, 10, 8, 8, 9, 8, 0, 0}
0431 };
0432
0433
0434 if (displaced_en) {
0435
0436 site_theta_window = {
0437 {14, 40, 4, 3, 3, 45, 0, 4, 4, 15, 8, 13},
0438 {16, 18, 7, 5, 5, 22, 7, 7, 8, 17, 9, 14},
0439 {26, 15, 8, 9, 9, 17, 11, 9, 10, 26, 21, 0}
0440 };
0441
0442 }
0443
0444 for (unsigned int site_id = 0; site_id < v3::kNumTrackSites; ++site_id) {
0445 auto& site_bit = track.site_mask[site_id];
0446 auto& site_rm_bit = track.site_rm_mask[site_id];
0447
0448
0449 const auto& theta_window = site_theta_window[trk_zone][site_id];
0450
0451
0452 if (site_bit == 0)
0453 continue;
0454
0455 const auto& site_seg_id = track.site_segs[site_id];
0456 const auto& site_seg = segments[site_seg_id];
0457
0458
0459 seg_theta_t diff_1 = theta_window + 1;
0460 seg_theta_t diff_2 = theta_window + 1;
0461
0462
0463 if (site_seg.theta1 != 0) {
0464 if (site_seg.theta1 < trk_abs_theta) {
0465 diff_1 = trk_abs_theta - site_seg.theta1;
0466 } else {
0467 diff_1 = site_seg.theta1 - trk_abs_theta;
0468 }
0469 }
0470
0471
0472 if (site_seg.theta2 != 0) {
0473 if (site_seg.theta2 < trk_abs_theta) {
0474 diff_2 = trk_abs_theta - site_seg.theta2;
0475 } else {
0476 diff_2 = site_seg.theta2 - trk_abs_theta;
0477 }
0478 }
0479
0480
0481 if (diff_1 <= diff_2 && diff_1 < theta_window) {
0482
0483 trk_seg_theta[site_id] = site_seg.theta1;
0484 } else if (diff_2 < theta_window) {
0485
0486 trk_seg_theta[site_id] = site_seg.theta2;
0487 } else {
0488
0489 site_bit = 0;
0490 site_rm_bit = 1;
0491
0492
0493 if (this->context_.config_.verbosity_ > 4) {
0494 edm::LogInfo("L1TEMTFpp") << "Segment outside of theta window; detatched:"
0495 << " site_id " << site_id << " seg_id " << site_seg_id << " seg_phi " << site_seg.phi
0496 << " seg_theta1 " << site_seg.theta1 << " seg_theta2 " << site_seg.theta2
0497 << std::endl;
0498 }
0499 }
0500 }
0501
0502
0503
0504
0505 track.zone = trk_zone;
0506 track.col = trk_col;
0507 track.pattern = trk_pattern;
0508 track.quality = trk_quality;
0509 track.phi = trk_abs_phi;
0510 track.theta = trk_abs_theta;
0511 track.valid = 1;
0512
0513
0514
0515
0516 int i_feature = 0;
0517
0518 for (auto& model_ft : model_ftc) {
0519 for (auto& model_ft_site : model_ft.sites) {
0520 int site_id = static_cast<int>(model_ft_site);
0521
0522 const auto& site_seg_id = track.site_segs[site_id];
0523 const auto& site_bit = track.site_mask[site_id];
0524 const auto& site_seg = segments[site_seg_id];
0525
0526 auto& trk_feature = track.features[i_feature++];
0527
0528
0529 if (site_bit == 0) {
0530 continue;
0531 }
0532
0533
0534 if (model_ft.id == feature_id_t::kPhi) {
0535
0536 trk_feature = static_cast<trk_feature_t>(site_seg.phi) - static_cast<trk_feature_t>(trk_abs_phi);
0537 } else if (model_ft.id == feature_id_t::kTheta) {
0538
0539 trk_feature = static_cast<trk_feature_t>(trk_seg_theta[site_id]) - static_cast<trk_feature_t>(trk_abs_theta);
0540 } else if (model_ft.id == feature_id_t::kBend) {
0541 trk_feature = site_seg.bend;
0542 } else if (model_ft.id == feature_id_t::kQuality) {
0543 trk_feature = site_seg.qual1;
0544 }
0545 }
0546 }
0547
0548
0549 track.features[i_feature++] = trk_quality > 0 ? trk_rel_phi : decltype(trk_rel_phi)(0);
0550 track.features[i_feature++] = trk_quality > 0 ? trk_abs_theta : decltype(trk_abs_theta)(0);
0551 track.features[i_feature++] = trk_quality;
0552 track.features[i_feature++] = 0;
0553
0554
0555 if (this->context_.config_.verbosity_ > 1) {
0556 edm::LogInfo("L1TEMTFpp") << "Track"
0557 << " zone " << track.zone << " col " << track.col << " pat " << track.pattern << " qual "
0558 << track.quality << " sector_abs_phi " << sector_abs_phi << " abs_phi " << track.phi
0559 << " rel_phi " << trk_rel_phi << " abs_theta " << track.theta << " features "
0560 << std::endl;
0561
0562 for (unsigned int i = 0; i < v3::kNumTrackFeatures; ++i) {
0563 if (i > 0) {
0564 edm::LogInfo("L1TEMTFpp") << " ";
0565 }
0566
0567 edm::LogInfo("L1TEMTFpp") << track.features[i];
0568 }
0569
0570 edm::LogInfo("L1TEMTFpp") << std::endl;
0571 }
0572 }