Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
#include "DataFormats/Common/interface/Handle.h"

#include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
#include "DataFormats/HLTReco/interface/TriggerRefsCollections.h"

#include "FWCore/MessageLogger/interface/MessageLogger.h"

#include "DataFormats/TrackReco/interface/Track.h"
#include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
#include "DataFormats/MuonReco/interface/MuonFwd.h"
#include "HLTMuonTrkL1TFilter.h"
#include "DataFormats/BeamSpot/interface/BeamSpot.h"
#include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h"
#include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeedCollection.h"

#include "TrackingTools/PatternTools/interface/ClosestApproachInRPhi.h"
#include "TrackingTools/TransientTrack/interface/TransientTrack.h"
#include "MagneticField/Engine/interface/MagneticField.h"
#include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "FWCore/Utilities/interface/InputTag.h"
#include "FWCore/Utilities/interface/EDMException.h"

#include "DataFormats/Math/interface/deltaR.h"

HLTMuonTrkL1TFilter::HLTMuonTrkL1TFilter(const edm::ParameterSet& iConfig)
    : HLTFilter(iConfig),
      propSetup_(iConfig, consumesCollector()),
      m_muonsTag(iConfig.getParameter<edm::InputTag>("inputMuonCollection")),
      m_muonsToken(consumes<reco::MuonCollection>(m_muonsTag)),
      m_candsTag(iConfig.getParameter<edm::InputTag>("inputCandCollection")),
      m_candsToken(consumes<reco::RecoChargedCandidateCollection>(m_candsTag)),
      m_previousCandTag(iConfig.getParameter<edm::InputTag>("previousCandTag")),
      m_previousCandToken(consumes<trigger::TriggerFilterObjectWithRefs>(m_previousCandTag)),
      m_minTrkHits(iConfig.getParameter<int>("minTrkHits")),
      m_minMuonHits(iConfig.getParameter<int>("minMuonHits")),
      m_minMuonStations(iConfig.getParameter<int>("minMuonStations")),
      m_maxNormalizedChi2(iConfig.getParameter<double>("maxNormalizedChi2")),
      m_allowedTypeMask(iConfig.getParameter<unsigned int>("allowedTypeMask")),
      m_requiredTypeMask(iConfig.getParameter<unsigned int>("requiredTypeMask")),
      m_trkMuonId(muon::SelectionType(iConfig.getParameter<unsigned int>("trkMuonId"))),
      m_minPt(iConfig.getParameter<double>("minPt")),
      m_minN(iConfig.getParameter<unsigned int>("minN")),
      m_maxAbsEta(iConfig.getParameter<double>("maxAbsEta")),
      m_l1MatchingdR(iConfig.getParameter<double>("L1MatchingdR")),
      m_l1MatchingdR2(m_l1MatchingdR * m_l1MatchingdR) {
  if (m_l1MatchingdR <= 0.) {
    throw cms::Exception("HLTMuonTrkL1TFilterConfiguration")
        << "invalid value for parameter \"L1MatchingdR\" (must be > 0): " << m_l1MatchingdR;
  }
}

void HLTMuonTrkL1TFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
  edm::ParameterSetDescription desc;
  makeHLTFilterDescription(desc);
  desc.add<edm::InputTag>("inputMuonCollection", edm::InputTag(""));
  desc.add<edm::InputTag>("inputCandCollection", edm::InputTag(""));
  desc.add<edm::InputTag>("previousCandTag", edm::InputTag(""));
  desc.add<int>("minTrkHits", -1);
  desc.add<int>("minMuonHits", -1);
  desc.add<int>("minMuonStations", -1);
  desc.add<double>("maxNormalizedChi2", 1e99);
  desc.add<unsigned int>("allowedTypeMask", 255);
  desc.add<unsigned int>("requiredTypeMask", 0);
  desc.add<unsigned int>("trkMuonId", 0);
  desc.add<double>("minPt", 24);
  desc.add<unsigned int>("minN", 1);
  desc.add<double>("maxAbsEta", 1e99);
  desc.add<double>("L1MatchingdR", 0.3);
  PropagateToMuonSetup::fillPSetDescription(desc);
  descriptions.add("hltMuonTrkL1TFilter", desc);
}

