Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-01-17 23:31:38

0001 #include "L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h"
0002 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0003 
0004 void SectorProcessorShower::configure(const edm::ParameterSet& pset, int endcap, int sector) {
0005   emtf_assert(emtf::MIN_ENDCAP <= endcap && endcap <= emtf::MAX_ENDCAP);
0006   emtf_assert(emtf::MIN_TRIGSECTOR <= sector && sector <= emtf::MAX_TRIGSECTOR);
0007 
0008   endcap_ = endcap;
0009   sector_ = sector;
0010 
0011   enableTwoLooseShowers_ = pset.getParameter<bool>("enableTwoLooseShowers");
0012   enableOneNominalShower_ = pset.getParameter<bool>("enableOneNominalShowers");
0013   enableOneTightShower_ = pset.getParameter<bool>("enableOneTightShowers");
0014   nLooseShowers_ = pset.getParameter<unsigned>("nLooseShowers");
0015   nNominalShowers_ = pset.getParameter<unsigned>("nNominalShowers");
0016   nTightShowers_ = pset.getParameter<unsigned>("nTightShowers");
0017 }
0018 
0019 void SectorProcessorShower::process(const CSCShowerDigiCollection& in_showers,
0020                                     l1t::RegionalMuonShowerBxCollection& out_showers) const {
0021   // reset
0022   std::vector<CSCShowerDigi> selected_showers;
0023 
0024   // shower selection
0025   auto chamber = in_showers.begin();
0026   auto chend = in_showers.end();
0027   for (; chamber != chend; ++chamber) {
0028     auto digi = (*chamber).second.first;
0029     auto dend = (*chamber).second.second;
0030     for (; digi != dend; ++digi) {
0031       // Returns CSC "link" index (0 - 45)
0032       int selected_shower = select_shower((*chamber).first, *digi);
0033 
0034       // index is valid
0035       if (selected_shower >= 0) {
0036         // 18 in ME1; 9x3 in ME2,3,4
0037         emtf_assert(selected_shower < CSCConstants::MAX_CSCS_PER_EMTF_SP_NO_OVERLAP);
0038 
0039         // shower is valid
0040         if (digi->isValid()) {
0041           selected_showers.emplace_back(*digi);
0042         }
0043       }
0044     }
0045   }
0046 
0047   // Shower recognition logic: at least one nominal shower (see DN-20-033, section 5.2)
0048   const unsigned nLooseInTime(std::count_if(
0049       selected_showers.begin(), selected_showers.end(), [](CSCShowerDigi p) { return p.isLooseInTime(); }));
0050   const unsigned nNominalInTime(std::count_if(
0051       selected_showers.begin(), selected_showers.end(), [](CSCShowerDigi p) { return p.isNominalInTime(); }));
0052   const unsigned nTightInTime(std::count_if(
0053       selected_showers.begin(), selected_showers.end(), [](CSCShowerDigi p) { return p.isTightInTime(); }));
0054 
0055   const bool hasTwoLooseInTime(nLooseInTime >= nLooseShowers_);
0056   const bool hasOneNominalInTime(nNominalInTime >= nNominalShowers_);
0057   const bool hasOneTightInTime(nTightInTime >= nTightShowers_);
0058 
0059   // for startup Run-3 we're not considering out of time triggers
0060   const bool acceptLoose(enableTwoLooseShowers_ and hasTwoLooseInTime);
0061   const bool acceptNominal(enableOneNominalShower_ and hasOneNominalInTime);
0062   const bool acceptTight(enableOneTightShower_ and hasOneTightInTime);
0063 
0064   // trigger condition
0065   const bool accept(acceptLoose or acceptNominal or acceptTight);
0066 
0067   if (accept) {
0068     // shower output
0069     l1t::RegionalMuonShower out_shower(hasOneNominalInTime, false, hasTwoLooseInTime, false, hasOneTightInTime, false);
0070     l1t::tftype tftype = (endcap_ == 1) ? l1t::tftype::emtf_pos : l1t::tftype::emtf_neg;
0071     out_shower.setTFIdentifiers(sector_ - 1, tftype);
0072     out_showers.push_back(0, out_shower);
0073   }
0074 }
0075 
0076 // shower selection
0077 int SectorProcessorShower::select_shower(const CSCDetId& tp_detId, const CSCShowerDigi& shower) const {
0078   int selected = -1;
0079 
0080   int tp_endcap = tp_detId.endcap();
0081   int tp_sector = tp_detId.triggerSector();
0082   int tp_station = tp_detId.station();
0083   int tp_chamber = tp_detId.chamber();
0084   int tp_csc_ID = shower.getCSCID();
0085 
0086   // station 1 --> subsector 1 or 2
0087   // station 2,3,4 --> subsector 0
0088   int tp_subsector = (tp_station != 1) ? 0 : ((tp_chamber % 6 > 2) ? 1 : 2);
0089 
0090   // Check if the chamber belongs to this sector processor at this BX.
0091   selected = get_index_shower(tp_endcap, tp_sector, tp_subsector, tp_station, tp_csc_ID);
0092   return selected;
0093 }
0094 
0095 int SectorProcessorShower::get_index_shower(
0096     int tp_endcap, int tp_sector, int tp_subsector, int tp_station, int tp_csc_ID) const {
0097   int selected = -1;
0098 
0099   // shower trigger does not considers overlaps
0100   if (is_in_sector_csc(tp_endcap, tp_sector)) {
0101     if (tp_station == 1) {  // ME1: 0 - 8, 9 - 17
0102       selected = (tp_subsector - 1) * 9 + (tp_csc_ID - 1);
0103     } else {  // ME2,3,4: 18 - 26, 27 - 35, 36 - 44
0104       selected = (tp_station)*9 + (tp_csc_ID - 1);
0105     }
0106   }
0107 
0108   emtf_assert(selected != -1);
0109   return selected;
0110 }
0111 
0112 bool SectorProcessorShower::is_in_sector_csc(int tp_endcap, int tp_sector) const {
0113   return ((endcap_ == tp_endcap) && (sector_ == tp_sector));
0114 }