Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:18:37

0001 /** \class HLTMuonL2PreFilter
0002  *
0003  * See header file for documentation
0004  *
0005  *  \author J. Alcaraz
0006  *
0007  */
0008 
0009 #include "HLTMuonL2PreFilter.h"
0010 #include "HLTMuonL2ToL1Map.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "DataFormats/Common/interface/Handle.h"
0013 #include "DataFormats/Common/interface/RefToBase.h"
0014 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
0015 #include "DataFormats/TrackReco/interface/Track.h"
0016 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
0017 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
0018 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0019 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0021 #include "FWCore/Utilities/interface/InputTag.h"
0022 
0023 //
0024 // constructors and destructor
0025 //
0026 
0027 HLTMuonL2PreFilter::HLTMuonL2PreFilter(const edm::ParameterSet& iConfig)
0028     : HLTFilter(iConfig),
0029       beamSpotTag_(iConfig.getParameter<edm::InputTag>("BeamSpotTag")),
0030       beamSpotToken_(consumes<reco::BeamSpot>(beamSpotTag_)),
0031       candTag_(iConfig.getParameter<edm::InputTag>("CandTag")),
0032       candToken_(consumes<reco::RecoChargedCandidateCollection>(candTag_)),
0033       previousCandTag_(iConfig.getParameter<edm::InputTag>("PreviousCandTag")),
0034       previousCandToken_(consumes<trigger::TriggerFilterObjectWithRefs>(previousCandTag_)),
0035       seedMapTag_(iConfig.getParameter<edm::InputTag>("SeedMapTag")),
0036       seedMapToken_(consumes<SeedMap>(seedMapTag_)),
0037       minN_(iConfig.getParameter<int>("MinN")),
0038       maxEta_(iConfig.getParameter<double>("MaxEta")),
0039       absetaBins_(iConfig.getParameter<std::vector<double> >("AbsEtaBins")),
0040       minNstations_(iConfig.getParameter<std::vector<int> >("MinNstations")),
0041       minNhits_(iConfig.getParameter<std::vector<int> >("MinNhits")),
0042       cutOnChambers_(iConfig.getParameter<bool>("CutOnChambers")),
0043       minNchambers_(iConfig.getParameter<std::vector<int> >("MinNchambers")),
0044       maxDr_(iConfig.getParameter<double>("MaxDr")),
0045       minDr_(iConfig.getParameter<double>("MinDr")),
0046       maxDz_(iConfig.getParameter<double>("MaxDz")),
0047       min_DxySig_(iConfig.getParameter<double>("MinDxySig")),
0048       minPt_(iConfig.getParameter<double>("MinPt")),
0049       nSigmaPt_(iConfig.getParameter<double>("NSigmaPt")) {
0050   using namespace std;
0051 
0052   // check that number of eta bins matches number of nStation cuts
0053   if (minNstations_.size() != absetaBins_.size() || minNhits_.size() != absetaBins_.size() ||
0054       (cutOnChambers_ && minNchambers_.size() != absetaBins_.size())) {
0055     throw cms::Exception("Configuration") << "Number of MinNstations, MinNhits, or MinNchambers cuts "
0056                                           << "does not match number of eta bins." << endl;
0057   }
0058 
0059   if (absetaBins_.size() > 1) {
0060     for (unsigned int i = 0; i < absetaBins_.size() - 1; ++i) {
0061       if (absetaBins_[i + 1] <= absetaBins_[i])
0062         throw cms::Exception("Configuration") << "Absolute eta bins must be in increasing order." << endl;
0063     }
0064   }
0065 
0066   // dump parameters for debugging
0067   if (edm::isDebugEnabled()) {
0068     ostringstream ss;
0069     ss << "Constructed with parameters:" << endl;
0070     ss << "    BeamSpotTag = " << beamSpotTag_.encode() << endl;
0071     ss << "    CandTag = " << candTag_.encode() << endl;
0072     ss << "    PreviousCandTag = " << previousCandTag_.encode() << endl;
0073     ss << "    SeedMapTag = " << seedMapTag_.encode() << endl;
0074     ss << "    MinN = " << minN_ << endl;
0075     ss << "    MaxEta = " << maxEta_ << endl;
0076     ss << "    MinNstations = ";
0077     for (unsigned int j = 0; j < absetaBins_.size(); ++j) {
0078       ss << minNstations_[j] << " (|eta|<" << absetaBins_[j] << "), ";
0079     }
0080     ss << endl;
0081     ss << "    MinNhits = ";
0082     for (unsigned int j = 0; j < absetaBins_.size(); ++j) {
0083       ss << minNhits_[j] << " (|eta|<" << absetaBins_[j] << "), ";
0084     }
0085     ss << endl;
0086     ss << "    CutOnChambers = " << cutOnChambers_ << endl;
0087     if (cutOnChambers_) {
0088       ss << "    MinNchambers = ";
0089       for (unsigned int j = 0; j < absetaBins_.size(); ++j) {
0090         ss << minNchambers_[j] << " (|eta|<" << absetaBins_[j] << "), ";
0091       }
0092     }
0093     ss << endl;
0094     ss << "    MaxDr = " << maxDr_ << endl;
0095     ss << "    MinDr = " << minDr_ << endl;
0096     ss << "    MaxDz = " << maxDz_ << endl;
0097     ss << "    MinDxySig = " << min_DxySig_ << endl;
0098     ss << "    MinPt = " << minPt_ << endl;
0099     ss << "    NSigmaPt = " << nSigmaPt_ << endl;
0100     ss << "    saveTags= " << saveTags();
0101     LogDebug("HLTMuonL2PreFilter") << ss.str();
0102   }
0103 }
0104 
0105 HLTMuonL2PreFilter::~HLTMuonL2PreFilter() = default;
0106 
0107 void HLTMuonL2PreFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0108   edm::ParameterSetDescription desc;
0109   makeHLTFilterDescription(desc);
0110   desc.add<edm::InputTag>("BeamSpotTag", edm::InputTag("hltOfflineBeamSpot"));
0111   desc.add<edm::InputTag>("CandTag", edm::InputTag("hltL2MuonCandidates"));
0112   desc.add<edm::InputTag>("PreviousCandTag", edm::InputTag(""));
0113   desc.add<edm::InputTag>("SeedMapTag", edm::InputTag("hltL2Muons"));
0114   desc.add<int>("MinN", 1);
0115   desc.add<double>("MaxEta", 2.5);
0116   desc.add<std::vector<double> >("AbsEtaBins", std::vector<double>(1, 9999.));
0117   desc.add<std::vector<int> >("MinNstations", std::vector<int>(1, 1));
0118   desc.add<std::vector<int> >("MinNhits", std::vector<int>(1, 0));
0119   desc.add<bool>("CutOnChambers", false);
0120   desc.add<std::vector<int> >("MinNchambers", std::vector<int>(1, 0));
0121   desc.add<double>("MaxDr", 9999.0);
0122   desc.add<double>("MinDr", -1.0);
0123   desc.add<double>("MaxDz", 9999.0);
0124   desc.add<double>("MinDxySig", -1.0);
0125   desc.add<double>("MinPt", 0.0);
0126   desc.add<double>("NSigmaPt", 0.0);
0127   descriptions.add("hltMuonL2PreFilter", desc);
0128 }
0129 
0130 //
0131 // member functions
0132 //
0133 
0134 // ------------ method called to produce the data  ------------
0135 bool HLTMuonL2PreFilter::hltFilter(edm::Event& iEvent,
0136                                    const edm::EventSetup& iSetup,
0137                                    trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0138   // All HLT filters must create and fill an HLT filter object,
0139   // recording any reconstructed physics objects satisfying (or not)
0140   // this HLT filter, and place it in the Event.
0141 
0142   using namespace std;
0143   using namespace edm;
0144   using namespace reco;
0145   using namespace trigger;
0146   using namespace l1extra;
0147 
0148   // save Tag
0149   if (saveTags())
0150     filterproduct.addCollectionTag(candTag_);
0151 
0152   // get hold of all muon candidates available at this level
0153   Handle<RecoChargedCandidateCollection> allMuons;
0154   iEvent.getByToken(candToken_, allMuons);
0155 
0156   // get hold of the beam spot
0157   Handle<BeamSpot> beamSpotHandle;
0158   iEvent.getByToken(beamSpotToken_, beamSpotHandle);
0159   BeamSpot::Point beamSpot = beamSpotHandle->position();
0160 
0161   // get the L2 to L1 map object for this event
0162   HLTMuonL2ToL1Map mapL2ToL1(previousCandToken_, seedMapToken_, iEvent);
0163 
0164   // number of eta bins for cut on number of stations
0165   const std::vector<double>::size_type nAbsetaBins = absetaBins_.size();
0166 
0167   // look at all allMuons,  check cuts and add to filter object
0168   int n = 0;
0169   for (auto cand = allMuons->begin(); cand != allMuons->end(); cand++) {
0170     TrackRef mu = cand->get<TrackRef>();
0171 
0172     // check if this muon passed previous level
0173     if (!mapL2ToL1.isTriggeredByL1(mu))
0174       continue;
0175 
0176     // eta cut
0177     if (std::abs(mu->eta()) > maxEta_)
0178       continue;
0179 
0180     // cut on number of stations
0181     bool failNstations(false), failNhits(false), failNchambers(false);
0182     for (unsigned int i = 0; i < nAbsetaBins; ++i) {
0183       if (std::abs(mu->eta()) < absetaBins_[i]) {
0184         if (mu->hitPattern().muonStationsWithAnyHits() < minNstations_[i]) {
0185           failNstations = true;
0186         }
0187         if (mu->numberOfValidHits() < minNhits_[i]) {
0188           failNhits = true;
0189         }
0190         if (cutOnChambers_ &&
0191             (mu->hitPattern().dtStationsWithAnyHits() + mu->hitPattern().cscStationsWithAnyHits() < minNchambers_[i])) {
0192           failNchambers = true;
0193         }
0194         break;
0195       }
0196     }
0197     if (failNstations || failNhits || failNchambers)
0198       continue;
0199 
0200     //dr cut
0201     if (std::abs(mu->dxy(beamSpot)) > maxDr_)
0202       continue;
0203 
0204     //dr cut
0205     if (std::abs(mu->dxy(beamSpot)) < minDr_)
0206       continue;
0207 
0208     //dz cut
0209     if (std::abs(mu->dz(beamSpot)) > maxDz_)
0210       continue;
0211 
0212     // dxy significance cut (safeguard against bizarre values)
0213     if (min_DxySig_ > 0 && (mu->dxyError() <= 0 || std::abs(mu->dxy(beamSpot) / mu->dxyError()) < min_DxySig_))
0214       continue;
0215 
0216     // Pt threshold cut
0217     double pt = mu->pt();
0218     double abspar0 = std::abs(mu->parameter(0));
0219     double ptLx = pt;
0220     // convert 50% efficiency threshold to 90% efficiency threshold
0221     if (abspar0 > 0)
0222       ptLx += nSigmaPt_ * mu->error(0) / abspar0 * pt;
0223     if (ptLx < minPt_)
0224       continue;
0225 
0226     // add the good candidate to the filter object
0227     filterproduct.addObject(
0228         TriggerMuon, RecoChargedCandidateRef(Ref<RecoChargedCandidateCollection>(allMuons, cand - allMuons->begin())));
0229 
0230     n++;
0231   }
0232 
0233   // filter decision
0234   const bool accept(n >= minN_);
0235 
0236   // dump event for debugging
0237   if (edm::isDebugEnabled()) {
0238     ostringstream ss;
0239     ss << "L2mu#" << '\t' << "q*pt" << '\t'  //scientific is too wide
0240        << '\t' << "q*ptLx" << '\t'           //scientific is too wide
0241        << '\t' << "eta" << '\t' << "phi" << '\t' << "nStations" << '\t' << "nHits" << '\t' << "dr"
0242        << '\t'                  //scientific is too wide
0243        << '\t' << "dz" << '\t'  //scientific is too wide
0244        << '\t' << "L1seed#" << '\t' << "isPrev" << '\t' << "isFired" << endl;
0245     ss << "------------------------------------------------------------------------------------------------------------"
0246           "-----------"
0247        << endl;
0248     for (auto cand = allMuons->begin(); cand != allMuons->end(); cand++) {
0249       TrackRef mu = cand->get<TrackRef>();
0250       ss << setprecision(2) << cand - allMuons->begin() << '\t' << scientific << mu->charge() * mu->pt() << '\t'
0251          << scientific
0252          << mu->charge() * mu->pt() *
0253                 (1. + ((mu->parameter(0) != 0) ? nSigmaPt_ * mu->error(0) / std::abs(mu->parameter(0)) : 0.))
0254          << '\t' << fixed << mu->eta() << '\t' << fixed << mu->phi() << '\t'
0255          << mu->hitPattern().muonStationsWithAnyHits() << '\t' << mu->numberOfValidHits() << '\t' << scientific
0256          << mu->d0() << '\t' << scientific << mu->dz() << '\t' << mapL2ToL1.getL1Keys(mu) << '\t'
0257          << mapL2ToL1.isTriggeredByL1(mu);
0258       vector<RecoChargedCandidateRef> firedMuons;
0259       filterproduct.getObjects(TriggerMuon, firedMuons);
0260       ss << '\t'
0261          << (find(firedMuons.begin(),
0262                   firedMuons.end(),
0263                   RecoChargedCandidateRef(Ref<RecoChargedCandidateCollection>(allMuons, cand - allMuons->begin()))) !=
0264              firedMuons.end())
0265          << endl;
0266     }
0267     ss << "------------------------------------------------------------------------------------------------------------"
0268           "-----------"
0269        << endl;
0270     ss << "Decision of filter is " << accept << ", number of muons passing = " << filterproduct.muonSize();
0271     LogDebug("HLTMuonL2PreFilter") << ss.str();
0272   }
0273 
0274   return accept;
0275 }
0276 
0277 // declare this class as a framework plugin
0278 #include "FWCore/Framework/interface/MakerMacros.h"
0279 DEFINE_FWK_MODULE(HLTMuonL2PreFilter);