Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-03-02 23:54:09

0001 /*
0002   Scouting Muon DQM for L1 seeds. 
0003   This code does the following:
0004 
0005      1) Reads pat muon and scouting muon collections, and writes an array of
0006 scouting muon triggers (selected in python/ScoutingMuonTriggerAnalyzer_cfi.py)
0007 
0008      2) For each event, if the event passes a logical OR of HLTriggers it is added
0009      to the denominator, and if it passes any of the scouting muon triggers it is
0010      added to the numerator of that specific trigger.
0011 
0012      3) Fills histograms for both leading and subleading muon in the event.
0013   
0014   Author: Javier Garcia de Castro, email:javigdc@bu.edu
0015 */
0016 
0017 // system includes
0018 #include <cmath>
0019 #include <iostream>
0020 #include <string>
0021 #include <vector>
0022 
0023 // user includes
0024 #include "DQMServices/Core/interface/DQMEDAnalyzer.h"
0025 #include "DQMServices/Core/interface/DQMGlobalEDAnalyzer.h"
0026 #include "DataFormats/Common/interface/TriggerResults.h"
0027 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
0028 #include "DataFormats/L1TGlobal/interface/GlobalAlgBlk.h"
0029 #include "DataFormats/PatCandidates/interface/Muon.h"
0030 #include "DataFormats/Scouting/interface/Run3ScoutingMuon.h"
0031 #include "DataFormats/Scouting/interface/Run3ScoutingVertex.h"
0032 #include "FWCore/Common/interface/TriggerNames.h"
0033 #include "FWCore/Framework/interface/ConsumesCollector.h"
0034 #include "FWCore/Framework/interface/Event.h"
0035 #include "FWCore/Framework/interface/Frameworkfwd.h"
0036 #include "FWCore/Framework/interface/MakerMacros.h"
0037 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0038 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0039 #include "HLTrigger/HLTcore/interface/TriggerExpressionData.h"
0040 #include "HLTrigger/HLTcore/interface/TriggerExpressionEvaluator.h"
0041 #include "HLTrigger/HLTcore/interface/TriggerExpressionParser.h"
0042 #include "L1Trigger/L1TGlobal/interface/L1TGlobalUtil.h"
0043 
0044 // Classes to be declared
0045 class ScoutingMuonTriggerAnalyzer : public DQMEDAnalyzer {
0046 public:
0047   explicit ScoutingMuonTriggerAnalyzer(const edm::ParameterSet& conf);
0048   ~ScoutingMuonTriggerAnalyzer() override = default;
0049   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0050 
0051 private:
0052   void analyze(const edm::Event& e, const edm::EventSetup& c) override;
0053   void bookHistograms(DQMStore::IBooker&, edm::Run const&, edm::EventSetup const&) override;
0054 
0055   // data members
0056   const std::string outputInternalPath_;
0057   triggerExpression::Data triggerCache_;
0058   const std::vector<std::string> vtriggerSelection_;
0059 
0060   const edm::EDGetTokenT<std::vector<pat::Muon>> muonCollection_;
0061   const edm::EDGetTokenT<std::vector<Run3ScoutingMuon>> scoutingMuonCollection_;
0062 
0063   std::vector<triggerExpression::Evaluator*> vtriggerSelector_;
0064   edm::EDGetToken algToken_;
0065   std::shared_ptr<l1t::L1TGlobalUtil> l1GtUtils_;
0066   std::vector<std::string> l1Seeds_;
0067   TString l1Names[100] = {""};
0068   Bool_t l1Result[100] = {false};
0069 
0070   // Histogram declaration
0071   // DENOMINATORS:
0072   dqm::reco::MonitorElement* h_invMass_denominator;
0073   dqm::reco::MonitorElement* h_pt1_l1_denominator;
0074   dqm::reco::MonitorElement* h_eta1_l1_denominator;
0075   dqm::reco::MonitorElement* h_phi1_l1_denominator;
0076   dqm::reco::MonitorElement* h_dxy1_l1_denominator;
0077   dqm::reco::MonitorElement* h_pt2_l1_denominator;
0078   dqm::reco::MonitorElement* h_eta2_l1_denominator;
0079   dqm::reco::MonitorElement* h_phi2_l1_denominator;
0080   dqm::reco::MonitorElement* h_dxy2_l1_denominator;
0081 
0082   // NUMERATORS:
0083   std::vector<dqm::reco::MonitorElement*> h_invMass_numerators;
0084   std::vector<dqm::reco::MonitorElement*> h_pt1_l1_numerators;
0085   std::vector<dqm::reco::MonitorElement*> h_eta1_l1_numerators;
0086   std::vector<dqm::reco::MonitorElement*> h_phi1_l1_numerators;
0087   std::vector<dqm::reco::MonitorElement*> h_dxy1_l1_numerators;
0088   std::vector<dqm::reco::MonitorElement*> h_pt2_l1_numerators;
0089   std::vector<dqm::reco::MonitorElement*> h_eta2_l1_numerators;
0090   std::vector<dqm::reco::MonitorElement*> h_phi2_l1_numerators;
0091   std::vector<dqm::reco::MonitorElement*> h_dxy2_l1_numerators;
0092 };
0093 
0094 // Read the collections and triggers
0095 ScoutingMuonTriggerAnalyzer::ScoutingMuonTriggerAnalyzer(const edm::ParameterSet& iConfig)
0096     : outputInternalPath_{iConfig.getParameter<std::string>("OutputInternalPath")},
0097       triggerCache_{triggerExpression::Data(iConfig.getParameterSet("triggerConfiguration"), consumesCollector())},
0098       vtriggerSelection_{iConfig.getParameter<vector<string>>("triggerSelection")},
0099       scoutingMuonCollection_{
0100           consumes<std::vector<Run3ScoutingMuon>>(iConfig.getParameter<edm::InputTag>("ScoutingMuonCollection"))},
0101       algToken_{consumes<BXVector<GlobalAlgBlk>>(iConfig.getParameter<edm::InputTag>("AlgInputTag"))} {
0102   vtriggerSelector_.reserve(vtriggerSelection_.size());
0103   for (auto const& vt : vtriggerSelection_)
0104     vtriggerSelector_.push_back(triggerExpression::parse(vt));
0105   l1GtUtils_ = std::make_shared<l1t::L1TGlobalUtil>(iConfig, consumesCollector(), l1t::UseEventSetupIn::RunAndEvent);
0106   l1Seeds_ = iConfig.getParameter<std::vector<std::string>>("l1Seeds");
0107   for (unsigned int i = 0; i < l1Seeds_.size(); i++) {
0108     const auto& l1seed(l1Seeds_.at(i));
0109     l1Names[i] = TString(l1seed);
0110   }
0111 }
0112 
0113 // Core of the implementation
0114 void ScoutingMuonTriggerAnalyzer::analyze(edm::Event const& iEvent, edm::EventSetup const& iSetup) {
0115   edm::Handle<std::vector<Run3ScoutingMuon>> sctMuons;
0116   iEvent.getByToken(scoutingMuonCollection_, sctMuons);
0117   if (sctMuons.failedToGet()) {
0118     edm::LogWarning("ScoutingMonitoring") << "Run3ScoutingMuon collection not found.";
0119     return;
0120   }
0121 
0122   // Check whether events pass any of the HLTriggers to add to the denominator
0123   bool passHLTDenominator = false;
0124   if (triggerCache_.setEvent(iEvent, iSetup)) {
0125     for (unsigned int i = 0; i < vtriggerSelector_.size(); i++) {
0126       auto& vts(vtriggerSelector_.at(i));
0127       bool result = false;
0128       if (vts) {
0129         if (triggerCache_.configurationUpdated())
0130           vts->init(triggerCache_);
0131         result = (*vts)(triggerCache_);
0132       }
0133       if (result)
0134         passHLTDenominator = true;
0135     }
0136   }
0137 
0138   // Find leading and subleading muon from the event
0139   if (!sctMuons->empty()) {
0140     Run3ScoutingMuon leading_mu;
0141     Run3ScoutingMuon subleading_mu;
0142 
0143     std::vector<Run3ScoutingMuon> sorted_mu;
0144     for (const auto& muon : *sctMuons) {
0145       sorted_mu.push_back(muon);
0146     }
0147     std::sort(std::begin(sorted_mu), std::end(sorted_mu), [&](Run3ScoutingMuon mu1, Run3ScoutingMuon mu2) {
0148       return mu1.pt() > mu2.pt();
0149     });
0150     leading_mu = sorted_mu.at(0);
0151     if (sorted_mu.size() > 1)
0152       subleading_mu = sorted_mu.at(1);
0153 
0154     l1GtUtils_->retrieveL1(iEvent, iSetup, algToken_);
0155 
0156     math::PtEtaPhiMLorentzVector mu1(leading_mu.pt(), leading_mu.eta(), leading_mu.phi(), leading_mu.m());
0157     math::PtEtaPhiMLorentzVector mu2(subleading_mu.pt(), subleading_mu.eta(), subleading_mu.phi(), subleading_mu.m());
0158     float invMass = (mu1 + mu2).mass();
0159     // If event passed and of the HLTs, add to denominator
0160     if (passHLTDenominator) {
0161       h_invMass_denominator->Fill(invMass);
0162       h_pt1_l1_denominator->Fill(leading_mu.pt());
0163       h_eta1_l1_denominator->Fill(leading_mu.eta());
0164       h_phi1_l1_denominator->Fill(leading_mu.phi());
0165       h_dxy1_l1_denominator->Fill(leading_mu.trk_dxy());
0166       if (sorted_mu.size() > 1) {
0167         h_pt2_l1_denominator->Fill(subleading_mu.pt());
0168         h_eta2_l1_denominator->Fill(subleading_mu.eta());
0169         h_phi2_l1_denominator->Fill(subleading_mu.phi());
0170         h_dxy2_l1_denominator->Fill(subleading_mu.trk_dxy());
0171       }
0172 
0173       // For each L1 seed, if the event passes the trigger plot distributions in
0174       // the numerator
0175       for (unsigned int i = 0; i < l1Seeds_.size(); i++) {
0176         const auto& l1seed(l1Seeds_.at(i));
0177         bool l1htbit = false;
0178         double prescale = -1;
0179         l1GtUtils_->getFinalDecisionByName(l1seed, l1htbit);
0180         l1GtUtils_->getPrescaleByName(l1seed, prescale);
0181         l1Result[i] = l1htbit;
0182         if (l1Result[i] == 1) {
0183           h_invMass_numerators[i]->Fill(invMass);
0184           h_pt1_l1_numerators[i]->Fill(leading_mu.pt());
0185           h_eta1_l1_numerators[i]->Fill(leading_mu.eta());
0186           h_phi1_l1_numerators[i]->Fill(leading_mu.phi());
0187           h_dxy1_l1_numerators[i]->Fill(leading_mu.trk_dxy());
0188           if (sorted_mu.size() > 1) {
0189             h_pt2_l1_numerators[i]->Fill(subleading_mu.pt());
0190             h_eta2_l1_numerators[i]->Fill(subleading_mu.eta());
0191             h_phi2_l1_numerators[i]->Fill(subleading_mu.phi());
0192             h_dxy2_l1_numerators[i]->Fill(subleading_mu.trk_dxy());
0193           }
0194         }
0195       }
0196     }
0197   }
0198 }
0199 
0200 // Histogram axes labels, bin number and range
0201 void ScoutingMuonTriggerAnalyzer::bookHistograms(DQMStore::IBooker& ibook,
0202                                                  edm::Run const& run,
0203                                                  edm::EventSetup const& iSetup) {
0204   ibook.setCurrentFolder(outputInternalPath_);
0205   h_invMass_denominator = ibook.book1D("h_invMass_denominator", ";Invariant Mass (GeV); Muons", 100, 0.0, 20.0);
0206   h_pt1_l1_denominator = ibook.book1D("h_pt1_denominator", ";Leading muon pt (GeV); Muons", 100, 0, 50.0);
0207   h_eta1_l1_denominator = ibook.book1D("h_eta1_denominator", ";Leading muon eta; Muons", 100, -5.0, 5.0);
0208   h_phi1_l1_denominator = ibook.book1D("h_phi1_denominator", ";Leading muon phi; Muons", 100, -3.3, 3.3);
0209   h_dxy1_l1_denominator = ibook.book1D("h_dxy1_denominator", ";Leading muon dxy; Muons", 100, 0, 5.0);
0210   h_pt2_l1_denominator = ibook.book1D("h_pt2_denominator", ";Subleading muon pt (GeV); Muons", 100, 0, 50.0);
0211   h_eta2_l1_denominator = ibook.book1D("h_eta2_denominator", ";Subleading muon eta; Muons", 100, -5.0, 5.0);
0212   h_phi2_l1_denominator = ibook.book1D("h_phi2_denominator", ";Subleading muon phi; Muons", 100, -3.3, 3.3);
0213   h_dxy2_l1_denominator = ibook.book1D("h_dxy2_denominator", ";Subleaing muon dxy; Muons", 100, 0, 5.0);
0214 
0215   for (unsigned int i = 0; i < l1Seeds_.size(); i++) {
0216     const auto& l1seed = l1Seeds_.at(i);
0217     h_invMass_numerators.push_back(
0218         ibook.book1D(Form("h_invMass_numerator_%s", l1seed.c_str()), ";Invariant mass (GeV); Muons", 100, 0.0, 20.0));
0219     h_pt1_l1_numerators.push_back(
0220         ibook.book1D(Form("h_pt1_numerator_%s", l1seed.c_str()), ";Leading muon pt (GeV); Muons", 100, 0, 50.0));
0221     h_eta1_l1_numerators.push_back(
0222         ibook.book1D(Form("h_eta1_numerator_%s", l1seed.c_str()), ";Leading muon eta; Muons", 100, -5.0, 5.0));
0223     h_phi1_l1_numerators.push_back(
0224         ibook.book1D(Form("h_phi1_numerator_%s", l1seed.c_str()), ";Leading muon phi; Muons", 100, 3.3, -3.3));
0225     h_dxy1_l1_numerators.push_back(
0226         ibook.book1D(Form("h_dxy1_numerator_%s", l1seed.c_str()), ";Leading muon dxy; Muons", 100, 0, 5.0));
0227     h_pt2_l1_numerators.push_back(
0228         ibook.book1D(Form("h_pt2_numerator_%s", l1seed.c_str()), ";Subleading muon pt (GeV); Muons", 100, 0, 50.0));
0229     h_eta2_l1_numerators.push_back(
0230         ibook.book1D(Form("h_eta2_numerator_%s", l1seed.c_str()), ";Subleading muon eta; Muons", 100, -5.0, 5.0));
0231     h_phi2_l1_numerators.push_back(
0232         ibook.book1D(Form("h_phi2_numerator_%s", l1seed.c_str()), ";Subleading muon phi; Muons", 100, 3.3, -3.3));
0233     h_dxy2_l1_numerators.push_back(
0234         ibook.book1D(Form("h_dxy2_numerator_%s", l1seed.c_str()), ";Subleading muon dxy; Muons", 100, 0, 5.0));
0235   }
0236 }
0237 
0238 // Input tags to read collections and L1 seeds
0239 void ScoutingMuonTriggerAnalyzer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0240   edm::ParameterSetDescription desc;
0241 
0242   desc.add<std::string>("OutputInternalPath", "MY_FOLDER");
0243   desc.add<vector<string>>("triggerSelection", {});
0244   desc.add<edm::InputTag>("ScoutingMuonCollection", edm::InputTag("hltScoutingMuonPackerVtx"));
0245   desc.add<edm::InputTag>("AlgInputTag", edm::InputTag("gtStage2Digis"));
0246   desc.add<std::vector<std::string>>("l1Seeds", {});
0247   desc.add<edm::InputTag>("l1tAlgBlkInputTag", edm::InputTag("gtStage2Digis"));
0248   desc.add<edm::InputTag>("l1tExtBlkInputTag", edm::InputTag("gtStage2Digis"));
0249   desc.add<bool>("ReadPrescalesFromFile", false);
0250   edm::ParameterSetDescription triggerConfig;
0251   triggerConfig.setAllowAnything();
0252   desc.add<edm::ParameterSetDescription>("triggerConfiguration", triggerConfig);
0253   descriptions.addWithDefaultLabel(desc);
0254 }
0255 
0256 DEFINE_FWK_MODULE(ScoutingMuonTriggerAnalyzer);