Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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