File indexing completed on 2024-04-06 12:21:03
0001 #include <iostream>
0002
0003 #include "FWCore/Framework/interface/Event.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005
0006 #include "L1Trigger/L1TMuonEndCapPhase2/interface/EMTFConstants.h"
0007 #include "L1Trigger/L1TMuonEndCapPhase2/interface/EMTFContext.h"
0008 #include "L1Trigger/L1TMuonEndCapPhase2/interface/EMTFTypes.h"
0009 #include "L1Trigger/L1TMuonEndCapPhase2/interface/Algo/HitmapLayer.h"
0010 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/CSCTPConverter.h"
0011 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/CSCTPSelector.h"
0012 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/RPCTPConverter.h"
0013 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/RPCTPSelector.h"
0014 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/GEMTPConverter.h"
0015 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/GEMTPSelector.h"
0016 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/ME0TPConverter.h"
0017 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/ME0TPSelector.h"
0018 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/GE0TPConverter.h"
0019 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/GE0TPSelector.h"
0020 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/TPConverters.h"
0021 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/TPSelectors.h"
0022 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/TPrimitives.h"
0023 #include "L1Trigger/L1TMuonEndCapPhase2/interface/Utils/DebugUtils.h"
0024 #include "L1Trigger/L1TMuonEndCapPhase2/interface/Utils/CSCUtils.h"
0025
0026 #include "L1Trigger/L1TMuonEndCapPhase2/interface/SectorProcessor.h"
0027
0028 using namespace emtf::phase2;
0029
0030 SectorProcessor::SectorProcessor(const EMTFContext& context, const int& endcap, const int& sector)
0031 : context_(context), endcap_(endcap), sector_(sector), event_(nullptr), bx_(nullptr) {
0032
0033
0034
0035 if (this->context_.config_.csc_en_) {
0036 tp_selectors_[L1TMuon::kCSC] = std::make_unique<CSCTPSelector>(context_, endcap_, sector_);
0037 tp_converters_[L1TMuon::kCSC] = std::make_unique<CSCTPConverter>(context_, endcap_, sector_);
0038 }
0039
0040 if (this->context_.config_.rpc_en_) {
0041 tp_selectors_[L1TMuon::kRPC] = std::make_unique<RPCTPSelector>(context_, endcap_, sector_);
0042 tp_converters_[L1TMuon::kRPC] = std::make_unique<RPCTPConverter>(context_, endcap_, sector_);
0043 }
0044
0045 if (this->context_.config_.gem_en_) {
0046 tp_selectors_[L1TMuon::kGEM] = std::make_unique<GEMTPSelector>(context_, endcap_, sector_);
0047 tp_converters_[L1TMuon::kGEM] = std::make_unique<GEMTPConverter>(context_, endcap_, sector_);
0048 }
0049
0050 if (this->context_.config_.me0_en_) {
0051 tp_selectors_[L1TMuon::kME0] = std::make_unique<ME0TPSelector>(context_, endcap_, sector_);
0052 tp_converters_[L1TMuon::kME0] = std::make_unique<ME0TPConverter>(context_, endcap_, sector_);
0053 }
0054
0055 if (this->context_.config_.ge0_en_) {
0056 tp_selectors_[L1TMuon::kME0] = std::make_unique<GE0TPSelector>(context_, endcap_, sector_);
0057 tp_converters_[L1TMuon::kME0] = std::make_unique<GE0TPConverter>(context_, endcap_, sector_);
0058 }
0059 }
0060
0061 SectorProcessor::~SectorProcessor() {
0062
0063 }
0064
0065 void SectorProcessor::configureEvent(const edm::Event& event) {
0066
0067 event_ = &event;
0068 bx_ = nullptr;
0069
0070
0071 bx_window_hits_.clear();
0072 bx_ilink_tpc_maps_.clear();
0073 }
0074
0075 void SectorProcessor::configureBx(const int& bx) {
0076
0077 bx_ = &bx;
0078
0079
0080 bx_ilink_tpc_maps_.clear();
0081
0082
0083
0084 const auto min_bx = this->context_.config_.min_bx_;
0085 const auto delay_bx = this->context_.config_.bx_window_ - 1;
0086 const auto pop_after_bx = min_bx + delay_bx;
0087
0088 if (pop_after_bx < bx) {
0089 bx_window_hits_.erase(bx_window_hits_.begin());
0090 }
0091 }
0092
0093 void SectorProcessor::select(const TriggerPrimitive& tp, const TPInfo& tp_info) {
0094
0095 auto tp_subsystem = tp.subsystem();
0096
0097 auto tp_selectors_it = tp_selectors_.find(tp_subsystem);
0098
0099
0100 if (tp_selectors_it == tp_selectors_.end()) {
0101 edm::LogWarning("L1TEMTFpp") << "TPCollector has been implemented, "
0102 << "but there is no TPSelector for " << tp_subsystem;
0103 return;
0104 }
0105
0106
0107 auto& bx_ilink_tpc_map = bx_ilink_tpc_maps_[tp_subsystem];
0108
0109 tp_selectors_it->second->select(tp, tp_info, bx_ilink_tpc_map);
0110 }
0111
0112 void SectorProcessor::process(EMTFHitCollection& out_hits,
0113 EMTFTrackCollection& out_tracks,
0114 EMTFInputCollection& out_inputs) {
0115
0116
0117
0118 ILinkTPCMap bx_ilink_tpc_map;
0119
0120 for (auto& [subsystem, ilink_tpc_map] : bx_ilink_tpc_maps_) {
0121 copyTP(ilink_tpc_map, bx_ilink_tpc_map);
0122 }
0123
0124
0125 bx_ilink_tpc_maps_.clear();
0126
0127
0128
0129
0130
0131
0132 EMTFHitCollection bx_hits;
0133
0134 convertTP(out_hits.size(), bx_ilink_tpc_map, bx_hits);
0135
0136
0137 bx_window_hits_.push_back(bx_hits);
0138
0139
0140 bx_ilink_tpc_map.clear();
0141
0142
0143 out_hits.insert(out_hits.end(), bx_hits.begin(), bx_hits.end());
0144
0145
0146
0147
0148
0149 if ((*bx_) != 0) {
0150 return;
0151 }
0152
0153
0154
0155
0156
0157
0158 std::map<int, int> seg_to_hit;
0159
0160
0161 segment_collection_t segments;
0162
0163 populateSegments(bx_window_hits_, seg_to_hit, segments);
0164
0165
0166 buildTracks(seg_to_hit, segments, false, out_tracks);
0167 buildTracks(seg_to_hit, segments, true, out_tracks);
0168
0169
0170
0171
0172 if (!seg_to_hit.empty()) {
0173 EMTFInput::hits_t hit_id_col;
0174 EMTFInput::segs_t seg_id_col;
0175
0176 for (const auto& [seg_id, hit_id] : seg_to_hit) {
0177 seg_id_col.push_back(seg_id);
0178 hit_id_col.push_back(hit_id);
0179 }
0180
0181 EMTFInput emtf_input;
0182
0183 const int endcap_pm = (endcap_ == 2) ? -1 : endcap_;
0184
0185 emtf_input.setEndcap(endcap_pm);
0186 emtf_input.setSector(sector_);
0187 emtf_input.setBx(*bx_);
0188 emtf_input.setHits(hit_id_col);
0189 emtf_input.setSegs(seg_id_col);
0190
0191 out_inputs.push_back(emtf_input);
0192 }
0193 }
0194
0195 void SectorProcessor::copyTP(const ILinkTPCMap& source, ILinkTPCMap& target) const {
0196 typedef typename ILinkTPCMap::iterator Iterator_t;
0197 typedef typename ILinkTPCMap::mapped_type Collection_t;
0198
0199 for (auto& source_kv : source) {
0200 std::pair<Iterator_t, bool> ins_res = target.insert(source_kv);
0201
0202
0203 if (ins_res.second) {
0204 continue;
0205 }
0206
0207
0208 const Collection_t& source_col = source_kv.second;
0209 Collection_t& target_col = ins_res.first->second;
0210
0211 target_col.insert(target_col.end(), source_col.begin(), source_col.end());
0212 }
0213 }
0214
0215 void SectorProcessor::convertTP(const int& initial_hit_id, const ILinkTPCMap& ilink_tpc_map, EMTFHitCollection& hits) {
0216 EMTFHitCollection substitutes;
0217
0218 for (const auto& [ilink, ilink_tpc] : ilink_tpc_map) {
0219
0220 unsigned int cnt_segments = 0;
0221
0222 for (const auto& tp_entry : ilink_tpc) {
0223
0224
0225 const auto& tp = tp_entry.tp_;
0226 auto tp_info = tp_entry.info_;
0227
0228
0229 auto tp_subsystem = tp.subsystem();
0230
0231
0232 auto tp_converters_it = tp_converters_.find(tp_subsystem);
0233
0234
0235 if (tp_converters_it == tp_converters_.end()) {
0236 edm::LogWarning("L1TEMTFpp") << "TPCollector & TPSelector have been implemented, "
0237 << "but there is no TPConverter for " << tp_subsystem;
0238 continue;
0239 }
0240
0241
0242 tp_info.segment_id = cnt_segments++;
0243
0244
0245 EMTFHit hit;
0246
0247 tp_converters_it->second->convert(tp, tp_info, hit);
0248
0249
0250 if (tp_info.flag_substitute) {
0251 substitutes.push_back(hit);
0252 } else {
0253 hits.push_back(hit);
0254 }
0255 }
0256 }
0257
0258
0259 hits.insert(hits.end(), std::make_move_iterator(substitutes.begin()), std::make_move_iterator(substitutes.end()));
0260
0261
0262 unsigned int cnt_hits = initial_hit_id;
0263
0264 for (auto& hit : hits) {
0265 hit.setId(cnt_hits++);
0266 }
0267 }
0268
0269 void SectorProcessor::populateSegments(const std::vector<EMTFHitCollection>& bx_window_hits,
0270 std::map<int, int>& seg_to_hit,
0271 segment_collection_t& segments) {
0272
0273 for (unsigned int seg_id = 0; seg_id < v3::kNumSegments; ++seg_id) {
0274 segments[seg_id].phi = 0;
0275 segments[seg_id].bend = 0;
0276 segments[seg_id].theta1 = 0;
0277 segments[seg_id].theta2 = 0;
0278 segments[seg_id].qual1 = 0;
0279 segments[seg_id].qual2 = 0;
0280 segments[seg_id].time = 0;
0281 segments[seg_id].zones = 0;
0282 segments[seg_id].tzones = 0;
0283 segments[seg_id].cscfr = 0;
0284 segments[seg_id].layer = 0;
0285 segments[seg_id].bx = 0;
0286 segments[seg_id].valid = 0;
0287 }
0288
0289
0290 auto bx_window_hits_rit = bx_window_hits.rbegin();
0291 auto bx_window_hits_rend = bx_window_hits.rend();
0292
0293 std::map<int, unsigned int> next_ch_seg;
0294
0295 for (; bx_window_hits_rit != bx_window_hits_rend;
0296 ++bx_window_hits_rit) {
0297
0298 const auto& bx_hits = *bx_window_hits_rit;
0299 std::map<int, unsigned int> bx_last_ch_seg;
0300
0301 for (const auto& hit : bx_hits) {
0302
0303 const auto& hit_chamber = hit.emtfChamber();
0304 const auto& hit_segment = hit.emtfSegment();
0305 const auto& hit_valid = hit.flagValid();
0306
0307 emtf_assert(hit_valid);
0308
0309
0310 unsigned int ch_seg = next_ch_seg[hit_chamber] + hit_segment;
0311
0312
0313 if (!(ch_seg < v3::kChamberSegments)) {
0314 continue;
0315 }
0316
0317
0318 const auto& hit_host = hit.emtfHost();
0319
0320
0321
0322 const auto& hit_bx = hit.bx();
0323 const int hit_rel_bx = (hit_bx - *bx_);
0324
0325
0326 if (hit_rel_bx != 0) {
0327 continue;
0328 }
0329
0330
0331 const auto hit_timezones = context_.timezone_lut_.getTimezones(hit_host, hit_rel_bx);
0332
0333
0334 const unsigned int seg_id = hit_chamber * v3::kChamberSegments + ch_seg;
0335
0336 emtf_assert(seg_id < v3::kNumSegments);
0337
0338 seg_to_hit[seg_id] = hit.id();
0339
0340
0341 segments[seg_id].phi = hit.emtfPhi();
0342 segments[seg_id].bend = hit.emtfBend();
0343 segments[seg_id].theta1 = hit.emtfTheta1();
0344 segments[seg_id].theta2 = hit.emtfTheta2();
0345 segments[seg_id].qual1 = hit.emtfQual1();
0346 segments[seg_id].qual2 = hit.emtfQual2();
0347 segments[seg_id].time = hit.emtfTime();
0348 segments[seg_id].zones = hit.emtfZones();
0349 segments[seg_id].tzones = hit_timezones;
0350 segments[seg_id].cscfr = hit.cscFR();
0351 segments[seg_id].layer = hit.layer();
0352 segments[seg_id].bx = hit.bx();
0353 segments[seg_id].valid = hit.flagValid();
0354
0355
0356 if (this->context_.config_.verbosity_ > 1) {
0357 edm::LogInfo("L1TEMTFpp") << std::endl
0358 << "Event: " << event_->id() << " Endcap: " << endcap_ << " Sector: " << sector_
0359 << " BX: " << (*bx_) << " Hit iLink: " << hit_chamber << " Hit iSeg: " << ch_seg
0360 << " Hit Host " << hit_host << " Hit Rel BX " << (hit_bx - *bx_) << " Hit Timezones "
0361 << hit_timezones << std::endl;
0362
0363 edm::LogInfo("L1TEMTFpp") << " id " << seg_id << " phi " << segments[seg_id].phi << " bend "
0364 << segments[seg_id].bend << " theta1 " << segments[seg_id].theta1 << " theta2 "
0365 << segments[seg_id].theta2 << " qual1 " << segments[seg_id].qual1 << " qual2 "
0366 << segments[seg_id].qual2 << " time " << segments[seg_id].time << " zones "
0367 << segments[seg_id].zones << " timezones " << segments[seg_id].tzones << " cscfr "
0368 << segments[seg_id].cscfr << " layer " << segments[seg_id].layer << " bx "
0369 << segments[seg_id].bx << " valid " << segments[seg_id].valid << std::endl;
0370 }
0371
0372
0373 bx_last_ch_seg[hit_chamber] = ch_seg;
0374 }
0375
0376 for (auto& [chamber, ch_seg] : bx_last_ch_seg) {
0377 next_ch_seg[chamber] = ch_seg + 1;
0378 }
0379
0380 bx_last_ch_seg.clear();
0381 }
0382 }
0383
0384 void SectorProcessor::buildTracks(const std::map<int, int>& seg_to_hit,
0385 const segment_collection_t& segments,
0386 const bool& displaced_en,
0387 EMTFTrackCollection& out_tracks) {
0388
0389 std::vector<hitmap_t> zone_hitmaps;
0390
0391 context_.hitmap_building_layer_.apply(segments, zone_hitmaps);
0392
0393
0394 std::vector<road_collection_t> zone_roads;
0395
0396 context_.pattern_matching_layer_.apply(zone_hitmaps, displaced_en, zone_roads);
0397
0398
0399 std::vector<road_t> best_roads;
0400
0401 context_.road_sorting_layer_.apply(v3::kNumTracks, zone_roads, best_roads);
0402
0403
0404 std::vector<track_t> tracks;
0405
0406 context_.track_building_layer_.apply(segments, best_roads, displaced_en, tracks);
0407
0408
0409 context_.duplicate_removal_layer_.apply(tracks);
0410
0411
0412 context_.parameter_assignment_layer_.apply(displaced_en, tracks);
0413
0414
0415 EMTFTrackCollection bx_tracks;
0416
0417 context_.output_layer_.apply(endcap_, sector_, *bx_, seg_to_hit, tracks, displaced_en, bx_tracks);
0418
0419
0420 out_tracks.insert(out_tracks.end(), bx_tracks.begin(), bx_tracks.end());
0421 }