Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:36:59

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   enableOneLooseShower_ = pset.getParameter<bool>("enableOneLooseShower");
0012   enableTwoLooseShowers_ = pset.getParameter<bool>("enableTwoLooseShowers");
0013   enableOneNominalShower_ = pset.getParameter<bool>("enableOneNominalShower");
0014   enableOneTightShower_ = pset.getParameter<bool>("enableOneTightShower");
0015 }
0016 
0017 void SectorProcessorShower::process(const CSCShowerDigiCollection& in_showers,
0018                                     l1t::RegionalMuonShowerBxCollection& out_showers) const {
0019   // reset
0020   std::vector<CSCShowerDigi> selected_showers;
0021 
0022   int bx = 0;
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           bx = digi->getBX() - CSCConstants::LCT_CENTRAL_BX;
0042           selected_showers.emplace_back(*digi);
0043         }
0044       }
0045     }
0046   }
0047 
0048   // Shower recognition logic: at least one nominal shower (see DN-20-033, section 5.2)
0049   // Updated shower recognition logic: at least one loose shower (starting April 2023)
0050   const unsigned nLooseInTime(std::count_if(
0051       selected_showers.begin(), selected_showers.end(), [](CSCShowerDigi p) { return p.isLooseInTime(); }));
0052   const unsigned nNominalInTime(std::count_if(
0053       selected_showers.begin(), selected_showers.end(), [](CSCShowerDigi p) { return p.isNominalInTime(); }));
0054   const unsigned nTightInTime(std::count_if(
0055       selected_showers.begin(), selected_showers.end(), [](CSCShowerDigi p) { return p.isTightInTime(); }));
0056 
0057   const bool hasOneLooseInTime(nLooseInTime >= 1);
0058   const bool hasTwoLooseInTime(nLooseInTime >= 2);
0059   const bool hasOneNominalInTime(nNominalInTime >= 1);
0060   const bool hasOneTightInTime(nTightInTime >= 1);
0061 
0062   // for startup Run-3 we're not considering out of time triggers
0063   const bool acceptLoose(enableOneLooseShower_ and hasOneLooseInTime);
0064   const bool acceptTwoLoose(enableTwoLooseShowers_ and hasTwoLooseInTime);
0065   const bool acceptNominal(enableOneNominalShower_ and hasOneNominalInTime);
0066   const bool acceptTight(enableOneTightShower_ and hasOneTightInTime);
0067 
0068   // trigger condition
0069   const bool accept(acceptLoose or acceptTwoLoose or acceptNominal or acceptTight);
0070 
0071   if (accept) {
0072     // shower output
0073     l1t::RegionalMuonShower out_shower(
0074         hasOneNominalInTime, false, hasTwoLooseInTime, false, hasOneLooseInTime, hasOneTightInTime, false);
0075     l1t::tftype tftype = (endcap_ == 1) ? l1t::tftype::emtf_pos : l1t::tftype::emtf_neg;
0076     out_shower.setTFIdentifiers(sector_ - 1, tftype);
0077     out_showers.push_back(bx, out_shower);
0078   }
0079 }
0080 
0081 // shower selection
0082 int SectorProcessorShower::select_shower(const CSCDetId& tp_detId, const CSCShowerDigi& shower) const {
0083   int selected = -1;
0084 
0085   int tp_endcap = tp_detId.endcap();
0086   int tp_sector = tp_detId.triggerSector();
0087   int tp_station = tp_detId.station();
0088   int tp_chamber = tp_detId.chamber();
0089   int tp_csc_ID = shower.getCSCID();
0090 
0091   // station 1 --> subsector 1 or 2
0092   // station 2,3,4 --> subsector 0
0093   int tp_subsector = (tp_station != 1) ? 0 : ((tp_chamber % 6 > 2) ? 1 : 2);
0094 
0095   // Check if the chamber belongs to this sector processor at this BX.
0096   selected = get_index_shower(tp_endcap, tp_sector, tp_subsector, tp_station, tp_csc_ID);
0097   return selected;
0098 }
0099 
0100 int SectorProcessorShower::get_index_shower(
0101     int tp_endcap, int tp_sector, int tp_subsector, int tp_station, int tp_csc_ID) const {
0102   int selected = -1;
0103 
0104   // shower trigger does not considers overlaps
0105   if (is_in_sector_csc(tp_endcap, tp_sector)) {
0106     if (tp_station == 1) {  // ME1: 0 - 8, 9 - 17
0107       selected = (tp_subsector - 1) * 9 + (tp_csc_ID - 1);
0108     } else {  // ME2,3,4: 18 - 26, 27 - 35, 36 - 44
0109       selected = (tp_station) * 9 + (tp_csc_ID - 1);
0110     }
0111   }
0112 
0113   emtf_assert(selected != -1);
0114   return selected;
0115 }
0116 
0117 bool SectorProcessorShower::is_in_sector_csc(int tp_endcap, int tp_sector) const {
0118   return ((endcap_ == tp_endcap) && (sector_ == tp_sector));
0119 }