diff --git a/DQM/HLTEvF/plugins/ScoutingCollectionMonitor.cc b/DQM/HLTEvF/plugins/ScoutingCollectionMonitor.cc index 3631dbf528652..3c6fe3951a401 100644 --- a/DQM/HLTEvF/plugins/ScoutingCollectionMonitor.cc +++ b/DQM/HLTEvF/plugins/ScoutingCollectionMonitor.cc @@ -24,11 +24,17 @@ It is based on the preexisting work of the scouting group and can be found at gi // user include files #include "DQMServices/Core/interface/DQMEDAnalyzer.h" +#include "DataFormats/EcalDetId/interface/EBDetId.h" +#include "DataFormats/EcalDetId/interface/EEDetId.h" +#include "DataFormats/HcalDetId/interface/HcalDetId.h" #include "DataFormats/L1TGlobal/interface/GlobalAlgBlk.h" #include "DataFormats/OnlineMetaData/interface/OnlineLuminosityRecord.h" #include "DataFormats/PatCandidates/interface/PackedTriggerPrescales.h" #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h" +#include "DataFormats/Scouting/interface/Run3ScoutingEBRecHit.h" +#include "DataFormats/Scouting/interface/Run3ScoutingEERecHit.h" #include "DataFormats/Scouting/interface/Run3ScoutingElectron.h" +#include "DataFormats/Scouting/interface/Run3ScoutingHBHERecHit.h" #include "DataFormats/Scouting/interface/Run3ScoutingMuon.h" #include "DataFormats/Scouting/interface/Run3ScoutingPFJet.h" #include "DataFormats/Scouting/interface/Run3ScoutingParticle.h" @@ -62,6 +68,14 @@ class ScoutingCollectionMonitor : public DQMEDAnalyzer { void analyze(const edm::Event&, const edm::EventSetup&) override; void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override; + template + void setToken(edm::EDGetTokenT& token, const edm::ParameterSet& iConfig, std::string name) { + const auto inputTag = iConfig.getParameter(name); + if (!inputTag.encode().empty()) { + token = consumes(inputTag); + } + } + template bool getValidHandle(const edm::Event& iEvent, const edm::EDGetTokenT& token, @@ -105,6 +119,13 @@ class ScoutingCollectionMonitor : public DQMEDAnalyzer { const edm::EDGetTokenT onlineMetaDataDigisToken_; const std::string topfoldername_; + // calo rechits (only 2025 V1.3 onwards, see https://its.cern.ch/jira/browse/CMSHLT-3607) + edm::EDGetTokenT ebRecHitsToken_; + edm::EDGetTokenT eeRecHitsToken_; + edm::EDGetTokenT ebCleanedRecHitsToken_; + edm::EDGetTokenT eeCleanedRecHitsToken_; + edm::EDGetTokenT hbheRecHitsToken_; + // pv vs PU and rho vs PU plots int primaryVertex_counter = 0; float avgPileUp; @@ -384,6 +405,22 @@ class ScoutingCollectionMonitor : public DQMEDAnalyzer { dqm::reco::MonitorElement* tk_chi2_prob_hist; dqm::reco::MonitorElement* tk_PV_dxy_hist; dqm::reco::MonitorElement* tk_PV_dz_hist; + + // calo rechits histrograms (ECAL has two version, cleaned and unclean) + dqm::reco::MonitorElement* ebRecHitsNumber_hist[2]; + dqm::reco::MonitorElement* ebRecHits_energy_hist[2]; + dqm::reco::MonitorElement* ebRecHits_time_hist[2]; + dqm::reco::MonitorElement* ebRecHitsEtaPhiMap[2]; + dqm::reco::MonitorElement* eeRecHitsNumber_hist[2]; + dqm::reco::MonitorElement* eeRecHits_energy_hist[2]; + dqm::reco::MonitorElement* eeRecHits_time_hist[2]; + dqm::reco::MonitorElement* eePlusRecHitsXYMap[2]; + dqm::reco::MonitorElement* eeMinusRecHitsXYMap[2]; + dqm::reco::MonitorElement* hbheRecHitsNumber_hist; + dqm::reco::MonitorElement* hbheRecHits_energy_hist; + dqm::reco::MonitorElement* hbheRecHitsEtaPhiMap; + dqm::reco::MonitorElement* hbRecHitsEtaPhiMap; + dqm::reco::MonitorElement* heRecHitsEtaPhiMap; }; // @@ -408,7 +445,13 @@ ScoutingCollectionMonitor::ScoutingCollectionMonitor(const edm::ParameterSet& iC pfjetsToken_(consumes>(iConfig.getParameter("pfjets"))), tracksToken_(consumes>(iConfig.getParameter("tracks"))), onlineMetaDataDigisToken_(consumes(iConfig.getParameter("onlineMetaDataDigis"))), - topfoldername_(iConfig.getParameter("topfoldername")) {} + topfoldername_(iConfig.getParameter("topfoldername")) { + setToken(ebRecHitsToken_, iConfig, "pfRecHitsEB"); + setToken(eeRecHitsToken_, iConfig, "pfRecHitsEE"); + setToken(ebCleanedRecHitsToken_, iConfig, "pfCleanedRecHitsEB"); + setToken(eeCleanedRecHitsToken_, iConfig, "pfCleanedRecHitsEE"); + setToken(hbheRecHitsToken_, iConfig, "pfRecHitsHBHE"); +} // // member functions @@ -797,6 +840,100 @@ void ScoutingCollectionMonitor::analyze(const edm::Event& iEvent, const edm::Eve tk_PV_dxy_hist->Fill(best_offset.first); tk_PV_dz_hist->Fill(best_offset.second); } + + // Define helper lambdas for EB and EE rechits + auto fillEBHistograms = [](const auto& rechits, + int index, + dqm::reco::MonitorElement* numberHist[2], + dqm::reco::MonitorElement* etaPhiMap[2], + dqm::reco::MonitorElement* energyHist[2], + dqm::reco::MonitorElement* timeHist[2]) { + numberHist[index]->Fill(rechits.size()); + for (const auto& hit : rechits) { + EBDetId id(hit.detId()); + etaPhiMap[index]->Fill(id.ieta(), id.iphi()); + energyHist[index]->Fill(hit.energy()); + timeHist[index]->Fill(hit.time()); + } + }; + + auto fillEEHistograms = [](const auto& rechits, + int index, + dqm::reco::MonitorElement* numberHist[2], + dqm::reco::MonitorElement* plusXYMap[2], + dqm::reco::MonitorElement* minusXYMap[2], + dqm::reco::MonitorElement* energyHist[2], + dqm::reco::MonitorElement* timeHist[2]) { + numberHist[index]->Fill(rechits.size()); + for (const auto& hit : rechits) { + EEDetId id(hit.detId()); + if (id.zside() > 0) { + plusXYMap[index]->Fill(id.ix(), id.iy()); + } else { + minusXYMap[index]->Fill(id.ix(), id.iy()); + } + energyHist[index]->Fill(hit.energy()); + timeHist[index]->Fill(hit.time()); + } + }; + + // Process uncleaned EB rechits + edm::Handle ebRecHitsH; + if (!ebRecHitsToken_.isUninitialized() && getValidHandle(iEvent, ebRecHitsToken_, ebRecHitsH, "pfRecHitsEB")) { + fillEBHistograms( + *ebRecHitsH, 0, ebRecHitsNumber_hist, ebRecHitsEtaPhiMap, ebRecHits_energy_hist, ebRecHits_time_hist); + } + + // Process uncleaned EE rechits + edm::Handle eeRecHitsH; + if (!eeRecHitsToken_.isUninitialized() && getValidHandle(iEvent, eeRecHitsToken_, eeRecHitsH, "pfRecHitsEE")) { + fillEEHistograms(*eeRecHitsH, + 0, + eeRecHitsNumber_hist, + eePlusRecHitsXYMap, + eeMinusRecHitsXYMap, + eeRecHits_energy_hist, + eeRecHits_time_hist); + } + + // Process cleaned EB rechits + edm::Handle ebRecHitsCleanedH; + if (!ebCleanedRecHitsToken_.isUninitialized() && + getValidHandle(iEvent, ebCleanedRecHitsToken_, ebRecHitsCleanedH, "pfCleanedRecHitsEB")) { + fillEBHistograms( + *ebRecHitsCleanedH, 1, ebRecHitsNumber_hist, ebRecHitsEtaPhiMap, ebRecHits_energy_hist, ebRecHits_time_hist); + } + + // Process cleaned EE rechits + edm::Handle eeRecHitsCleanedH; + if (!eeCleanedRecHitsToken_.isUninitialized() && + getValidHandle(iEvent, eeCleanedRecHitsToken_, eeRecHitsCleanedH, "pfCleanedRecHitsEE")) { + fillEEHistograms(*eeRecHitsCleanedH, + 1, + eeRecHitsNumber_hist, + eePlusRecHitsXYMap, + eeMinusRecHitsXYMap, + eeRecHits_energy_hist, + eeRecHits_time_hist); + } + + // process the HBHE rechits + edm::Handle hbheRecHitsH; + if (!hbheRecHitsToken_.isUninitialized() && + getValidHandle(iEvent, hbheRecHitsToken_, hbheRecHitsH, "pfRecHitsHBHE")) { + hbheRecHitsNumber_hist->Fill(hbheRecHitsH->size()); + for (const auto& hbheRecHit : *hbheRecHitsH) { + hbheRecHits_energy_hist->Fill(hbheRecHit.energy()); + HcalDetId hcalid(hbheRecHit.detId()); + hbheRecHitsEtaPhiMap->Fill(hcalid.ieta(), hcalid.iphi()); + const auto& subdet = hcalid.subdetId(); + if (subdet == 1) { // HB + hbRecHitsEtaPhiMap->Fill(hcalid.ieta(), hcalid.iphi()); + } else { // HE + heRecHitsEtaPhiMap->Fill(hcalid.ieta(), hcalid.iphi()); + } + } + } } // ------------ method called once each job just before starting event loop ------------ @@ -1203,6 +1340,93 @@ void ScoutingCollectionMonitor::bookHistograms(DQMStore::IBooker& ibook, tk_chi2_prob_hist = ibook.book1DD("tk_chi2_prob_hist", "p(#chi^{2}, NDOF); p(#chi^{2}, NDOF); Entries", 100, 0, 1); tk_PV_dz_hist = ibook.book1DD("tk_PV_dz", "Track dz w.r.t. PV; Track dz w.r.t. PV; Entries", 100, -0.35, 0.35); tk_PV_dxy_hist = ibook.book1DD("tk_PV_dxy", "Track dxy w.r.t. PV; Track dxy w.r.t. PV; Entries", 100, -0.15, 0.15); + + // book the calo rechits histograms + const std::array caloLabels = {{"All", "Cleaned"}}; + const std::array caloSuffixes = {{"", "_clean"}}; + for (int i = 0; i < 2; ++i) { + ibook.setCurrentFolder(topfoldername_ + "/CaloRecHits" + caloLabels[i]); + + const std::string& lbl = caloLabels[i]; + const std::string& sfx = caloSuffixes[i]; + + ebRecHitsNumber_hist[i] = ibook.book1D( + "ebRechitsN" + sfx, "Number of EB RecHits (" + lbl + "); number of EB recHits; Entries", 100, 0.0, 1000.0); + + ebRecHits_energy_hist[i] = + ibook.book1D("ebRechits_energy" + sfx, + "Energy spectrum of EB RecHits (" + lbl + "); Energy of EB recHits (Gev); Entries", + 100, + 0.0, + 500.0); + + ebRecHits_time_hist[i] = ibook.book1D("ebRechits_time" + sfx, + "Time of EB RecHits (" + lbl + "); Energy of EB recHits (ps); Entries", + 100, + 0.0, + 1000.0); + eeRecHitsNumber_hist[i] = ibook.book1D( + "eeRechitsN" + sfx, "Number of EE RecHits (" + lbl + "); number of EE recHits; Entries", 100, 0.0, 1000.0); + eeRecHits_energy_hist[i] = + ibook.book1D("eeRechits_energy" + sfx, + "Energy spectrum of EE RecHits (" + lbl + "); Energy of EE recHits (GeV); Entries", + 100, + 0.0, + 1000.0); + eeRecHits_time_hist[i] = ibook.book1D( + "eeRechits_time" + sfx, "Time of EE RecHits (" + lbl + "); Time of EE recHits (ps); Entries", 100, 0.0, 1000.0); + + ebRecHitsEtaPhiMap[i] = ibook.book2D("ebRecHitsEtaPhitMap" + sfx, + "Occupancy map of EB rechits (" + lbl + ");ieta;iphi;Entries", + 171, + -85.5, + 85.5, + 361, + 0., + 361); + + ebRecHitsEtaPhiMap[i]->setOption("colz"); + + eePlusRecHitsXYMap[i] = ibook.book2D("eePlusRecHitsEtaPhitMap" + sfx, + "Occupancy map of EE+ rechits (" + lbl + ");ix;iy;Entries", + 100, + 1, + 101, + 100, + 1, + 101); + + eePlusRecHitsXYMap[i]->setOption("colz"); + + eeMinusRecHitsXYMap[i] = ibook.book2D("eeMinusRecHitsEtaPhitMap" + sfx, + "Occupancy map of EE- rechits (" + lbl + ");ix;iy;Entries", + 100, + 1, + 101, + 100, + 1, + 101); + + eeMinusRecHitsXYMap[i]->setOption("colz"); + } + + ibook.setCurrentFolder(topfoldername_ + "/CaloRecHitsAll"); + hbheRecHitsNumber_hist = + ibook.book1D("hbheRechitsN", "number of hbhe RecHits; Number of HBHE recHits; Entries", 100, 0.0, 2000.0); + hbheRecHits_energy_hist = ibook.book1D( + "hbheRechits_energy", "Energy spectrum of hbhe RecHits; Energy of HBHE recHits (GeV); Entries", 100, 0.0, 200.0); + + hbheRecHitsEtaPhiMap = ibook.book2D( + "hbheRecHitsEtaPhitMap", "Occupancy map of HBHE rechits;ieta;iphi;Entries", 61, -30.5, 30.5, 74, -0.5, 73.5); + hbheRecHitsEtaPhiMap->setOption("colz"); + + hbRecHitsEtaPhiMap = ibook.book2D( + "hbRecHitsEtaPhitMap", "Occupancy map of HB rechits;ieta;iphi;Entries", 83, -41.5, 41.5, 72, 0.5, 72.5); + hbRecHitsEtaPhiMap->setOption("colz"); + + heRecHitsEtaPhiMap = ibook.book2D( + "heRecHitsEtaPhitMap", "Occupancy map of HE rechits;ieta;iphi;Entries", 83, -41.5, 41.5, 72, 0.5, 72.5); + heRecHitsEtaPhiMap->setOption("colz"); } // ------------ method fills 'descriptions' with the allowed parameters for the module ------------ @@ -1223,6 +1447,11 @@ void ScoutingCollectionMonitor::fillDescriptions(edm::ConfigurationDescriptions& desc.add("pfMetPhi", edm::InputTag("hltScoutingPFPacker", "pfMetPhi")); desc.add("rho", edm::InputTag("hltScoutingPFPacker", "rho")); desc.add("onlineMetaDataDigis", edm::InputTag("onlineMetaDataDigis")); + desc.add("pfRecHitsEB", edm::InputTag("hltScoutingRecHitPacker", "EB")); + desc.add("pfRecHitsEE", edm::InputTag("hltScoutingRecHitPacker", "EE")); + desc.add("pfRecHitsHBHE", edm::InputTag("hltScoutingRecHitPacker", "HBHE")); + desc.add("pfCleanedRecHitsEB", edm::InputTag("hltScoutingRecHitPacker", "EBCleaned")); + desc.add("pfCleanedRecHitsEE", edm::InputTag("hltScoutingRecHitPacker", "EECleaned")); desc.add("topfoldername", "HLT/ScoutingOffline/Miscellaneous"); descriptions.addWithDefaultLabel(desc); } diff --git a/DQM/HLTEvF/python/ScoutingCollectionMonitor_cfi.py b/DQM/HLTEvF/python/ScoutingCollectionMonitor_cfi.py index c7b579853c069..24dfc2750d762 100644 --- a/DQM/HLTEvF/python/ScoutingCollectionMonitor_cfi.py +++ b/DQM/HLTEvF/python/ScoutingCollectionMonitor_cfi.py @@ -2,7 +2,8 @@ from DQMServices.Core.DQMEDAnalyzer import DQMEDAnalyzer scoutingCollectionMonitor = DQMEDAnalyzer('ScoutingCollectionMonitor', - onlyScouting = cms.bool(False), + topfoldername = cms.string("HLT/ScoutingOffline/Miscellaneous"), + onlyScouting = cms.bool(False), onlineMetaDataDigis = cms.InputTag("onlineMetaDataDigis"), muons = cms.InputTag("hltScoutingMuonPackerNoVtx"), muonsVtx = cms.InputTag("hltScoutingMuonPackerVtx"), @@ -17,6 +18,9 @@ pfMetPt = cms.InputTag("hltScoutingPFPacker","pfMetPt"), pfMetPhi = cms.InputTag("hltScoutingPFPacker","pfMetPhi"), rho = cms.InputTag("hltScoutingPFPacker","rho"), - topfoldername = cms.string("HLT/ScoutingOffline/Miscellaneous") - ) + pfRecHitsEB = cms.InputTag("hltScoutingRecHitPacker", "EB"), + pfRecHitsEE = cms.InputTag("hltScoutingRecHitPacker", "EE"), + pfCleanedRecHitsEB = cms.InputTag("hltScoutingRecHitPacker", "EBCleaned"), + pfCleanedRecHitsEE = cms.InputTag("hltScoutingRecHitPacker", "EECleaned"), + pfRecHitsHBHE = cms.InputTag("hltScoutingRecHitPacker", "HBHE"))