bool HLTMuonTrkL1TFilter::hltFilter(edm::Event& iEvent,
                                    const edm::EventSetup& iSetup,
                                    trigger::TriggerFilterObjectWithRefs& filterproduct) const {
  auto const prop = propSetup_.init(iSetup);

  edm::Handle<reco::MuonCollection> muons;
  iEvent.getByToken(m_muonsToken, muons);
  edm::Handle<reco::RecoChargedCandidateCollection> cands;
  iEvent.getByToken(m_candsToken, cands);
  if (saveTags())
    filterproduct.addCollectionTag(m_candsTag);
  if (cands->size() != muons->size())
    throw edm::Exception(edm::errors::Configuration)
        << "Both input collection must be aligned and represent same physical muon objects";

  edm::Handle<trigger::TriggerFilterObjectWithRefs> previousLevelCands;
  std::vector<l1t::MuonRef> vl1cands;
  std::vector<l1t::MuonRef>::iterator vl1cands_begin;
  std::vector<l1t::MuonRef>::iterator vl1cands_end;

  bool check_l1match = true;
  if (m_previousCandTag == edm::InputTag(""))
    check_l1match = false;
  if (check_l1match) {
    iEvent.getByToken(m_previousCandToken, previousLevelCands);
    previousLevelCands->getObjects(trigger::TriggerL1Mu, vl1cands);
    vl1cands_begin = vl1cands.begin();
    vl1cands_end = vl1cands.end();
  }

  std::vector<unsigned int> filteredMuons;
  for (unsigned int i = 0; i < muons->size(); ++i) {
    const reco::Muon& muon(muons->at(i));
    if (check_l1match) {
      const reco::RecoChargedCandidateRef cand(cands, i);
      const reco::TrackRef tk = cand->track();
      auto etaForMatch = cand->eta();
      auto phiForMatch = cand->phi();
      // check for dR match to L1 muons
      if (tk.isNonnull()) {
        auto const propagated = prop.extrapolate(*tk);
        if (propagated.isValid()) {
          etaForMatch = propagated.globalPosition().eta();
          phiForMatch = propagated.globalPosition().phi();
        }
      }
      bool matchl1 = false;
      for (auto l1cand = vl1cands_begin; l1cand != vl1cands_end; ++l1cand) {
        if (deltaR2(etaForMatch, phiForMatch, (*l1cand)->eta(), (*l1cand)->phi()) < m_l1MatchingdR2) {
          matchl1 = true;
          break;
        }
      }
      if (!matchl1)
        continue;
    }
    if ((muon.type() & m_allowedTypeMask) == 0)
      continue;
    if ((muon.type() & m_requiredTypeMask) != m_requiredTypeMask)
      continue;
    if (muon.numberOfMatchedStations() < m_minMuonStations)
      continue;
    if (!muon.innerTrack().isNull()) {
      if (muon.innerTrack()->numberOfValidHits() < m_minTrkHits)
        continue;
    }
    if (!muon.globalTrack().isNull()) {
      if (muon.globalTrack()->normalizedChi2() > m_maxNormalizedChi2)
        continue;
      if (muon.globalTrack()->hitPattern().numberOfValidMuonHits() < m_minMuonHits)
        continue;
    }
    if (muon.isTrackerMuon() && !muon::isGoodMuon(muon, m_trkMuonId))
      continue;
    if (muon.pt() < m_minPt)
      continue;
    if (std::abs(muon.eta()) > m_maxAbsEta)
      continue;
    filteredMuons.push_back(i);
  }

  for (std::vector<unsigned int>::const_iterator itr = filteredMuons.begin(); itr != filteredMuons.end(); ++itr)
    filterproduct.addObject(trigger::TriggerMuon, reco::RecoChargedCandidateRef(cands, *itr));

  return filteredMuons.size() >= m_minN;
}

// declare this class as a framework plugin
#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(HLTMuonTrkL1TFilter);