diff --git a/DQM/L1TMonitor/interface/L1TStage2uGMT.h b/DQM/L1TMonitor/interface/L1TStage2uGMT.h index 3b42ddd51bcd7..9e3c6bb6f7978 100644 --- a/DQM/L1TMonitor/interface/L1TStage2uGMT.h +++ b/DQM/L1TMonitor/interface/L1TStage2uGMT.h @@ -3,6 +3,8 @@ #include "DataFormats/L1Trigger/interface/Muon.h" #include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h" #include "L1Trigger/L1TMuon/interface/MicroGMTConfiguration.h" #include "DQMServices/Core/interface/DQMEDAnalyzer.h" @@ -27,14 +29,17 @@ class L1TStage2uGMT : public DQMEDAnalyzer { private: l1t::tftype getTfOrigin(const int tfMuonIndex); - edm::EDGetTokenT ugmtBMTFToken; - edm::EDGetTokenT ugmtOMTFToken; - edm::EDGetTokenT ugmtEMTFToken; - edm::EDGetTokenT ugmtMuonToken; - std::string monitorDir; - bool emul; - bool verbose; + edm::EDGetTokenT ugmtBMTFToken_; + edm::EDGetTokenT ugmtOMTFToken_; + edm::EDGetTokenT ugmtEMTFToken_; + edm::EDGetTokenT ugmtMuonToken_; + edm::EDGetTokenT ugmtEMTFShowerToken_; + edm::EDGetTokenT ugmtMuonShowerToken_; + std::string monitorDir_; + bool emul_; + bool verbose_; bool displacedQuantities_; + bool hadronicShowers_; const float etaScale_; const float phiScale_; @@ -94,6 +99,10 @@ class L1TStage2uGMT : public DQMEDAnalyzer { MonitorElement* ugmtEMTFMuMuDPhi; MonitorElement* ugmtEMTFMuMuDR; + MonitorElement* ugmtEMTFShowerTypeOccupancyPerSector; + MonitorElement* ugmtEMTFShowerTypeOccupancyPerBx; + MonitorElement* ugmtEMTFShowerSectorOccupancyPerBx; + MonitorElement* ugmtBOMTFposMuMuDEta; MonitorElement* ugmtBOMTFposMuMuDPhi; MonitorElement* ugmtBOMTFposMuMuDR; @@ -161,6 +170,9 @@ class L1TStage2uGMT : public DQMEDAnalyzer { MonitorElement* ugmtMuonBXvshwIso; MonitorElement* ugmtMuonChargevsLink; + // Output shower plots + MonitorElement* ugmtMuonShowerTypeOccupancyPerBx; + // muon correlations MonitorElement* ugmtMuMuInvMass; MonitorElement* ugmtMuMuInvMassAtVtx; @@ -200,6 +212,9 @@ class L1TStage2uGMT : public DQMEDAnalyzer { MonitorElement* ugmtMuMuDEtaEneg; MonitorElement* ugmtMuMuDPhiEneg; MonitorElement* ugmtMuMuDREneg; + + static constexpr unsigned IDX_TIGHT_SHOWER{2}; + static constexpr unsigned IDX_NOMINAL_SHOWER{1}; }; #endif diff --git a/DQM/L1TMonitor/python/L1TStage2uGMT_cfi.py b/DQM/L1TMonitor/python/L1TStage2uGMT_cfi.py index b3ad6108691e2..f33e5056624d0 100644 --- a/DQM/L1TMonitor/python/L1TStage2uGMT_cfi.py +++ b/DQM/L1TMonitor/python/L1TStage2uGMT_cfi.py @@ -7,13 +7,16 @@ bmtfProducer = cms.InputTag("gmtStage2Digis", "BMTF"), omtfProducer = cms.InputTag("gmtStage2Digis", "OMTF"), emtfProducer = cms.InputTag("gmtStage2Digis", "EMTF"), + emtfShowerProducer = cms.InputTag("gmtStage2Digis", "EMTF"), muonProducer = cms.InputTag("gmtStage2Digis", "Muon"), + muonShowerProducer = cms.InputTag("gmtStage2Digis", "MuonShower"), monitorDir = cms.untracked.string("L1T/L1TStage2uGMT"), emulator = cms.untracked.bool(False), verbose = cms.untracked.bool(False), - displacedQuantities = cms.untracked.bool(False) + displacedQuantities = cms.untracked.bool(False), + hadronicShowers = cms.untracked.bool(False) ) ## Era: Run3_2021; Displaced muons from BMTF used in uGMT from Run-3 from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 -stage2L1Trigger_2021.toModify(l1tStage2uGMT, displacedQuantities = cms.untracked.bool(True)) +stage2L1Trigger_2021.toModify(l1tStage2uGMT, displacedQuantities = cms.untracked.bool(True), hadronicShowers = cms.untracked.bool(True)) diff --git a/DQM/L1TMonitor/src/L1TStage2Shower.cc b/DQM/L1TMonitor/src/L1TStage2Shower.cc index 83fd9cf6bcab4..59d164debe80e 100644 --- a/DQM/L1TMonitor/src/L1TStage2Shower.cc +++ b/DQM/L1TMonitor/src/L1TStage2Shower.cc @@ -166,8 +166,8 @@ void L1TStage2Shower::analyze(const edm::Event& e, const edm::EventSetup& c) { if (not Shower.isValid()) continue; if (Shower.isOneNominalInTime() or Shower.isTwoLooseInTime() or Shower.isOneTightInTime()) { - int endcap = Shower.endcap(); - int sector = Shower.sector(); + int endcap = Shower.trackFinderType() == l1t::tftype::emtf_pos ? 1 : -1; + int sector = Shower.processor() + 1; if (Shower.isOneTightInTime()) emtfShowerTypeOccupancy->Fill(sector, (endcap == 1) ? 7.5 : 0.5); if (Shower.isTwoLooseInTime()) diff --git a/DQM/L1TMonitor/src/L1TStage2uGMT.cc b/DQM/L1TMonitor/src/L1TStage2uGMT.cc index 1996d092b82d0..cda7d7855a031 100644 --- a/DQM/L1TMonitor/src/L1TStage2uGMT.cc +++ b/DQM/L1TMonitor/src/L1TStage2uGMT.cc @@ -1,18 +1,22 @@ #include "DQM/L1TMonitor/interface/L1TStage2uGMT.h" L1TStage2uGMT::L1TStage2uGMT(const edm::ParameterSet& ps) - : ugmtMuonToken(consumes(ps.getParameter("muonProducer"))), - monitorDir(ps.getUntrackedParameter("monitorDir")), - emul(ps.getUntrackedParameter("emulator")), - verbose(ps.getUntrackedParameter("verbose")), + : ugmtMuonToken_(consumes(ps.getParameter("muonProducer"))), + ugmtMuonShowerToken_(consumes(ps.getParameter("muonShowerProducer"))), + monitorDir_(ps.getUntrackedParameter("monitorDir")), + emul_(ps.getUntrackedParameter("emulator")), + verbose_(ps.getUntrackedParameter("verbose")), displacedQuantities_(ps.getUntrackedParameter("displacedQuantities")), + hadronicShowers_(ps.getUntrackedParameter("hadronicShowers")), etaScale_(0.010875), // eta scale (CMS DN-2015/017) phiScale_(0.010908) // phi scale (2*pi/576 HW values) { - if (!emul) { - ugmtBMTFToken = consumes(ps.getParameter("bmtfProducer")); - ugmtOMTFToken = consumes(ps.getParameter("omtfProducer")); - ugmtEMTFToken = consumes(ps.getParameter("emtfProducer")); + if (!emul_) { + ugmtBMTFToken_ = consumes(ps.getParameter("bmtfProducer")); + ugmtOMTFToken_ = consumes(ps.getParameter("omtfProducer")); + ugmtEMTFToken_ = consumes(ps.getParameter("emtfProducer")); + ugmtEMTFShowerToken_ = + consumes(ps.getParameter("emtfShowerProducer")); } } @@ -21,23 +25,26 @@ L1TStage2uGMT::~L1TStage2uGMT() {} void L1TStage2uGMT::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("muonProducer")->setComment("uGMT output muons."); - ; + desc.add("bmtfProducer")->setComment("RegionalMuonCands from BMTF."); desc.add("omtfProducer")->setComment("RegionalMuonCands from OMTF."); desc.add("emtfProducer")->setComment("RegionalMuonCands from EMTF."); + desc.add("muonShowerProducer")->setComment("uGMT output showers."); + desc.add("emtfShowerProducer")->setComment("RegionalMuonShowers from EMTF."); desc.addUntracked("monitorDir", "") ->setComment("Target directory in the DQM file. Will be created if not existing."); desc.addUntracked("emulator", false) ->setComment("Create histograms for muonProducer input only. xmtfProducer inputs are ignored."); desc.addUntracked("verbose", false); desc.addUntracked("displacedQuantities", false); + desc.addUntracked("hadronicShowers", false); descriptions.add("l1tStage2uGMT", desc); } void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, const edm::EventSetup&) { - if (!emul) { + if (!emul_) { // BMTF Input - ibooker.setCurrentFolder(monitorDir + "/BMTFInput"); + ibooker.setCurrentFolder(monitorDir_ + "/BMTFInput"); ugmtBMTFBX = ibooker.book1D("ugmtBMTFBX", "uGMT BMTF Input BX", 7, -3.5, 3.5); ugmtBMTFBX->setAxisTitle("BX", 1); @@ -98,7 +105,7 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, ugmtBMTFMuMuDR->setAxisTitle("#DeltaR", 1); // OMTF Input - ibooker.setCurrentFolder(monitorDir + "/OMTFInput"); + ibooker.setCurrentFolder(monitorDir_ + "/OMTFInput"); ugmtOMTFBX = ibooker.book1D("ugmtOMTFBX", "uGMT OMTF Input BX", 7, -3.5, 3.5); ugmtOMTFBX->setAxisTitle("BX", 1); @@ -165,7 +172,7 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, ugmtOMTFMuMuDR->setAxisTitle("#DeltaR", 1); // EMTF Input - ibooker.setCurrentFolder(monitorDir + "/EMTFInput"); + ibooker.setCurrentFolder(monitorDir_ + "/EMTFInput"); ugmtEMTFBX = ibooker.book1D("ugmtEMTFBX", "uGMT EMTF Input BX", 7, -3.5, 3.5); ugmtEMTFBX->setAxisTitle("BX", 1); @@ -240,8 +247,56 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, ugmtEMTFMuMuDR = ibooker.book1D("ugmtEMTFMuMuDR", "uGMT EMTF input muons #DeltaR between sectors", 50, 0., 0.5); ugmtEMTFMuMuDR->setAxisTitle("#DeltaR", 1); + // EMTF muon showers + if (hadronicShowers_) { + ibooker.setCurrentFolder(monitorDir_ + "/EMTFInput/Muon showers"); + + ugmtEMTFShowerTypeOccupancyPerSector = ibooker.book2D( + "ugmtEMTFShowerTypeOccupancyPerSector", "Shower type occupancy per sector", 12, 1, 13, 2, 1, 3); + ugmtEMTFShowerTypeOccupancyPerSector->setAxisTitle("Processor", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(12, "+6", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(11, "+5", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(10, "+4", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(9, "+3", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(8, "+2", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(7, "+1", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(6, "-6", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(5, "-5", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(4, "-4", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(3, "-3", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(2, "-2", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(1, "-1", 1); + ugmtEMTFShowerTypeOccupancyPerSector->setAxisTitle("Shower type", 2); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(IDX_TIGHT_SHOWER, "Tight", 2); + ugmtEMTFShowerTypeOccupancyPerSector->setBinLabel(IDX_NOMINAL_SHOWER, "Nominal", 2); + + ugmtEMTFShowerTypeOccupancyPerBx = + ibooker.book2D("ugmtEMTFShowerTypeOccupancyPerBx", "Shower type occupancy per BX", 7, -3.5, 3.5, 2, 1, 3); + ugmtEMTFShowerTypeOccupancyPerBx->setAxisTitle("BX", 1); + ugmtEMTFShowerTypeOccupancyPerBx->setAxisTitle("Shower type", 2); + ugmtEMTFShowerTypeOccupancyPerBx->setBinLabel(IDX_TIGHT_SHOWER, "Tight", 2); + ugmtEMTFShowerTypeOccupancyPerBx->setBinLabel(IDX_NOMINAL_SHOWER, "Nominal", 2); + + ugmtEMTFShowerSectorOccupancyPerBx = ibooker.book2D( + "ugmtEMTFShowerSectorOccupancyPerBx", "Shower BX occupancy per sector", 7, -3.5, 3.5, 12, 1, 13); + ugmtEMTFShowerSectorOccupancyPerBx->setAxisTitle("BX", 1); + ugmtEMTFShowerSectorOccupancyPerBx->setAxisTitle("Processor", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(12, "+6", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(11, "+5", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(10, "+4", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(9, "+3", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(8, "+2", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(7, "+1", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(6, "-6", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(5, "-5", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(4, "-4", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(3, "-3", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(2, "-2", 2); + ugmtEMTFShowerSectorOccupancyPerBx->setBinLabel(1, "-1", 2); + } + // inter-TF muon correlations - ibooker.setCurrentFolder(monitorDir + "/muon_correlations"); + ibooker.setCurrentFolder(monitorDir_ + "/muon_correlations"); ugmtBOMTFposMuMuDEta = ibooker.book1D("ugmtBOMTFposMuMuDEta", "uGMT input muons #Delta#eta between BMTF and OMTF+", 100, -0.5, 0.5); @@ -293,9 +348,9 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, } // Subsystem Monitoring and Muon Output - ibooker.setCurrentFolder(monitorDir); + ibooker.setCurrentFolder(monitorDir_); - if (!emul) { + if (!emul_) { ugmtBMTFBXvsProcessor = ibooker.book2D("ugmtBXvsProcessorBMTF", "uGMT BMTF Input BX vs Processor", 12, -0.5, 11.5, 5, -2.5, 2.5); ugmtBMTFBXvsProcessor->setAxisTitle("Wedge", 1); @@ -523,6 +578,15 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, } ugmtMuonChargevsLink->setAxisTitle("Charge", 2); + if (hadronicShowers_) { + ugmtMuonShowerTypeOccupancyPerBx = + ibooker.book2D("ugmtMuonShowerTypeOccupancyPerBx", "Shower type occupancy per BX", 7, -3.5, 3.5, 2, 1, 3); + ugmtMuonShowerTypeOccupancyPerBx->setAxisTitle("BX", 1); + ugmtMuonShowerTypeOccupancyPerBx->setAxisTitle("Shower type", 2); + ugmtMuonShowerTypeOccupancyPerBx->setBinLabel(IDX_TIGHT_SHOWER, "Tight", 2); + ugmtMuonShowerTypeOccupancyPerBx->setBinLabel(IDX_NOMINAL_SHOWER, "Nominal", 2); + } + ugmtMuonBXvshwPt = ibooker.book2D("ugmtMuonBXvshwPt", "uGMT Muon BX vs HW p_{T}", 128, -0.5, 511.5, 5, -2.5, 2.5); ugmtMuonBXvshwPt->setAxisTitle("Hardware p_{T}", 1); ugmtMuonBXvshwPt->setAxisTitle("BX", 2); @@ -554,7 +618,7 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, ugmtMuonBXvshwIso->setAxisTitle("BX", 2); // muon correlations - ibooker.setCurrentFolder(monitorDir + "/muon_correlations"); + ibooker.setCurrentFolder(monitorDir_ + "/muon_correlations"); ugmtMuMuInvMass = ibooker.book1D("ugmtMuMuInvMass", "uGMT dimuon invariant mass", 200, 0., 200.); ugmtMuMuInvMass->setAxisTitle("m(#mu#mu) [GeV]", 1); @@ -680,12 +744,12 @@ void L1TStage2uGMT::bookHistograms(DQMStore::IBooker& ibooker, const edm::Run&, } void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { - if (verbose) + if (verbose_) edm::LogInfo("L1TStage2uGMT") << "L1TStage2uGMT: analyze..." << std::endl; - if (!emul) { + if (!emul_) { edm::Handle BMTFBxCollection; - e.getByToken(ugmtBMTFToken, BMTFBxCollection); + e.getByToken(ugmtBMTFToken_, BMTFBxCollection); ugmtBMTFnMuons->Fill(BMTFBxCollection->size(0)); @@ -734,7 +798,7 @@ void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { } edm::Handle OMTFBxCollection; - e.getByToken(ugmtOMTFToken, OMTFBxCollection); + e.getByToken(ugmtOMTFToken_, OMTFBxCollection); ugmtOMTFnMuons->Fill(OMTFBxCollection->size(0)); @@ -789,7 +853,7 @@ void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { } edm::Handle EMTFBxCollection; - e.getByToken(ugmtEMTFToken, EMTFBxCollection); + e.getByToken(ugmtEMTFToken_, EMTFBxCollection); ugmtEMTFnMuons->Fill(EMTFBxCollection->size(0)); @@ -847,6 +911,38 @@ void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { } } + // Fill shower plots + if (hadronicShowers_) { + edm::Handle EMTFShowersBxCollection; + e.getByToken(ugmtEMTFShowerToken_, EMTFShowersBxCollection); + + for (int itBX = EMTFShowersBxCollection->getFirstBX(); itBX <= EMTFShowersBxCollection->getLastBX(); ++itBX) { + for (l1t::RegionalMuonShowerBxCollection::const_iterator shower = EMTFShowersBxCollection->begin(itBX); + shower != EMTFShowersBxCollection->end(itBX); + ++shower) { + if (not shower->isValid()) { + continue; + } + if (shower->isOneNominalInTime()) { + ugmtEMTFShowerSectorOccupancyPerBx->Fill( + itBX, shower->processor() + 1 + (shower->trackFinderType() == l1t::tftype::emtf_pos ? 6 : 0)); + ugmtEMTFShowerTypeOccupancyPerSector->Fill( + shower->processor() + 1 + (shower->trackFinderType() == l1t::tftype::emtf_pos ? 6 : 0), + IDX_NOMINAL_SHOWER); + ugmtEMTFShowerTypeOccupancyPerBx->Fill(itBX, IDX_NOMINAL_SHOWER); + } + if (shower->isOneTightInTime()) { + ugmtEMTFShowerSectorOccupancyPerBx->Fill( + itBX, shower->processor() + 1 + (shower->trackFinderType() == l1t::tftype::emtf_pos ? 6 : 0)); + ugmtEMTFShowerTypeOccupancyPerSector->Fill( + shower->processor() + 1 + (shower->trackFinderType() == l1t::tftype::emtf_pos ? 6 : 0), + IDX_TIGHT_SHOWER); + ugmtEMTFShowerTypeOccupancyPerBx->Fill(itBX, IDX_TIGHT_SHOWER); + } + } + } + } + // barrel-overlap muon correlations int firstBxBO = (BMTFBxCollection->getFirstBX() < OMTFBxCollection->getFirstBX()) ? OMTFBxCollection->getFirstBX() : BMTFBxCollection->getFirstBX(); @@ -921,7 +1017,7 @@ void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { } edm::Handle MuonBxCollection; - e.getByToken(ugmtMuonToken, MuonBxCollection); + e.getByToken(ugmtMuonToken_, MuonBxCollection); ugmtnMuons->Fill(MuonBxCollection->size(0)); @@ -1062,6 +1158,28 @@ void L1TStage2uGMT::analyze(const edm::Event& e, const edm::EventSetup& c) { } } } + + // Fill shower plots + if (hadronicShowers_) { + edm::Handle showersBxCollection; + e.getByToken(ugmtMuonShowerToken_, showersBxCollection); + + for (int itBX = showersBxCollection->getFirstBX(); itBX <= showersBxCollection->getLastBX(); ++itBX) { + for (l1t::MuonShowerBxCollection::const_iterator shower = showersBxCollection->begin(itBX); + shower != showersBxCollection->end(itBX); + ++shower) { + if (not shower->isValid()) { + continue; + } + if (shower->isOneNominalInTime()) { + ugmtMuonShowerTypeOccupancyPerBx->Fill(itBX, IDX_NOMINAL_SHOWER); + } + if (shower->isOneTightInTime()) { + ugmtMuonShowerTypeOccupancyPerBx->Fill(itBX, IDX_TIGHT_SHOWER); + } + } + } + } } l1t::tftype L1TStage2uGMT::getTfOrigin(const int tfMuonIndex) { diff --git a/DataFormats/L1TMuon/interface/RegionalMuonShower.h b/DataFormats/L1TMuon/interface/RegionalMuonShower.h index 230dc49d12664..0e02146c8ae22 100644 --- a/DataFormats/L1TMuon/interface/RegionalMuonShower.h +++ b/DataFormats/L1TMuon/interface/RegionalMuonShower.h @@ -5,6 +5,8 @@ #include "DataFormats/L1Trigger/interface/BXVector.h" #include "DataFormats/L1Trigger/interface/L1TObjComparison.h" +#include "RegionalMuonCandFwd.h" // For tftype. + namespace l1t { class RegionalMuonShower; @@ -31,9 +33,8 @@ namespace l1t { void setTwoLooseOutOfTime(const bool bit) { isTwoLooseOutOfTime_ = bit; } void setTwoLooseInTime(const bool bit) { isTwoLooseInTime_ = bit; } - void setEndcap(const int endcap) { endcap_ = endcap; } - void setSector(const unsigned sector) { sector_ = sector; } - void setLink(const int link) { link_ = link; }; + /// Set the processor ID, track-finder type. From these two, the link is set + void setTFIdentifiers(int processor, tftype trackFinder); bool isValid() const; bool isOneNominalInTime() const { return isOneNominalInTime_; } @@ -43,10 +44,12 @@ namespace l1t { bool isTwoLooseInTime() const { return isTwoLooseInTime_; } bool isTwoLooseOutOfTime() const { return isTwoLooseOutOfTime_; } - int endcap() const { return endcap_; } - int sector() const { return sector_; } /// Get link on which the MicroGMT receives the candidate - int link() const { return link_; } + const int link() const { return link_; }; + /// Get processor ID on which the candidate was found (0..5 for OMTF/EMTF; 0..11 for BMTF) + const int processor() const { return processor_; }; + /// Get track-finder which found the muon (bmtf, emtf_pos/emtf_neg or omtf_pos/omtf_neg) + const tftype trackFinderType() const { return trackFinder_; }; bool operator==(const l1t::RegionalMuonShower& rhs) const; inline bool operator!=(const l1t::RegionalMuonShower& rhs) const { return !(operator==(rhs)); }; @@ -60,9 +63,9 @@ namespace l1t { bool isOneTightOutOfTime_; bool isTwoLooseInTime_; bool isTwoLooseOutOfTime_; - int endcap_; // +/-1. For ME+ and ME-. - unsigned sector_; // 1 - 6. int link_; + int processor_; + tftype trackFinder_; }; } // namespace l1t diff --git a/DataFormats/L1TMuon/src/RegionalMuonShower.cc b/DataFormats/L1TMuon/src/RegionalMuonShower.cc index ce73da8584331..ba4c68832686b 100644 --- a/DataFormats/L1TMuon/src/RegionalMuonShower.cc +++ b/DataFormats/L1TMuon/src/RegionalMuonShower.cc @@ -12,12 +12,33 @@ l1t::RegionalMuonShower::RegionalMuonShower(bool oneNominalInTime, isOneTightOutOfTime_(oneTightOutOfTime), isTwoLooseInTime_(twoLooseInTime), isTwoLooseOutOfTime_(twoLooseOutOfTime), - endcap_(0), - sector_(0), - link_(0) {} + link_(0), + processor_(0) {} l1t::RegionalMuonShower::~RegionalMuonShower() {} +void l1t::RegionalMuonShower::setTFIdentifiers(int processor, tftype trackFinder) { + trackFinder_ = trackFinder; + processor_ = processor; + + switch (trackFinder_) { + case tftype::emtf_pos: + link_ = processor_ + 36; // range 36...41 + break; + case tftype::omtf_pos: + link_ = processor_ + 42; // range 42...47 + break; + case tftype::bmtf: + link_ = processor_ + 48; // range 48...59 + break; + case tftype::omtf_neg: + link_ = processor_ + 60; // range 60...65 + break; + case tftype::emtf_neg: + link_ = processor_ + 66; // range 66...71 + } +} + bool l1t::RegionalMuonShower::isValid() const { return (isOneNominalInTime_ or isTwoLooseInTime_ or isOneTightInTime_); } diff --git a/DataFormats/L1TMuon/src/classes_def.xml b/DataFormats/L1TMuon/src/classes_def.xml index d045b4388ab55..07cb26f030624 100644 --- a/DataFormats/L1TMuon/src/classes_def.xml +++ b/DataFormats/L1TMuon/src/classes_def.xml @@ -13,7 +13,8 @@ - + + diff --git a/DataFormats/L1Trigger/interface/MuonShower.h b/DataFormats/L1Trigger/interface/MuonShower.h index 15125d77bc548..716737fe71094 100644 --- a/DataFormats/L1Trigger/interface/MuonShower.h +++ b/DataFormats/L1Trigger/interface/MuonShower.h @@ -54,13 +54,15 @@ namespace l1t { The 2 loose showers case would be mapped onto musOutOfTime0 and musOutOfTime1 later during Run-3 */ - void setMus0(const bool bit) { mus0_ = bit; } - void setMus1(const bool bit) { mus1_ = bit; } + void setOneNominalInTime(const bool bit) { oneNominalInTime_ = bit; } + void setOneTightInTime(const bool bit) { oneTightInTime_ = bit; } + void setMus0(const bool bit) { oneNominalInTime_ = bit; } + void setMus1(const bool bit) { oneTightInTime_ = bit; } void setMusOutOfTime0(const bool bit) { musOutOfTime0_ = bit; } void setMusOutOfTime1(const bool bit) { musOutOfTime1_ = bit; } - bool mus0() const { return mus0_; } - bool mus1() const { return mus1_; } + bool mus0() const { return oneNominalInTime_; } + bool mus1() const { return oneTightInTime_; } bool musOutOfTime0() const { return musOutOfTime0_; } bool musOutOfTime1() const { return musOutOfTime1_; } @@ -69,8 +71,8 @@ namespace l1t { // useful members for trigger performance studies // needed at startup Run-3 - bool isOneNominalInTime() const { return mus0_; } - bool isOneTightInTime() const { return mus1_; } + bool isOneNominalInTime() const { return oneNominalInTime_; } + bool isOneTightInTime() const { return oneTightInTime_; } // to be developed during Run-3 bool isTwoLooseInTime() const { return false; } // these options require more study @@ -84,8 +86,8 @@ namespace l1t { private: // Run-3 definitions as provided in DN-20-033 // in time and out-of-time qualities. only 2 bits each. - bool mus0_; - bool mus1_; + bool oneNominalInTime_; + bool oneTightInTime_; bool musOutOfTime0_; bool musOutOfTime1_; }; diff --git a/DataFormats/L1Trigger/src/MuonShower.cc b/DataFormats/L1Trigger/src/MuonShower.cc index 123363221b79e..f80cf8763c7f8 100644 --- a/DataFormats/L1Trigger/src/MuonShower.cc +++ b/DataFormats/L1Trigger/src/MuonShower.cc @@ -9,16 +9,18 @@ l1t::MuonShower::MuonShower(bool oneNominalInTime, : L1Candidate(math::PtEtaPhiMLorentzVector{0., 0., 0., 0.}, 0., 0., 0., 0, 0), // in this object it makes more sense to the different shower types to // the 4 bits, so that the object easily interfaces with the uGT emulator - mus0_(oneNominalInTime), - mus1_(oneTightInTime), + oneNominalInTime_(oneNominalInTime), + oneTightInTime_(oneTightInTime), musOutOfTime0_(false), musOutOfTime1_(false) {} l1t::MuonShower::~MuonShower() {} -bool l1t::MuonShower::isValid() const { return mus0_ or mus1_ or musOutOfTime0_ or musOutOfTime1_; } +bool l1t::MuonShower::isValid() const { + return oneNominalInTime_ or oneTightInTime_ or musOutOfTime0_ or musOutOfTime1_; +} bool l1t::MuonShower::operator==(const l1t::MuonShower& rhs) const { - return (mus0_ == rhs.mus0() and mus1_ == rhs.mus1() and musOutOfTime0_ == rhs.musOutOfTime0() and - musOutOfTime1_ == rhs.musOutOfTime1()); + return (oneNominalInTime_ == rhs.isOneNominalInTime() and oneTightInTime_ == rhs.isOneTightInTime() and + musOutOfTime0_ == rhs.musOutOfTime0() and musOutOfTime1_ == rhs.musOutOfTime1()); } diff --git a/DataFormats/L1Trigger/src/classes_def.xml b/DataFormats/L1Trigger/src/classes_def.xml index b639135a3e1f6..fd7c21da3a2f7 100644 --- a/DataFormats/L1Trigger/src/classes_def.xml +++ b/DataFormats/L1Trigger/src/classes_def.xml @@ -103,7 +103,8 @@ - + + diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CommonTokens.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CommonTokens.h index 5e10377235b2a..a78e7323ad3d3 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CommonTokens.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/CommonTokens.h @@ -6,6 +6,7 @@ #include "DataFormats/L1Trigger/interface/Jet.h" #include "DataFormats/L1Trigger/interface/Tau.h" #include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" #include "FWCore/Utilities/interface/EDGetToken.h" #include "EventFilter/L1TRawToDigi/interface/PackerTokens.h" @@ -19,6 +20,7 @@ namespace l1t { inline const edm::EDGetTokenT& getJetToken() const { return jetToken_; }; inline const edm::EDGetTokenT& getTauToken() const { return tauToken_; }; inline const edm::EDGetTokenT& getMuonToken() const { return muonToken_; }; + inline const edm::EDGetTokenT& getMuonShowerToken() const { return muonShowerToken_; }; protected: edm::EDGetTokenT egammaToken_; @@ -26,6 +28,7 @@ namespace l1t { edm::EDGetTokenT jetToken_; edm::EDGetTokenT tauToken_; edm::EDGetTokenT muonToken_; + edm::EDGetTokenT muonShowerToken_; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.cc index 6ba0a8ebcb1d9..8f998e86820a7 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.cc @@ -11,7 +11,7 @@ namespace l1t { event_.put(std::move(regionalMuonCandsOMTF_), "OMTF"); event_.put(std::move(regionalMuonCandsEMTF_), "EMTF"); event_.put(std::move(muons_[0]), "Muon"); - for (int i = 1; i < 6; ++i) { + for (size_t i = 1; i < NUM_OUTPUT_COPIES; ++i) { event_.put(std::move(muons_[i]), "MuonCopy" + std::to_string(i)); } event_.put(std::move(imdMuonsBMTF_), "imdMuonsBMTF"); @@ -19,6 +19,12 @@ namespace l1t { event_.put(std::move(imdMuonsEMTFPos_), "imdMuonsEMTFPos"); event_.put(std::move(imdMuonsOMTFNeg_), "imdMuonsOMTFNeg"); event_.put(std::move(imdMuonsOMTFPos_), "imdMuonsOMTFPos"); + + event_.put(std::move(regionalMuonShowersEMTF_), "EMTF"); + event_.put(std::move(muonShowers_[0]), "MuonShower"); + for (size_t i = 1; i < NUM_OUTPUT_COPIES; ++i) { + event_.put(std::move(muonShowers_[i]), "MuonShowerCopy" + std::to_string(i)); + } } } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.h index 281b2ba92a2a8..a02b15d107cc7 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTCollections.h @@ -4,6 +4,9 @@ #include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" #include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" + #include "L1TObjectCollections.h" #include @@ -27,10 +30,16 @@ namespace l1t { imdMuonsEMTFNeg_(std::make_unique(0, oFirstBx, oLastBx)), imdMuonsEMTFPos_(std::make_unique(0, oFirstBx, oLastBx)), imdMuonsOMTFNeg_(std::make_unique(0, oFirstBx, oLastBx)), - imdMuonsOMTFPos_(std::make_unique(0, oFirstBx, oLastBx)) { + imdMuonsOMTFPos_(std::make_unique(0, oFirstBx, oLastBx)), + + regionalMuonShowersEMTF_(std::make_unique(0, iFirstBx, iLastBx)), + muonShowers_() { std::generate(muons_.begin(), muons_.end(), [&oFirstBx, &oLastBx] { return std::make_unique(0, oFirstBx, oLastBx); }); + std::generate(muonShowers_.begin(), muonShowers_.end(), [&oFirstBx, &oLastBx] { + return std::make_unique(0, oFirstBx, oLastBx); + }); }; ~GMTCollections() override; @@ -45,6 +54,13 @@ namespace l1t { inline MuonBxCollection* getImdMuonsOMTFNeg() { return imdMuonsOMTFNeg_.get(); }; inline MuonBxCollection* getImdMuonsOMTFPos() { return imdMuonsOMTFPos_.get(); }; + inline RegionalMuonShowerBxCollection* getRegionalMuonShowersEMTF() { return regionalMuonShowersEMTF_.get(); }; + inline MuonShowerBxCollection* getMuonShowers(const unsigned int copy) override { + return muonShowers_[copy].get(); + }; + + static constexpr size_t NUM_OUTPUT_COPIES{6}; + private: std::unique_ptr regionalMuonCandsBMTF_; std::unique_ptr regionalMuonCandsOMTF_; @@ -55,6 +71,9 @@ namespace l1t { std::unique_ptr imdMuonsEMTFPos_; std::unique_ptr imdMuonsOMTFNeg_; std::unique_ptr imdMuonsOMTFPos_; + + std::unique_ptr regionalMuonShowersEMTF_; + std::array, 6> muonShowers_; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc index c4508e7763388..c0846fcddc101 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTSetup.cc @@ -5,11 +5,11 @@ #include "EventFilter/L1TRawToDigi/plugins/PackingSetupFactory.h" #include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h" -#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h" #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h" +#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h" #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h" -#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.h" #include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h" +#include "EventFilter/L1TRawToDigi/plugins/implementations_stage2/IntermediateMuonUnpacker.h" #include "GMTSetup.h" @@ -36,6 +36,8 @@ namespace l1t { ->setComment("uGMT intermediate muon from neg. OMTF side after first sorting stage"); desc.addOptional("ImdInputLabelOMTFPos") ->setComment("uGMT intermediate muon from pos. OMTF side after first sorting stage"); + desc.addOptional("ShowerInputLabel")->setComment("for Run3"); + desc.addOptional("EMTFShowerInputLabel")->setComment("for Run3"); } PackerMap GMTSetup::getPackers(int fed, unsigned int fw) { @@ -43,6 +45,9 @@ namespace l1t { if (fed == 1402) { auto gmt_in_packer = static_pointer_cast( PackerFactory::get()->make("stage2::RegionalMuonGMTPacker")); + if (fw >= 0x7000000) { + gmt_in_packer->setUseEmtfShowers(); + } if (fw >= 0x6010000) { gmt_in_packer->setUseEmtfDisplacementInfo(); } @@ -68,7 +73,7 @@ namespace l1t { prod.produces("OMTF"); prod.produces("EMTF"); prod.produces("Muon"); - for (int i = 1; i < 6; ++i) { + for (size_t i = 1; i < GMTCollections::NUM_OUTPUT_COPIES; ++i) { prod.produces("MuonCopy" + std::to_string(i)); } prod.produces("imdMuonsBMTF"); @@ -76,6 +81,12 @@ namespace l1t { prod.produces("imdMuonsEMTFPos"); prod.produces("imdMuonsOMTFNeg"); prod.produces("imdMuonsOMTFPos"); + + prod.produces("EMTF"); + prod.produces("MuonShower"); + for (size_t i = 1; i < GMTCollections::NUM_OUTPUT_COPIES; ++i) { + prod.produces("MuonShowerCopy" + std::to_string(i)); + } } std::unique_ptr GMTSetup::getCollections(edm::Event& e) { @@ -89,6 +100,9 @@ namespace l1t { // input muons on links 36-71 auto gmt_in_unp = static_pointer_cast( UnpackerFactory::get()->make("stage2::RegionalMuonGMTUnpacker")); + if (fw >= 0x7000000) { + gmt_in_unp->setUseEmtfShowers(); + } if (fw >= 0x6010000) { gmt_in_unp->setUseEmtfDisplacementInfo(); } diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.cc index 39269759ccd0b..2c992a9742c8a 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.cc @@ -26,6 +26,12 @@ namespace l1t { imdMuonTokenEMTFPos_ = cc.consumes(imdEmtfPosTag); imdMuonTokenOMTFNeg_ = cc.consumes(imdOmtfNegTag); imdMuonTokenOMTFPos_ = cc.consumes(imdOmtfPosTag); + + auto emtfShowerTag = cfg.getParameter("EMTFShowerInputLabel"); + auto showerTag = cfg.getParameter("ShowerInputLabel"); + + regionalMuonShowerTokenEMTF_ = cc.consumes(emtfShowerTag); + muonShowerToken_ = cc.consumes(showerTag); } } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.h index 9838e11fed804..6089529a9d47d 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GMTTokens.h @@ -2,6 +2,7 @@ #define GMTTokens_h #include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h" #include "DataFormats/L1Trigger/interface/Muon.h" #include "CommonTokens.h" @@ -27,6 +28,10 @@ namespace l1t { inline const edm::EDGetTokenT& getImdMuonTokenOMTFNeg() const { return imdMuonTokenOMTFNeg_; }; inline const edm::EDGetTokenT& getImdMuonTokenOMTFPos() const { return imdMuonTokenOMTFPos_; }; + inline const edm::EDGetTokenT& getRegionalMuonShowerTokenEMTF() const { + return regionalMuonShowerTokenEMTF_; + }; + private: edm::EDGetTokenT regionalMuonCandTokenBMTF_; edm::EDGetTokenT regionalMuonCandTokenOMTF_; @@ -36,6 +41,8 @@ namespace l1t { edm::EDGetTokenT imdMuonTokenEMTFPos_; edm::EDGetTokenT imdMuonTokenOMTFNeg_; edm::EDGetTokenT imdMuonTokenOMTFPos_; + + edm::EDGetTokenT regionalMuonShowerTokenEMTF_; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.cc index facab356f553e..c033551330b57 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.cc @@ -6,13 +6,14 @@ namespace l1t { namespace stage2 { GTCollections::~GTCollections() { event_.put(std::move(muons_[0]), "Muon"); + event_.put(std::move(muonShowers_[0]), "MuonShower"); event_.put(std::move(egammas_[0]), "EGamma"); event_.put(std::move(etsums_[0]), "EtSum"); event_.put(std::move(jets_[0]), "Jet"); event_.put(std::move(taus_[0]), "Tau"); - for (int i = 1; i < 6; ++i) { event_.put(std::move(muons_[i]), "Muon" + std::to_string(i + 1)); + event_.put(std::move(muonShowers_[i]), "MuonShower" + std::to_string(i + 1)); event_.put(std::move(egammas_[i]), "EGamma" + std::to_string(i + 1)); event_.put(std::move(etsums_[i]), "EtSum" + std::to_string(i + 1)); event_.put(std::move(jets_[i]), "Jet" + std::to_string(i + 1)); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.h index ae71bdb65724f..36dcba98f2507 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTCollections.h @@ -20,6 +20,8 @@ namespace l1t { GTCollections(edm::Event& e) : L1TObjectCollections(e), algBlk_(new GlobalAlgBlkBxCollection()), extBlk_(new GlobalExtBlkBxCollection()) { std::generate(muons_.begin(), muons_.end(), [] { return std::make_unique(); }); + std::generate( + muonShowers_.begin(), muonShowers_.end(), [] { return std::make_unique(); }); std::generate(egammas_.begin(), egammas_.end(), [] { return std::make_unique(); }); std::generate(etsums_.begin(), etsums_.end(), [] { return std::make_unique(); }); std::generate(jets_.begin(), jets_.end(), [] { return std::make_unique(); }); @@ -29,6 +31,9 @@ namespace l1t { ~GTCollections() override; inline MuonBxCollection* getMuons(const unsigned int copy) override { return muons_[copy].get(); }; + inline MuonShowerBxCollection* getMuonShowers(const unsigned int copy) override { + return muonShowers_[copy].get(); + }; inline EGammaBxCollection* getEGammas(const unsigned int copy) override { return egammas_[copy].get(); }; inline EtSumBxCollection* getEtSums(const unsigned int copy) override { return etsums_[copy].get(); }; inline JetBxCollection* getJets(const unsigned int copy) override { return jets_[copy].get(); }; @@ -39,6 +44,7 @@ namespace l1t { private: std::array, 6> muons_; + std::array, 6> muonShowers_; std::array, 6> egammas_; std::array, 6> etsums_; std::array, 6> jets_; diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc index 11b6aec6befd5..3e9e09097373a 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTSetup.cc @@ -21,6 +21,7 @@ namespace l1t { desc.addOptional("GtInputTag")->setComment("for stage2"); desc.addOptional("ExtInputTag")->setComment("for stage2"); desc.addOptional("MuonInputTag")->setComment("for stage2"); + desc.addOptional("ShowerInputTag")->setComment("for Run3"); desc.addOptional("EGammaInputTag")->setComment("for stage2"); desc.addOptional("JetInputTag")->setComment("for stage2"); desc.addOptional("TauInputTag")->setComment("for stage2"); @@ -50,6 +51,7 @@ namespace l1t { void GTSetup::registerProducts(edm::ProducesCollector prod) { prod.produces("Muon"); + prod.produces("MuonShower"); prod.produces("EGamma"); prod.produces("EtSum"); prod.produces("Jet"); @@ -58,6 +60,7 @@ namespace l1t { prod.produces(); for (int i = 2; i < 7; ++i) { // Collections from boards 2-6 prod.produces("Muon" + std::to_string(i)); + prod.produces("MuonShower" + std::to_string(i)); prod.produces("EGamma" + std::to_string(i)); prod.produces("EtSum" + std::to_string(i)); prod.produces("Jet" + std::to_string(i)); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTTokens.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTTokens.cc index 5cf3962495ee4..ed0460ee983f4 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTTokens.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/GTTokens.cc @@ -14,10 +14,12 @@ namespace l1t { auto tautag = cfg.getParameter("TauInputTag"); auto etsumtag = cfg.getParameter("EtSumInputTag"); auto muontag = cfg.getParameter("MuonInputTag"); + auto muonshowertag = cfg.getParameter("ShowerInputLabel"); //cout << "DEBUG: GmtInputTag" << muontag << "\n"; muonToken_ = cc.consumes(muontag); + muonShowerToken_ = cc.consumes(muonshowertag); egammaToken_ = cc.consumes(egammatag); etSumToken_ = cc.consumes(etsumtag); jetToken_ = cc.consumes(jettag); diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h index f543f9ce0ff98..1650face93738 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/L1TObjectCollections.h @@ -6,6 +6,7 @@ #include "DataFormats/L1Trigger/interface/Jet.h" #include "DataFormats/L1Trigger/interface/Tau.h" #include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h" @@ -19,6 +20,7 @@ namespace l1t { ~L1TObjectCollections() override; virtual MuonBxCollection* getMuons(const unsigned int copy) { return nullptr; } + virtual MuonShowerBxCollection* getMuonShowers(const unsigned int copy) { return nullptr; } virtual EGammaBxCollection* getEGammas(const unsigned int copy) { return nullptr; } //= 0; virtual EtSumBxCollection* getEtSums(const unsigned int copy) { return nullptr; } virtual JetBxCollection* getJets(const unsigned int copy) { return nullptr; } diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc index f2d62ae8f8470..adeb75f2628c0 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.cc @@ -6,14 +6,16 @@ namespace l1t { namespace stage2 { Blocks MuonPacker::pack(const edm::Event& event, const PackerTokens* toks) { - edm::Handle muons; - event.getByToken(static_cast(toks)->getMuonToken(), muons); + GMTOutputObjectMap gmtObjMap; + std::pair muonBx = getMuons(gmtObjMap, event, static_cast(toks)->getMuonToken()); + std::pair muonShowerBx{0, 0}; + if ((fedId_ == 1402 && fwId_ >= 0x7000000) || (fedId_ == 1404 && fwId_ >= 0x00010f01)) { + muonShowerBx = getMuonShowers(gmtObjMap, event, static_cast(toks)->getMuonShowerToken()); + } PayloadMap payloadMap; - for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) { - packBx(payloadMap, muons, bx); - } + packBx(gmtObjMap, muonBx.first, muonBx.second, muonShowerBx.first, muonShowerBx.second, payloadMap); Blocks blocks; // push everything in the blocks vector @@ -23,58 +25,98 @@ namespace l1t { return blocks; } - void MuonPacker::packBx(PayloadMap& payloadMap, const edm::Handle& muons, int bx) { - // the first word in every BX and every block id is 0 - for (unsigned int blkId = b1_; blkId < b1_ + 7; blkId += 2) { - payloadMap[blkId].push_back(0); + std::pair MuonPacker::getMuonShowers(GMTOutputObjectMap& objMap, + const edm::Event& event, + const edm::EDGetTokenT& showerToken) { + edm::Handle muonShowers; + event.getByToken(showerToken, muonShowers); + for (int bx = muonShowers->getFirstBX(); bx <= muonShowers->getLastBX(); ++bx) { + if (muonShowers->size(bx) > 0) { + objMap[bx].shower = muonShowers->at(bx, 0); // At most one shower per BX. + } + } + return std::make_pair(muonShowers->getFirstBX(), muonShowers->getLastBX()); + } + + std::pair MuonPacker::getMuons(GMTOutputObjectMap& objMap, + const edm::Event& event, + const edm::EDGetTokenT& muonToken) { + edm::Handle muons; + event.getByToken(muonToken, muons); + for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) { + objMap[bx] = GMTObjects(); + for (auto mu = muons->begin(bx); mu != muons->end(bx); ++mu) { + objMap[bx].mus.push_back(*mu); + } } + return std::make_pair(muons->getFirstBX(), muons->getLastBX()); + } + + void MuonPacker::packBx(const GMTOutputObjectMap& objMap, + const int firstMuonBx, + const int lastMuonBx, + const int firstMuonShowerBx, + const int lastMuonShowerBx, + PayloadMap& payloadMap) { + const auto firstBx{std::min(firstMuonShowerBx, firstMuonBx)}; + const auto lastBx{std::max(lastMuonShowerBx, lastMuonBx)}; - unsigned int blkId = b1_; - auto mu{muons->begin(bx)}; - uint32_t mu1_shared_word{0}; - uint32_t mu2_shared_word{0}; - uint32_t mu1_msw{0}; - uint32_t mu2_msw{0}; - uint32_t mu1_lsw{0}; - uint32_t mu2_lsw{0}; - // Slightly convoluted logic to account for the Run-3 muon readout record: - // To make space for displacement information we moved the raw - // (i.e. non-extrapolated) eta value to the second "spare" word - // in the block which we call "shared word". So the logic below - // needs to be aware if it is operating on the first or second - // muon in the block in order to place the eta value in the right - // place in the shared word. Additionally the logic needs to - // wait for the second muon in the block before filling the - // payload map because the shared word goes in first. - for (int muCtr = 1; muCtr <= 8; ++muCtr) { - if (mu != muons->end(bx)) { - MuonRawDigiTranslator::generatePackedDataWords( - *mu, mu2_shared_word, mu2_lsw, mu2_msw, fedId_, fwId_, 2 - (muCtr % 2)); - ++mu; + for (int bx{firstBx}; bx < lastBx + 1; ++bx) { + // the first word in every BX and every block id is 0 + for (unsigned int blkId = b1_; blkId < b1_ + 7; blkId += 2) { + payloadMap[blkId].push_back(0); } - // If we're remaining in the current block the muon we just packed is the first one in the block. - // If not we add both muons to the payload map and go to the next block. - if (muCtr % 2 == 1) { - mu1_shared_word = mu2_shared_word; - mu1_lsw = mu2_lsw; - mu1_msw = mu2_msw; - } else { - payloadMap[blkId].push_back(mu1_shared_word | mu2_shared_word); - payloadMap[blkId].push_back(mu1_lsw); - payloadMap[blkId].push_back(mu1_msw); - payloadMap[blkId].push_back(mu2_lsw); - payloadMap[blkId].push_back(mu2_msw); + unsigned int blkId = b1_; + uint32_t mu1_shared_word{0}; + uint32_t mu2_shared_word{0}; + uint32_t mu1_msw{0}; + uint32_t mu2_msw{0}; + uint32_t mu1_lsw{0}; + uint32_t mu2_lsw{0}; + auto mu{objMap.at(bx).mus.begin()}; // Need to get the first muon of that bx from the object map + std::array showerWords{ + MuonRawDigiTranslator::getPackedShowerDataWords(objMap.at(bx).shower, fedId_, fwId_)}; + // Slightly convoluted logic to account for the Run-3 muon readout record: + // To make space for displacement information we moved the raw + // (i.e. non-extrapolated) eta value to the second "spare" word + // in the block which we call "shared word". So the logic below + // needs to be aware if it is operating on the first or second + // muon in the block in order to place the eta value in the right + // place in the shared word. Additionally the logic needs to + // wait for the second muon in the block before filling the + // payload map because the shared word goes in first. + for (int muCtr = 1; muCtr <= 8; ++muCtr) { + if (mu != objMap.at(bx).mus.end()) { + MuonRawDigiTranslator::generatePackedMuonDataWords( + *mu, mu2_shared_word, mu2_lsw, mu2_msw, fedId_, fwId_, 2 - (muCtr % 2)); + ++mu; + } + + // If we're remaining in the current block the muon we just packed is the first one in the block. + // If not we add both muons to the payload map and go to the next block. + if (muCtr % 2 == 1) { + mu1_shared_word = mu2_shared_word; + mu1_lsw = mu2_lsw; + mu1_msw = mu2_msw; + mu1_msw |= showerWords.at(muCtr / 2); // Shower bits are added only to the first muon of the link. + } else { + payloadMap[blkId].push_back(mu1_shared_word | mu2_shared_word); + payloadMap[blkId].push_back(mu1_lsw); + payloadMap[blkId].push_back(mu1_msw); + payloadMap[blkId].push_back(mu2_lsw); + payloadMap[blkId].push_back(mu2_msw); - blkId += 2; + blkId += 2; - mu1_shared_word = 0; - mu1_lsw = 0; - mu1_msw = 0; + mu1_shared_word = 0; + mu1_lsw = 0; + mu1_msw = 0; + } + mu2_shared_word = 0; + mu2_lsw = 0; + mu2_msw = 0; } - mu2_shared_word = 0; - mu2_lsw = 0; - mu2_msw = 0; } } } // namespace stage2 diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h index 7cb46c12845bb..fe7be55e6421d 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonPacker.h @@ -18,9 +18,25 @@ namespace l1t { inline void setFed(unsigned fedId) { fedId_ = fedId; }; private: + struct GMTObjects { + std::vector mus; + MuonShower shower; + }; + typedef std::map GMTOutputObjectMap; // Map of BX --> objects typedef std::map> PayloadMap; - void packBx(PayloadMap& payloadMap, const edm::Handle& muons, int bx); + std::pair getMuonShowers(GMTOutputObjectMap& objMap, + const edm::Event& event, + const edm::EDGetTokenT& showerToken); + std::pair getMuons(GMTOutputObjectMap& objMap, + const edm::Event& event, + const edm::EDGetTokenT& muonToken); + void packBx(const GMTOutputObjectMap& objMap, + int firstMuonBx, + int lastMuonBx, + int firstMuonShowerBx, + int lastMuonShowerBx, + PayloadMap& payloadMap); unsigned fwId_{0}; unsigned fedId_{0}; diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc index 1c1b12021aa07..7f2c0125debba 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.cc @@ -8,7 +8,7 @@ namespace l1t { namespace stage2 { - MuonUnpacker::MuonUnpacker() : res_(nullptr), muonCopy_(0) {} + MuonUnpacker::MuonUnpacker() : muonCollection_(nullptr), muonShowerCollection_(nullptr), muonCopy_(0) {} bool MuonUnpacker::unpack(const Block& block, UnpackerCollections* coll) { LogDebug("L1T") << "Block ID = " << block.header().getID() << " size = " << block.header().getSize(); @@ -33,8 +33,12 @@ namespace l1t { getBXRange(nBX, firstBX, lastBX); // Set the muon collection and the BX range - res_ = static_cast(coll)->getMuons(muonCopy_); - res_->setBXRange(firstBX, lastBX); + muonCollection_ = static_cast(coll)->getMuons(muonCopy_); + muonCollection_->setBXRange(firstBX, lastBX); + // Set the muon shower collection and the BX range + muonShowerCollection_ = static_cast(coll)->getMuonShowers(muonCopy_); + muonShowerCollection_->setBXRange(firstBX, lastBX); + LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX; // Get the BX blocks and unpack them @@ -48,15 +52,48 @@ namespace l1t { << " in BX header is outside of the BX range [" << firstBX << "," << lastBX << "] defined in the block header."; } - unpackBx(bx, bxBlock.payload()); + unpackBx(bx, bxBlock.payload(), block.header().getID()); } return true; } - void MuonUnpacker::unpackBx(int bx, const std::vector& payload, unsigned int startIdx) { + void MuonUnpacker::unpackBx(int bx, + const std::vector& payload, + unsigned int blockID, + unsigned int startIdx) { unsigned int i = startIdx + 2; // Only words 2-5 are "standard" muon words. // Check if there are enough words left in the payload if (startIdx + nWords_ <= payload.size()) { + // Unpacking showers. + // The shower from uGMT is transmitted via four links, each link + // carrying on of the bits of the shower. We therefore have to + // determine which link we're looking at and act accordingly. + // Output links are odd and input links are even. + int link_offset{0}; // This is correct for the uGT unpacker + if (fed_ == 1402) { // For uGMT we have to adjust the block/link ID + link_offset = 1; + } + unsigned linkID{(blockID - link_offset) / 2}; + + // Try to get the shower for this BX and if it doesn't exist create an + // empty one and push it in. + // Note: We can't just create it for the first linkID, because in + // prinicple there could be a case where that is removed by the ZS. + MuonShower shower; + if (!muonShowerCollection_->isEmpty(bx)) { + shower = muonShowerCollection_->at(bx, 0); + muonShowerCollection_->erase(bx, 0); + } + if (linkID == 0) { // OneNominal shower + shower.setOneNominalInTime(l1t::MuonRawDigiTranslator::showerFired(payload[i + 1], fed_, getAlgoVersion())); + } else if (linkID == 1) { // OneTight shower + shower.setOneTightInTime(l1t::MuonRawDigiTranslator::showerFired(payload[i + 1], fed_, getAlgoVersion())); + } + + if (shower.isValid()) { + muonShowerCollection_->push_back(bx, shower); + } + for (unsigned nWord = 2; nWord < nWords_; nWord += 2) { // Only words 2-5 are "standard" muon words. uint32_t raw_data_spare = payload[startIdx + 1]; uint32_t raw_data_00_31 = payload[i++]; @@ -78,7 +115,7 @@ namespace l1t { << " iso " << mu.hwIso() << " qual " << mu.hwQual() << " charge " << mu.hwCharge() << " charge valid " << mu.hwChargeValid(); - res_->push_back(bx, mu); + muonCollection_->push_back(bx, mu); } } else { edm::LogWarning("L1T") << "Only " << payload.size() - i << " 32 bit words in this BX but " << nWords_ diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h index bd7ac0bc726cd..f3fe08696b497 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/MuonUnpacker.h @@ -24,11 +24,12 @@ namespace l1t { static constexpr unsigned nWords_ = 6; // every link transmits 6 words (3 muons) per bx static constexpr unsigned bxzs_enable_shift_ = 1; - MuonBxCollection* res_; + MuonBxCollection* muonCollection_; + MuonShowerBxCollection* muonShowerCollection_; int fed_; unsigned int muonCopy_; - void unpackBx(int bx, const std::vector& payload, unsigned int startIdx = 0); + void unpackBx(int bx, const std::vector& payload, unsigned int blockID, unsigned int startIdx = 0); }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc index 36301c3037568..281edd581d460 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.cc @@ -1,3 +1,4 @@ +#include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Framework/interface/Event.h" #include "EventFilter/L1TRawToDigi/plugins/PackerFactory.h" @@ -8,62 +9,121 @@ namespace l1t { namespace stage2 { Blocks RegionalMuonGMTPacker::pack(const edm::Event& event, const PackerTokens* toks) { + GMTObjectMap bmtfObjMap; + GMTObjectMap omtfObjMap; + GMTObjectMap emtfObjMap; auto bmtfToken = static_cast(toks)->getRegionalMuonCandTokenBMTF(); auto omtfToken = static_cast(toks)->getRegionalMuonCandTokenOMTF(); auto emtfToken = static_cast(toks)->getRegionalMuonCandTokenEMTF(); + // First we put the muons in our object map. + std::pair bmtfMuonBx = getMuons(bmtfObjMap, event, bmtfToken); + std::pair omtfMuonBx = getMuons(omtfObjMap, event, omtfToken); + std::pair emtfMuonBx = getMuons(emtfObjMap, event, emtfToken); + + // Then the showers (We don't expect to have shower data from BMTF and OMTF -- at the moment, at least) + std::pair emtfMuonShowerBx{0, 0}; + if (useEmtfShowers_) { + auto emtfShowerToken = static_cast(toks)->getRegionalMuonShowerTokenEMTF(); + emtfMuonShowerBx = getMuonShowers(emtfObjMap, event, emtfShowerToken); + } + Blocks blocks; - // pack the muons for each TF in blocks - packTF(event, bmtfToken, blocks); - packTF(event, omtfToken, blocks); - packTF(event, emtfToken, blocks); + // Pack the muons and showers for each TF in blocks + packTF(bmtfObjMap, bmtfMuonBx.first, bmtfMuonBx.second, 0, 0, blocks); + packTF(omtfObjMap, omtfMuonBx.first, omtfMuonBx.second, 0, 0, blocks); + packTF(emtfObjMap, emtfMuonBx.first, emtfMuonBx.second, emtfMuonShowerBx.first, emtfMuonShowerBx.second, blocks); return blocks; } - void RegionalMuonGMTPacker::packTF(const edm::Event& event, - const edm::EDGetTokenT& tfToken, - Blocks& blocks) { + std::pair RegionalMuonGMTPacker::getMuonShowers( + GMTObjectMap& objMap, + const edm::Event& event, + const edm::EDGetTokenT& tfShowerToken) { + edm::Handle muonShowers; + event.getByToken(tfShowerToken, muonShowers); + for (int bx = muonShowers->getFirstBX(); bx <= muonShowers->getLastBX(); ++bx) { + for (auto muShower = muonShowers->begin(bx); muShower != muonShowers->end(bx); ++muShower) { + objMap[bx][muShower->link()].shower = *muShower; + } + } + return std::make_pair(muonShowers->getFirstBX(), muonShowers->getLastBX()); + } + + std::pair RegionalMuonGMTPacker::getMuons(GMTObjectMap& objMap, + const edm::Event& event, + const edm::EDGetTokenT& tfToken) { edm::Handle muons; event.getByToken(tfToken, muons); + for (int bx = muons->getFirstBX(); bx <= muons->getLastBX(); ++bx) { + for (auto mu = muons->begin(bx); mu != muons->end(bx); ++mu) { + objMap[bx][mu->link()].mus.push_back(*mu); + } + } + return std::make_pair(muons->getFirstBX(), muons->getLastBX()); + } - constexpr unsigned wordsPerBx = 6; // number of 32 bit words per BX + void RegionalMuonGMTPacker::packTF(const GMTObjectMap& objMap, + const int firstMuonBx, + const int lastMuonBx, + const int firstMuonShowerBx, + const int lastMuonShowerBx, + Blocks& blocks) { + const auto firstBx{std::min(firstMuonShowerBx, firstMuonBx)}; + const auto lastBx{std::max(lastMuonShowerBx, lastMuonBx)}; + const auto nBx{lastBx - firstBx + 1}; PayloadMap payloadMap; - const auto nBx = muons->getLastBX() - muons->getFirstBX() + 1; unsigned bxCtr = 0; - for (int i = muons->getFirstBX(); i <= muons->getLastBX(); ++i, ++bxCtr) { - for (auto mu = muons->begin(i); mu != muons->end(i); ++mu) { - const auto linkTimes2 = mu->link() * 2; - - // If the map key is new reserve the payload size. - if (payloadMap.count(linkTimes2) == 0) { - payloadMap[linkTimes2].reserve(wordsPerBx * nBx); - // If there was no muon on the link of this muon in previous - // BX the payload up to this BX must be filled with zeros. - if (bxCtr > 0) { - while (payloadMap[linkTimes2].size() < bxCtr * wordsPerBx) { - payloadMap[linkTimes2].push_back(0); + for (int bx{firstBx}; bx < lastBx + 1; ++bx, ++bxCtr) { + if (objMap.count(bx) > 0) { + for (const auto& linkMap : objMap.at(bx)) { + const auto linkTimes2{linkMap.first * 2}; + const auto gmtObjects{linkMap.second}; + + // If the payload map key is new reserve the payload size. + if (payloadMap.count(linkTimes2) == 0) { + payloadMap[linkTimes2].reserve(wordsPerBx_ * nBx); + // If there was no muon on the link of this muon in previous + // BX the payload up to this BX must be filled with zeros. + if (bxCtr > 0) { + while (payloadMap[linkTimes2].size() < bxCtr * wordsPerBx_) { + payloadMap[linkTimes2].push_back(0); + } } } - } - // Fill the muon in the payload for this link. - uint32_t msw = 0; - uint32_t lsw = 0; + if (gmtObjects.mus.size() > 3) { + edm::LogError("L1T") << "Muon collection for link " << linkMap.first << " has " << gmtObjects.mus.size() + << " entries, but 3 is the maximum!"; + } - RegionalMuonRawDigiTranslator::generatePackedDataWords(*mu, lsw, msw, isKbmtf_, useEmtfDisplacementInfo_); + std::array buf{}; // Making sure contents of buf are initialised to 0. + size_t frameIdx{0}; + for (const auto& mu : gmtObjects.mus) { + // Fill the muon in the payload for this link. + uint32_t msw{0}; + uint32_t lsw{0}; - payloadMap[linkTimes2].push_back(lsw); - payloadMap[linkTimes2].push_back(msw); - } + RegionalMuonRawDigiTranslator::generatePackedDataWords(mu, lsw, msw, isKbmtf_, useEmtfDisplacementInfo_); - // padding to 3 muons per block id (link) per BX - // This can be empty muons as well. + buf.at(frameIdx++) = lsw; + buf.at(frameIdx++) = msw; + } + // Add shower bits to the payload buffer. + RegionalMuonRawDigiTranslator::generatePackedShowerPayload(gmtObjects.shower, buf, useEmtfShowers_); + + payloadMap[linkTimes2].insert( + payloadMap[linkTimes2].end(), std::move_iterator(buf.begin()), std::move_iterator(buf.end())); + } + } + // We now loop over all channels in the payload map and make sure that they are filled up to the current BX + // If they are not, we fill them with zeros for (auto& kv : payloadMap) { - while (kv.second.size() < (bxCtr + 1) * wordsPerBx) { + while (kv.second.size() < (bxCtr + 1) * wordsPerBx_) { kv.second.push_back(0); } } @@ -74,6 +134,7 @@ namespace l1t { blocks.push_back(Block(kv.first, kv.second)); } } + } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h index e3feb1bce562b..fa356b1812256 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTPacker.h @@ -6,6 +6,7 @@ #include "EventFilter/L1TRawToDigi/interface/PackerTokens.h" #include "EventFilter/L1TRawToDigi/interface/Block.h" #include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h" #include "FWCore/Framework/interface/Event.h" namespace l1t { @@ -15,13 +16,33 @@ namespace l1t { Blocks pack(const edm::Event&, const PackerTokens*) override; void setIsKbmtf() { isKbmtf_ = true; }; void setUseEmtfDisplacementInfo() { useEmtfDisplacementInfo_ = true; }; + void setUseEmtfShowers() { useEmtfShowers_ = true; }; private: + struct GMTObjects { + std::vector mus; + RegionalMuonShower shower; + }; + typedef std::map> GMTObjectMap; // Map of BX --> linkID --> objects typedef std::map> PayloadMap; - void packTF(const edm::Event&, const edm::EDGetTokenT&, Blocks&); + void packTF(const GMTObjectMap& objMap, + int firstMuonBx, + int lastMuonBx, + int firstMuonShowerBx, + int lastMuonShowerBx, + Blocks&); + std::pair getMuons(GMTObjectMap& objMap, + const edm::Event& event, + const edm::EDGetTokenT& tfToken); + std::pair getMuonShowers(GMTObjectMap& objMap, + const edm::Event& event, + const edm::EDGetTokenT& tfShowerToken); + + static constexpr size_t wordsPerBx_ = 6; // number of 32 bit words per BX bool isKbmtf_{false}; bool useEmtfDisplacementInfo_{false}; + bool useEmtfShowers_{false}; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc index 57a603a82294e..7f498ef48abe4 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.cc @@ -33,14 +33,19 @@ namespace l1t { // decide which collection to use according to the link ID unsigned int linkId = blockId / 2; int processor; - RegionalMuonCandBxCollection* res; + RegionalMuonCandBxCollection* regionalMuonCollection; + RegionalMuonShowerBxCollection* regionalMuonShowerCollection; tftype trackFinder; if (linkId > 47 && linkId < 60) { - res = static_cast(coll)->getRegionalMuonCandsBMTF(); + regionalMuonCollection = static_cast(coll)->getRegionalMuonCandsBMTF(); + regionalMuonShowerCollection = + new RegionalMuonShowerBxCollection(); // To avoid warning re uninitialised collection trackFinder = tftype::bmtf; processor = linkId - 48; } else if (linkId > 41 && linkId < 66) { - res = static_cast(coll)->getRegionalMuonCandsOMTF(); + regionalMuonCollection = static_cast(coll)->getRegionalMuonCandsOMTF(); + regionalMuonShowerCollection = + new RegionalMuonShowerBxCollection(); // To avoid warning re uninitialised collection if (linkId < 48) { trackFinder = tftype::omtf_pos; processor = linkId - 42; @@ -49,7 +54,8 @@ namespace l1t { processor = linkId - 60; } } else if (linkId > 35 && linkId < 72) { - res = static_cast(coll)->getRegionalMuonCandsEMTF(); + regionalMuonCollection = static_cast(coll)->getRegionalMuonCandsEMTF(); + regionalMuonShowerCollection = static_cast(coll)->getRegionalMuonShowersEMTF(); if (linkId < 42) { trackFinder = tftype::emtf_pos; processor = linkId - 36; @@ -61,7 +67,8 @@ namespace l1t { edm::LogError("L1T") << "No TF muon expected for link " << linkId; return false; } - res->setBXRange(firstBX, lastBX); + regionalMuonCollection->setBXRange(firstBX, lastBX); + regionalMuonShowerCollection->setBXRange(firstBX, lastBX); LogDebug("L1T") << "nBX = " << nBX << " first BX = " << firstBX << " lastBX = " << lastBX; @@ -108,7 +115,13 @@ namespace l1t { << mu.hwPt() << " qual " << mu.hwQual() << " sign " << mu.hwSign() << " sign valid " << mu.hwSignValid() << " unconstrained pT " << mu.hwPtUnconstrained(); - res->push_back(bx, mu); + regionalMuonCollection->push_back(bx, mu); + } + // Fill RegionalMuonShower objects. For this we need to look at all six words together. + RegionalMuonShower muShower; + if (RegionalMuonRawDigiTranslator::fillRegionalMuonShower( + muShower, bxPayload, processor, trackFinder, useEmtfShowers_)) { + regionalMuonShowerCollection->push_back(bx, muShower); } } else { unsigned int nWords = diff --git a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h index f991d1cffdca1..53bf86047dddb 100644 --- a/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h +++ b/EventFilter/L1TRawToDigi/plugins/implementations_stage2/RegionalMuonGMTUnpacker.h @@ -12,6 +12,7 @@ namespace l1t { bool unpack(const Block& block, UnpackerCollections* coll) override; void setIsKbmtf() { isKbmtf_ = true; } void setUseEmtfDisplacementInfo() { useEmtfDisplacementInfo_ = true; } + void setUseEmtfShowers() { useEmtfShowers_ = true; } private: static constexpr unsigned nWords_ = 6; // every link transmits 6 words (3 muons) per bx @@ -19,6 +20,7 @@ namespace l1t { bool isKbmtf_{false}; bool useEmtfDisplacementInfo_{false}; + bool useEmtfShowers_{false}; }; } // namespace stage2 } // namespace l1t diff --git a/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py b/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py index eb031df1e82fd..d581e48f957e5 100644 --- a/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py +++ b/EventFilter/L1TRawToDigi/python/gmtStage2Raw_cfi.py @@ -12,6 +12,8 @@ ImdInputLabelEMTFPos = cms.InputTag("simGmtStage2Digis", "imdMuonsEMTFPos"), ImdInputLabelOMTFNeg = cms.InputTag("simGmtStage2Digis", "imdMuonsOMTFNeg"), ImdInputLabelOMTFPos = cms.InputTag("simGmtStage2Digis", "imdMuonsOMTFPos"), + EMTFShowerInputLabel = cms.InputTag("simEmtfShowers", "EMTF"), + ShowerInputLabel = cms.InputTag("simGmtShowerDigis"), FedId = cms.int32(1402), FWId = cms.uint32(0x3000000), # First used uGMT firmware version lenSlinkHeader = cms.untracked.int32(8), @@ -32,4 +34,4 @@ ### Era: Run3_2021 from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 -stage2L1Trigger_2021.toModify(gmtStage2Raw, BMTFInputLabel = cms.InputTag("simKBmtfDigis", "BMTF"), FWId = cms.uint32(0x6010000)) +stage2L1Trigger_2021.toModify(gmtStage2Raw, BMTFInputLabel = cms.InputTag("simKBmtfDigis", "BMTF"), FWId = cms.uint32(0x7000000)) diff --git a/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py b/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py index 95f3bf6802068..e3d126d7ee523 100644 --- a/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py +++ b/EventFilter/L1TRawToDigi/python/gtStage2Raw_cfi.py @@ -7,6 +7,7 @@ GtInputTag = cms.InputTag("simGtStage2Digis"), ExtInputTag = cms.InputTag("simGtExtFakeStage2Digis"), MuonInputTag = cms.InputTag("simGmtStage2Digis"), + ShowerInputLabel = cms.InputTag("simGmtShowerDigis"), EGammaInputTag = cms.InputTag("simCaloStage2Digis"), TauInputTag = cms.InputTag("simCaloStage2Digis"), JetInputTag = cms.InputTag("simCaloStage2Digis"), @@ -31,4 +32,4 @@ ### Era: Run3_2021 from Configuration.Eras.Modifier_stage2L1Trigger_2021_cff import stage2L1Trigger_2021 -stage2L1Trigger_2021.toModify(gtStage2Raw, FWId = cms.uint32(0x1130)) # FW w/ displaced muon info. +stage2L1Trigger_2021.toModify(gtStage2Raw, FWId = cms.uint32(0x10f01)) # FW w/ displaced muon info and hadronic showers. diff --git a/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h b/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h index cd4ee201a89a6..f0f32df597f9e 100644 --- a/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h +++ b/L1Trigger/L1TMuon/interface/MuonRawDigiTranslator.h @@ -2,6 +2,9 @@ #define MuonRawDigiTranslator_h #include "DataFormats/L1Trigger/interface/Muon.h" +#include "DataFormats/L1Trigger/interface/MuonShower.h" + +#include namespace l1t { class MuonRawDigiTranslator { @@ -15,16 +18,18 @@ namespace l1t { int muInBx); static void fillMuon(Muon& mu, uint32_t raw_data_spare, uint64_t dataword, int fed, unsigned int fw, int muInBx); static void fillIntermediateMuon(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63, unsigned int fw); - static void generatePackedDataWords(const Muon& mu, - uint32_t& raw_data_spare, - uint32_t& raw_data_00_31, - uint32_t& raw_data_32_63, - int fedId, - int fwId, - int muInBx); + static bool showerFired(uint32_t shower_word, int fedId, unsigned int fwId); + static void generatePackedMuonDataWords(const Muon& mu, + uint32_t& raw_data_spare, + uint32_t& raw_data_00_31, + uint32_t& raw_data_32_63, + int fedId, + int fwId, + int muInBx); static void generate64bitDataWord( const Muon& mu, uint32_t& raw_data_spare, uint64_t& dataword, int fedId, int fwId, int muInBx); - static int calcHwEta(const uint32_t& raw, const unsigned absEtaShift, const unsigned etaSignShift); + static std::array getPackedShowerDataWords(const MuonShower& shower, int fedId, unsigned int fwId); + static int calcHwEta(const uint32_t& raw, unsigned absEtaShift, unsigned etaSignShift); static constexpr unsigned ptMask_ = 0x1FF; static constexpr unsigned ptShift_ = 10; @@ -49,6 +54,7 @@ namespace l1t { static constexpr unsigned ptUnconstrainedMask_ = 0xFF; static constexpr unsigned ptUnconstrainedShift_ = 21; static constexpr unsigned ptUnconstrainedIntermedidateShift_ = 0; + static constexpr unsigned showerShift_ = 29; // For Run-3 static constexpr unsigned absEtaMu1Shift_ = 13; // For Run-3 static constexpr unsigned etaMu1SignShift_ = 21; // For Run-3 static constexpr unsigned absEtaMu2Shift_ = 22; // For Run-3 @@ -65,14 +71,14 @@ namespace l1t { int muInBx, bool wasSpecialMWGR = false); static void fillIntermediateMuonQuantitiesRun3(Muon& mu, uint32_t raw_data_00_31, uint32_t raw_data_32_63); - static void generatePackedDataWordsRun3(const Muon& mu, - int abs_eta, - int abs_eta_at_vtx, - uint32_t& raw_data_spare, - uint32_t& raw_data_00_31, - uint32_t& raw_data_32_63, - int muInBx, - bool wasSpecialMWGR = false); + static void generatePackedMuonDataWordsRun3(const Muon& mu, + int abs_eta, + int abs_eta_at_vtx, + uint32_t& raw_data_spare, + uint32_t& raw_data_00_31, + uint32_t& raw_data_32_63, + int muInBx, + bool wasSpecialMWGR = false); }; } // namespace l1t diff --git a/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h b/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h index 3032b3971a240..248851332a7a3 100644 --- a/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h +++ b/L1Trigger/L1TMuon/interface/RegionalMuonRawDigiTranslator.h @@ -2,6 +2,7 @@ #define RegionalMuonRawDigiTranslator_h #include "DataFormats/L1TMuon/interface/RegionalMuonCand.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonShower.h" namespace l1t { class RegionalMuonRawDigiTranslator { @@ -15,11 +16,16 @@ namespace l1t { bool useEmtfDisplacementInfo); static void fillRegionalMuonCand( RegionalMuonCand& mu, uint64_t dataword, int proc, tftype tf, bool isKbmtf, bool useEmtfDisplacementInfo); + static bool fillRegionalMuonShower( + RegionalMuonShower& muShower, std::vector bxPayload, int proc, tftype tf, bool useEmtfShowers); static void generatePackedDataWords(const RegionalMuonCand& mu, uint32_t& raw_data_00_31, uint32_t& raw_data_32_63, bool isKbmtf, bool useEmtfDisplacementInfo); + static void generatePackedShowerPayload(const RegionalMuonShower& shower, + std::array& payload, + bool useEmtfShowers); static uint64_t generate64bitDataWord(const RegionalMuonCand& mu, bool isKbmtf, bool useEmtfDisplacementInfo); static int generateRawTrkAddress(const RegionalMuonCand&, bool isKalman); @@ -45,6 +51,12 @@ namespace l1t { static constexpr unsigned emtfPtUnconstrainedShift_ = 20; static constexpr unsigned trackAddressMask_ = 0x1FFFFFFF; static constexpr unsigned trackAddressShift_ = 2; + static constexpr unsigned emtfShowerMask_ = 0x1; + static constexpr unsigned emtfShowerInTimeFrame_ = 1; + static constexpr unsigned emtfShowerOOTFrame_ = 3; + static constexpr unsigned emtfShowerOneNominalShift_ = 18; + static constexpr unsigned emtfShowerOneTightShift_ = 19; + // relative shifts within track address static constexpr unsigned bmtfTrAddrSegSelMask_ = 0xF; static constexpr unsigned bmtfTrAddrSegSelShift_ = 21; diff --git a/L1Trigger/L1TMuon/python/simDigis_cff.py b/L1Trigger/L1TMuon/python/simDigis_cff.py index 134a832412a95..521660d4717fd 100644 --- a/L1Trigger/L1TMuon/python/simDigis_cff.py +++ b/L1Trigger/L1TMuon/python/simDigis_cff.py @@ -108,7 +108,7 @@ from L1Trigger.L1TMuonBarrel.simKBmtfStubs_cfi import * from L1Trigger.L1TMuonBarrel.simKBmtfDigis_cfi import * from Configuration.Eras.Modifier_phase2_trigger_cff import phase2_trigger -phase2_trigger.toReplaceWith(SimL1TMuonTask, cms.Task(SimL1TMuonCommonTask, simTwinMuxDigis, simBmtfDigis, simKBmtfStubs, simKBmtfDigis, simEmtfDigis, simOmtfDigis, simGmtCaloSumDigis, simGmtStage2Digis)) +phase2_trigger.toReplaceWith(SimL1TMuonTask, cms.Task(SimL1TMuonCommonTask, simTwinMuxDigis, simBmtfDigis, simKBmtfStubs, simKBmtfDigis, simEmtfDigis, simOmtfDigis, simGmtCaloSumDigis, simGmtStage2Digis, simEmtfShowers, simGmtShowerDigis)) ## GEM TPs from L1Trigger.L1TGEM.simGEMDigis_cff import * diff --git a/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc b/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc index 79becf8ea8016..64e75fea6f4e5 100644 --- a/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc +++ b/L1Trigger/L1TMuon/src/MuonRawDigiTranslator.cc @@ -177,13 +177,13 @@ void l1t::MuonRawDigiTranslator::fillIntermediateMuonQuantitiesRun3(Muon& mu, mu.setHwPtUnconstrained((raw_data_00_31 >> ptUnconstrainedIntermedidateShift_) & ptUnconstrainedMask_); } -void l1t::MuonRawDigiTranslator::generatePackedDataWords(const Muon& mu, - uint32_t& raw_data_spare, - uint32_t& raw_data_00_31, - uint32_t& raw_data_32_63, - const int fedID, - const int fwID, - const int muInBx) { +void l1t::MuonRawDigiTranslator::generatePackedMuonDataWords(const Muon& mu, + uint32_t& raw_data_spare, + uint32_t& raw_data_00_31, + uint32_t& raw_data_32_63, + const int fedID, + const int fwID, + const int muInBx) { int abs_eta = mu.hwEta(); if (abs_eta < 0) { abs_eta += (1 << (etaSignShift_ - absEtaShift_)); @@ -212,22 +212,22 @@ void l1t::MuonRawDigiTranslator::generatePackedDataWords(const Muon& mu, (mu.hwPhi() & phiMask_) << phiShift_; } else if ((fedID == 1402 && fwID == 0x6000001) || (fedID == 1404 && fwID < 0x1130)) { // This allows us to unpack data taken in the November 2020 MWGR. - generatePackedDataWordsRun3( + generatePackedMuonDataWordsRun3( mu, abs_eta, abs_eta_at_vtx, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx, true); } else { - generatePackedDataWordsRun3( + generatePackedMuonDataWordsRun3( mu, abs_eta, abs_eta_at_vtx, raw_data_spare, raw_data_00_31, raw_data_32_63, muInBx, false); } } -void l1t::MuonRawDigiTranslator::generatePackedDataWordsRun3(const Muon& mu, - const int abs_eta, - const int abs_eta_at_vtx, - uint32_t& raw_data_spare, - uint32_t& raw_data_00_31, - uint32_t& raw_data_32_63, - const int muInBx, - const bool wasSpecialMWGR /*= false*/) { +void l1t::MuonRawDigiTranslator::generatePackedMuonDataWordsRun3(const Muon& mu, + const int abs_eta, + const int abs_eta_at_vtx, + uint32_t& raw_data_spare, + uint32_t& raw_data_00_31, + uint32_t& raw_data_32_63, + const int muInBx, + const bool wasSpecialMWGR /*= false*/) { int absEtaShiftRun3{0}, etaSignShiftRun3{0}; if (muInBx == 1) { absEtaShiftRun3 = absEtaMu1Shift_; @@ -259,10 +259,28 @@ void l1t::MuonRawDigiTranslator::generate64bitDataWord( uint32_t lsw; uint32_t msw; - generatePackedDataWords(mu, raw_data_spare, lsw, msw, fedId, fwId, muInBx); + generatePackedMuonDataWords(mu, raw_data_spare, lsw, msw, fedId, fwId, muInBx); dataword = (((uint64_t)msw) << 32) + lsw; } +bool l1t::MuonRawDigiTranslator::showerFired(uint32_t shower_word, int fedId, unsigned int fwId) { + if ((fedId == 1402 && fwId >= 0x7000000) || (fedId == 1404 && fwId >= 0x00010f01)) { + return ((shower_word >> showerShift_) & 1) == 1; + } + return false; +} + +std::array l1t::MuonRawDigiTranslator::getPackedShowerDataWords(const MuonShower& shower, + const int fedId, + const unsigned int fwId) { + std::array res{}; + if ((fedId == 1402 && fwId >= 0x7000000) || (fedId == 1404 && fwId >= 0x00010f01)) { + res.at(0) = shower.isOneNominalInTime() ? (1 << showerShift_) : 0; + res.at(1) = shower.isOneTightInTime() ? (1 << showerShift_) : 0; + } + return res; +} + int l1t::MuonRawDigiTranslator::calcHwEta(const uint32_t& raw, const unsigned absEtaShift, const unsigned etaSignShift) { diff --git a/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc b/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc index d144a84ca0df5..ce363b405a853 100644 --- a/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc +++ b/L1Trigger/L1TMuon/src/RegionalMuonRawDigiTranslator.cc @@ -76,12 +76,15 @@ void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand(RegionalMuonCand& mu.setTrackSubAddress(RegionalMuonCand::kME3Ch, (rawTrackAddress >> emtfTrAddrMe3ChShift_) & emtfTrAddrMe3ChMask_); mu.setTrackSubAddress(RegionalMuonCand::kME4Seg, (rawTrackAddress >> emtfTrAddrMe4SegShift_) & 0x1); mu.setTrackSubAddress(RegionalMuonCand::kME4Ch, (rawTrackAddress >> emtfTrAddrMe4ChShift_) & emtfTrAddrMe4ChMask_); - mu.setTrackSubAddress(RegionalMuonCand::kTrkNum, - (rawTrackAddress >> emtfTrAddrTrkNumShift_) & emtfTrAddrTrkNumMask_); - mu.setTrackSubAddress(RegionalMuonCand::kBX, (rawTrackAddress >> emtfTrAddrBxShift_) & emtfTrAddrBxMask_); if (useEmtfDisplacementInfo) { // In Run-3 we receive displaced muon information from EMTF mu.setHwPtUnconstrained((raw_data_32_63 >> emtfPtUnconstrainedShift_) & ptUnconstrainedMask_); mu.setHwDXY((raw_data_32_63 >> emtfDxyShift_) & dxyMask_); + mu.setTrackSubAddress(RegionalMuonCand::kTrkNum, 0); + mu.setTrackSubAddress(RegionalMuonCand::kBX, 0); + } else { + mu.setTrackSubAddress(RegionalMuonCand::kTrkNum, + (rawTrackAddress >> emtfTrAddrTrkNumShift_) & emtfTrAddrTrkNumMask_); + mu.setTrackSubAddress(RegionalMuonCand::kBX, (rawTrackAddress >> emtfTrAddrBxShift_) & emtfTrAddrBxMask_); } } else if (tf == omtf_neg || tf == omtf_pos) { mu.setTrackSubAddress(RegionalMuonCand::kLayers, @@ -114,6 +117,44 @@ void l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonCand(RegionalMuonCand& useEmtfDisplacementInfo); } +bool l1t::RegionalMuonRawDigiTranslator::fillRegionalMuonShower( + RegionalMuonShower& muShower, std::vector bxPayload, int proc, tftype tf, bool useEmtfShowers) { + if (useEmtfShowers && (tf == emtf_pos || tf == emtf_neg)) { + muShower.setTFIdentifiers(proc, tf); + + muShower.setOneNominalInTime(((bxPayload[emtfShowerInTimeFrame_] >> emtfShowerOneNominalShift_) & 1) == 1); + muShower.setOneNominalOutOfTime(((bxPayload[emtfShowerOOTFrame_] >> emtfShowerOneNominalShift_) & 1) == 1); + muShower.setOneTightInTime(((bxPayload[emtfShowerInTimeFrame_] >> emtfShowerOneTightShift_) & 1) == 1); + muShower.setOneTightOutOfTime(((bxPayload[emtfShowerOOTFrame_] >> emtfShowerOneTightShift_) & 1) == 1); + + return muShower.isValid(); + } else { + return false; + } +} + +void l1t::RegionalMuonRawDigiTranslator::generatePackedShowerPayload(const RegionalMuonShower& shower, + std::array& payload, + const bool useEmtfShowers) { + if (!useEmtfShowers || !shower.isValid()) { + return; + } + // First we check whether we're going to overwrite something in the payload. + if ((((payload.at(emtfShowerInTimeFrame_) >> emtfShowerOneNominalShift_) & emtfShowerMask_) != 0) || + (((payload.at(emtfShowerInTimeFrame_) >> emtfShowerOneTightShift_) & emtfShowerMask_) != 0) || + (((payload.at(emtfShowerOOTFrame_) >> emtfShowerOneNominalShift_) & emtfShowerMask_) != 0) || + (((payload.at(emtfShowerOOTFrame_) >> emtfShowerOneTightShift_) & emtfShowerMask_) != 0)) { + edm::LogError("L1T") << "Check constants for RegionalMuonShower fields! It looks like we're in danger of " + "overwriting muon data in the packer! InTimeFrame is " + << payload.at(emtfShowerInTimeFrame_) << ", OOTFrame is " << payload.at(emtfShowerOOTFrame_); + return; + } + payload.at(emtfShowerInTimeFrame_) |= (shower.isOneNominalInTime() & 1) << emtfShowerOneNominalShift_ | + (shower.isOneTightInTime() & 1) << emtfShowerOneTightShift_; + payload.at(emtfShowerOOTFrame_) |= (shower.isOneNominalOutOfTime() & 1) << emtfShowerOneNominalShift_ | + (shower.isOneTightOutOfTime() & 1) << emtfShowerOneTightShift_; +} + void l1t::RegionalMuonRawDigiTranslator::generatePackedDataWords(const RegionalMuonCand& mu, uint32_t& raw_data_00_31, uint32_t& raw_data_32_63, @@ -197,9 +238,7 @@ int l1t::RegionalMuonRawDigiTranslator::generateRawTrkAddress(const RegionalMuon (mu.trackSubAddress(RegionalMuonCand::kME3Seg) & 0x1) << emtfTrAddrMe3SegShift_ | (mu.trackSubAddress(RegionalMuonCand::kME3Ch) & emtfTrAddrMe3ChMask_) << emtfTrAddrMe3ChShift_ | (mu.trackSubAddress(RegionalMuonCand::kME4Seg) & 0x1) << emtfTrAddrMe4SegShift_ | - (mu.trackSubAddress(RegionalMuonCand::kME4Ch) & emtfTrAddrMe4ChMask_) << emtfTrAddrMe4ChShift_ | - (mu.trackSubAddress(RegionalMuonCand::kTrkNum) & emtfTrAddrTrkNumMask_) << emtfTrAddrTrkNumShift_ | - (mu.trackSubAddress(RegionalMuonCand::kBX) & emtfTrAddrBxMask_) << emtfTrAddrBxShift_; + (mu.trackSubAddress(RegionalMuonCand::kME4Ch) & emtfTrAddrMe4ChMask_) << emtfTrAddrMe4ChShift_; } else { edm::LogWarning("L1T") << "EMTF muon track address map contains " << mu.trackAddress().size() diff --git a/L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h b/L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h index f48f93ef154e0..bfe1c00688b34 100644 --- a/L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h +++ b/L1Trigger/L1TMuonEndCap/interface/SectorProcessorShower.h @@ -15,6 +15,8 @@ #include "DataFormats/CSCDigi/interface/CSCShowerDigiCollection.h" #include "L1Trigger/L1TMuonEndCap/interface/Common.h" +#include "DataFormats/L1TMuon/interface/RegionalMuonCandFwd.h" + #include class SectorProcessorShower { diff --git a/L1Trigger/L1TMuonEndCap/src/SectorProcessorShower.cc b/L1Trigger/L1TMuonEndCap/src/SectorProcessorShower.cc index f271cfea93549..671310fb30218 100644 --- a/L1Trigger/L1TMuonEndCap/src/SectorProcessorShower.cc +++ b/L1Trigger/L1TMuonEndCap/src/SectorProcessorShower.cc @@ -67,10 +67,8 @@ void SectorProcessorShower::process(const CSCShowerDigiCollection& in_showers, if (accept) { // shower output l1t::RegionalMuonShower out_shower(hasOneNominalInTime, false, hasTwoLooseInTime, false, hasOneTightInTime, false); - // convert [1,2] to [1, -1] - const int endcap(endcap_ == 1 ? 1 : -1); - out_shower.setEndcap(endcap); - out_shower.setSector(sector_); + l1t::tftype tftype = (endcap_ == 1) ? l1t::tftype::emtf_pos : l1t::tftype::emtf_neg; + out_shower.setTFIdentifiers(sector_, tftype); out_showers.push_back(0, out_shower); } }