Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:21:02

0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "FWCore/Framework/interface/ConsumesCollector.h"
0003 
0004 #include "L1Trigger/L1TMuonEndCapPhase2/interface/EMTFConfiguration.h"
0005 #include "L1Trigger/L1TMuonEndCapPhase2/interface/EMTFConstants.h"
0006 #include "L1Trigger/L1TMuonEndCapPhase2/interface/EMTFContext.h"
0007 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/GEMTPCollector.h"
0008 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/SubsystemTags.h"
0009 #include "L1Trigger/L1TMuonEndCapPhase2/interface/DAQ/TPrimitives.h"
0010 #include "L1Trigger/L1TMuonEndCapPhase2/interface/Utils/DebugUtils.h"
0011 
0012 using namespace emtf::phase2;
0013 
0014 GEMTPCollector::GEMTPCollector(const EMTFContext& context, edm::ConsumesCollector& i_consumes_collector)
0015     : context_(context),
0016       input_token_(i_consumes_collector.consumes<GEMTag::collection_type>(context.config_.gem_input_)) {}
0017 
0018 void GEMTPCollector::collect(const edm::Event& i_event, BXTPCMap& bx_tpc_map) const {
0019   // Constants
0020   static const int max_delta_roll = 1;
0021   static const int max_delta_pad_ge11 = 4;
0022   static const int max_delta_pad_ge21 = 4;
0023 
0024   // Read GEM digis
0025   TPCollection tpc;
0026 
0027   edm::Handle<GEMTag::collection_type> gem_digis;
0028   i_event.getByToken(input_token_, gem_digis);
0029 
0030   auto chamber = gem_digis->begin();
0031   auto chend = gem_digis->end();
0032 
0033   for (; chamber != chend; ++chamber) {
0034     auto digi = (*chamber).second.first;
0035     auto dend = (*chamber).second.second;
0036 
0037     for (; digi != dend; ++digi) {
0038       // Short-Circuit: Ignore invalid digis
0039       bool tp_valid = (*digi).isValid();
0040 
0041       if (!tp_valid) {
0042         continue;
0043       }
0044 
0045       // Append digi
0046       tpc.emplace_back((*chamber).first, *digi);
0047     }
0048   }
0049 
0050   // Find Copads
0051   std::map<std::pair<uint32_t, uint16_t>, std::vector<std::array<uint16_t, 3>>> chamber_copads_map;
0052 
0053   for (auto& tp_entry : tpc) {
0054     const auto& tp_det_id = tp_entry.tp_.detId<GEMDetId>();
0055     const GEMData& tp_data = tp_entry.tp_.getGEMData();
0056 
0057     const int tp_region = tp_det_id.region();  // 0: barrel, +/-1: endcap
0058     const int tp_station = tp_det_id.station();
0059     const int tp_ring = tp_det_id.ring();
0060     const int tp_chamber = tp_det_id.chamber();
0061     const int tp_layer = tp_det_id.layer();
0062 
0063     const uint16_t tp_roll = tp_det_id.roll();
0064     const uint16_t tp_pad_lo = tp_data.pad_low;
0065     const uint16_t tp_pad_hi = tp_data.pad_hi;
0066 
0067     const int tp_bx = tp_data.bx + this->context_.config_.gem_bx_shift_;
0068 
0069     GEMDetId tp_mod_det_id(tp_region, tp_ring, tp_station, 0, tp_chamber, 0);
0070     auto key = std::make_pair(tp_mod_det_id.rawId(), tp_bx);
0071 
0072     if (tp_layer == 1) {
0073       // Layer 1 is incidence
0074       // If key does not exist, insert an empty vector. If key exists, do nothing.
0075       decltype(chamber_copads_map)::mapped_type copads;
0076       chamber_copads_map.insert({key, copads});
0077     } else if (tp_layer == 2) {
0078       // Layer 2 is coincidence
0079       decltype(chamber_copads_map)::mapped_type::value_type copad{{tp_roll, tp_pad_lo, tp_pad_hi}};
0080       chamber_copads_map[key].push_back(copad);
0081     }
0082   }
0083 
0084   // Map to BX
0085   for (auto& tp_entry : tpc) {
0086     const auto& tp_det_id = tp_entry.tp_.detId<GEMDetId>();
0087     const GEMData& tp_data = tp_entry.tp_.getGEMData();
0088 
0089     const int tp_region = tp_det_id.region();                    // 0: barrel, +/-1: endcap
0090     const int tp_endcap = (tp_region == -1) ? 2 : tp_region;     // 1: +endcap, 2: -endcap
0091     const int tp_endcap_pm = (tp_endcap == 2) ? -1 : tp_endcap;  // 1: +endcap, -1: -endcap
0092     const int tp_station = tp_det_id.station();
0093     const int tp_ring = tp_det_id.ring();
0094     const int tp_layer = tp_det_id.layer();
0095     const int tp_chamber = tp_det_id.chamber();
0096 
0097     const int tp_roll = tp_det_id.roll();
0098     const int tp_pad = (tp_data.pad_low + tp_data.pad_hi) / 2;
0099     const int tp_pad_lo = tp_data.pad_low;
0100     const int tp_pad_hi = tp_data.pad_hi;
0101 
0102     const int tp_bx = tp_data.bx + this->context_.config_.gem_bx_shift_;
0103 
0104     // Get Copad Info
0105     GEMDetId tp_mod_det_id(tp_region, tp_ring, tp_station, 0, tp_chamber, 0);
0106     auto tp_copads_key = std::make_pair(tp_mod_det_id.rawId(), tp_bx);
0107     auto tp_copads = chamber_copads_map.at(tp_copads_key);
0108 
0109     // Check Copads
0110     bool tp_is_substitute = false;
0111 
0112     if (tp_layer == 1) {
0113       // layer 1 is used as incidence
0114       const bool is_ge21 = (tp_station == 2);
0115 
0116       auto match_fn = [&tp_roll, &tp_pad_lo, &tp_pad_hi, &is_ge21](const std::array<uint16_t, 3>& elem) {
0117         // Unpack entry
0118         // Compare roll and (pad_lo, pad_hi)-range with tolerance
0119         const auto& [c_roll_tmp, c_pad_lo_tmp, c_pad_hi_tmp] = elem;
0120         int c_roll_lo = static_cast<int>(c_roll_tmp) - max_delta_roll;
0121         int c_roll_hi = static_cast<int>(c_roll_tmp) + max_delta_roll;
0122         int c_pad_lo = static_cast<int>(c_pad_lo_tmp) - (is_ge21 ? max_delta_pad_ge21 : max_delta_pad_ge11);
0123         int c_pad_hi = static_cast<int>(c_pad_hi_tmp) + (is_ge21 ? max_delta_pad_ge21 : max_delta_pad_ge11);
0124 
0125         // Two ranges overlap if (range_a_lo <= range_b_hi) and (range_a_hi >= range_b_lo)
0126         return (tp_roll <= c_roll_hi) and (tp_roll >= c_roll_lo) and (tp_pad_lo <= c_pad_hi) and
0127                (tp_pad_hi >= c_pad_lo);
0128       };
0129 
0130       auto match = std::find_if(tp_copads.begin(), tp_copads.end(), match_fn);
0131 
0132       if (match != tp_copads.end()) {
0133         // Has copad
0134         tp_is_substitute = false;
0135       } else if (tp_copads.empty()) {
0136         // Kinda has copad
0137         tp_is_substitute = true;
0138       } else {
0139         // Short-Circuit: Didn't find coincidence
0140         continue;
0141       }
0142     } else if (tp_layer == 2) {
0143       // Short-Circuit: layer 2 is used as coincidence
0144       continue;
0145     }
0146 
0147     // Calculate EMTF Info
0148     const int tp_sector = csc::getTriggerSector(tp_station, tp_ring, tp_chamber);
0149     const int tp_subsector = csc::getTriggerSubsector(tp_station, tp_chamber);
0150     const int tp_csc_id = csc::getId(tp_station, tp_ring, tp_chamber);
0151     const auto tp_csc_facing = csc::getFaceDirection(tp_station, tp_ring, tp_chamber);
0152 
0153     // Assertion checks
0154     emtf_assert(kMinEndcap <= tp_endcap && tp_endcap <= kMaxEndcap);
0155     emtf_assert(kMinTrigSector <= tp_sector && tp_sector <= kMaxTrigSector);
0156     emtf_assert((0 <= tp_subsector) and (tp_subsector <= 2));
0157     emtf_assert(1 <= tp_station && tp_station <= 2);
0158     emtf_assert(tp_ring == 1);
0159     emtf_assert((1 <= tp_chamber) and (tp_chamber <= 36));
0160     emtf_assert(1 <= tp_csc_id && tp_csc_id <= 3);
0161     emtf_assert(tp_station == 1 or (1 <= tp_roll && tp_roll <= 16));
0162     emtf_assert(tp_station != 1 or (1 <= tp_roll && tp_roll <= 8));
0163     emtf_assert(1 <= tp_layer && tp_layer <= 2);
0164     emtf_assert((tp_station == 1 && 0 <= tp_pad && tp_pad <= 191) || (tp_station != 1));
0165     emtf_assert((tp_station == 2 && 0 <= tp_pad && tp_pad <= 383) || (tp_station != 2));
0166 
0167     // Add info
0168     tp_entry.info_.bx = tp_bx;
0169 
0170     tp_entry.info_.endcap = tp_endcap;
0171     tp_entry.info_.endcap_pm = tp_endcap_pm;
0172     tp_entry.info_.sector = tp_sector;
0173     tp_entry.info_.subsector = tp_subsector;
0174     tp_entry.info_.station = tp_station;
0175     tp_entry.info_.ring = tp_ring;
0176     tp_entry.info_.roll = tp_roll;
0177     tp_entry.info_.layer = tp_layer;
0178     tp_entry.info_.chamber = tp_chamber;
0179 
0180     tp_entry.info_.csc_id = tp_csc_id;
0181     tp_entry.info_.csc_facing = tp_csc_facing;
0182 
0183     tp_entry.info_.flag_substitute = tp_is_substitute;
0184 
0185     bx_tpc_map[tp_bx].push_back(tp_entry);
0186   }
0187 }