Skip to content

Commit

Permalink
Merge pull request #46574 from mmusich/mm_dev_ali_goo_id_muon_selector
Browse files Browse the repository at this point in the history
Rework Muon candidate selection in few tracker ALCARECO
  • Loading branch information
cmsbuild authored Nov 4, 2024
2 parents 669f2de + b916211 commit d08538a
Show file tree
Hide file tree
Showing 10 changed files with 268 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "DataFormats/Common/interface/Handle.h"
#include "DataFormats/MuonReco/interface/Muon.h"
#include "DataFormats/MuonReco/interface/MuonFwd.h"
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/global/EDFilter.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"

class AlignmentGoodIdMuonSelector : public edm::global::EDFilter<> {
public:
explicit AlignmentGoodIdMuonSelector(const edm::ParameterSet&);
~AlignmentGoodIdMuonSelector() override = default;

static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);

private:
bool filter(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;

const edm::EDGetTokenT<reco::MuonCollection> muonToken_;
const double maxEta_;
const double maxChi2_;
const int minMuonHits_;
const int minMatches_;
const bool requireGlobal_;
const bool requireTracker_;
const bool filterEvents_; // flag to control event filtering behavior

// Secondary selection parameters (e.g., for Phase 2)
const bool useSecondarySelection_;
const double secondaryEtaLow_;
const double secondaryEtaHigh_;
const int secondaryMinMatches_;
const bool requireTrackerForSecondary_;
};

void AlignmentGoodIdMuonSelector::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.add<edm::InputTag>("src", edm::InputTag("muons"))->setComment("Input muon collection");
desc.add<double>("maxEta", 2.5)->setComment("|eta| cut");
desc.add<double>("maxChi2", 20.)->setComment("max chi2 of the global tags");
desc.add<int>("minMuonHits", 0.)->setComment("minimum number of valid muon hits");
desc.add<int>("minMatches", 1.)->setComment("minimum number of matches");
desc.add<bool>("requireGlobal", true)->setComment("is global muons");
desc.add<bool>("requireTracker", true)->setComment("is tracker muon");
desc.add<bool>("useSecondarySelection", false)->setComment("secondary selection");
desc.add<double>("secondaryEtaLow", 2.3)->setComment("min eta cut (secondary)");
desc.add<double>("secondaryEtaHigh", 3.0)->setComment("max eta cut (secondary)");
desc.add<int>("secondaryMinMatches", 0.)->setComment("minimum number of matches (secondary)");
desc.add<bool>("secondaryRequireTracker", true)->setComment("is tracker muon (secondary)");
desc.add<bool>("filter", true)->setComment("retain event only if non empty collection");
descriptions.addWithDefaultLabel(desc);
}

AlignmentGoodIdMuonSelector::AlignmentGoodIdMuonSelector(const edm::ParameterSet& iConfig)
: muonToken_(consumes<reco::MuonCollection>(iConfig.getParameter<edm::InputTag>("src"))),
maxEta_(iConfig.getParameter<double>("maxEta")),
maxChi2_(iConfig.getParameter<double>("maxChi2")),
minMuonHits_(iConfig.getParameter<int>("minMuonHits")),
minMatches_(iConfig.getParameter<int>("minMatches")),
requireGlobal_(iConfig.getParameter<bool>("requireGlobal")),
requireTracker_(iConfig.getParameter<bool>("requireTracker")),
filterEvents_(iConfig.getParameter<bool>("filter")),

// Secondary selection
useSecondarySelection_(iConfig.getParameter<bool>("useSecondarySelection")),
secondaryEtaLow_(iConfig.getParameter<double>("secondaryEtaLow")),
secondaryEtaHigh_(iConfig.getParameter<double>("secondaryEtaHigh")),
secondaryMinMatches_(iConfig.getParameter<int>("secondaryMinMatches")),
requireTrackerForSecondary_(iConfig.getParameter<bool>("secondaryRequireTracker")) {
produces<reco::MuonCollection>();
}

bool AlignmentGoodIdMuonSelector::filter(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const {
edm::Handle<reco::MuonCollection> muons;
iEvent.getByToken(muonToken_, muons);

auto selectedMuons = std::make_unique<reco::MuonCollection>();

for (const auto& muon : *muons) {
bool passPrimarySelection = true;

// Check if globalTrack() is valid before using it
if (requireGlobal_) {
if (!muon.isGlobalMuon() || muon.globalTrack().isNull()) {
passPrimarySelection = false;
} else {
// Only access properties if the global track is valid
if (muon.globalTrack()->hitPattern().numberOfValidMuonHits() <= minMuonHits_)
passPrimarySelection = false;
if (muon.globalTrack()->normalizedChi2() >= maxChi2_)
passPrimarySelection = false;
}
}

if (requireTracker_ && !muon.isTrackerMuon())
passPrimarySelection = false;
if (muon.numberOfMatches() <= minMatches_)
passPrimarySelection = false;
if (std::abs(muon.eta()) >= maxEta_)
passPrimarySelection = false;

bool passSecondarySelection = false;
if (useSecondarySelection_) {
if (std::abs(muon.eta()) > secondaryEtaLow_ && std::abs(muon.eta()) < secondaryEtaHigh_ &&
muon.numberOfMatches() >= secondaryMinMatches_ && (!requireTrackerForSecondary_ || muon.isTrackerMuon())) {
passSecondarySelection = true;
}
}

if (passPrimarySelection || passSecondarySelection) {
selectedMuons->push_back(muon);
}
}

const bool passEvent = !selectedMuons->empty();
iEvent.put(std::move(selectedMuons));

// Decide if the event should pass based on filterEvents_ flag
return filterEvents_ ? passEvent : true;
}

#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(AlignmentGoodIdMuonSelector);
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "DataFormats/Common/interface/Handle.h"
#include "DataFormats/MuonReco/interface/Muon.h"
#include "DataFormats/MuonReco/interface/MuonFwd.h"
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/global/EDFilter.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"

class AlignmentRelCombIsoMuonSelector : public edm::global::EDFilter<> {
public:
explicit AlignmentRelCombIsoMuonSelector(const edm::ParameterSet&);
~AlignmentRelCombIsoMuonSelector() override = default;

static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);

private:
bool filter(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;

edm::EDGetTokenT<reco::MuonCollection> muonToken_;
const double relCombIsoCut_;
const bool useTrackerOnlyIsolation_; // New flag for tracker-only isolation
const bool filterEvents_;
};

void AlignmentRelCombIsoMuonSelector::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.add<edm::InputTag>("src", edm::InputTag("muons"))->setComment("Input muon collection");
desc.add<double>("relCombIsoCut", 0.15)->setComment("cut on the relative combined isolation");
desc.add<bool>("useTrackerOnlyIsolation", false)->setComment("use only tracker isolation");
desc.add<bool>("filter", true);
descriptions.addWithDefaultLabel(desc);
}

AlignmentRelCombIsoMuonSelector::AlignmentRelCombIsoMuonSelector(const edm::ParameterSet& iConfig)
: muonToken_(consumes<reco::MuonCollection>(iConfig.getParameter<edm::InputTag>("src"))),
relCombIsoCut_(iConfig.getParameter<double>("relCombIsoCut")),
useTrackerOnlyIsolation_(iConfig.getParameter<bool>("useTrackerOnlyIsolation")),
filterEvents_(iConfig.getParameter<bool>("filter")) {
produces<reco::MuonCollection>();
}

bool AlignmentRelCombIsoMuonSelector::filter(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const {
edm::Handle<reco::MuonCollection> muons;
iEvent.getByToken(muonToken_, muons);

auto selectedMuons = std::make_unique<reco::MuonCollection>();

for (const auto& muon : *muons) {
double relCombIso;
if (useTrackerOnlyIsolation_) {
// Tracker-only isolation
relCombIso = muon.isolationR03().sumPt / muon.pt();
} else {
// Full combined isolation
relCombIso = (muon.isolationR03().sumPt + muon.isolationR03().emEt + muon.isolationR03().hadEt) / muon.pt();
}

if (relCombIso < relCombIsoCut_) {
selectedMuons->push_back(muon);
}
}

const bool passEvent = !selectedMuons->empty();
iEvent.put(std::move(selectedMuons));

// Apply the filter flag logic
return filterEvents_ ? passEvent : true;
}

#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(AlignmentRelCombIsoMuonSelector);
5 changes: 5 additions & 0 deletions Alignment/CommonAlignmentProducer/plugins/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,8 @@
<use name="HLTrigger/HLTcore"/>
<flags EDM_PLUGIN="1"/>
</library>

<library file="Alignment*MuonSelector.cc" name="AlignmentCommonAlignmentProducerSelector">
<use name="DataFormats/MuonReco"/>
<flags EDM_PLUGIN="1"/>
</library>
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@
##################################################################
# Exact same configuration as TkAlZMuMu: extract mumu pairs
#################################################################
from Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi import *
import Alignment.CommonAlignmentProducer.ALCARECOTkAlZMuMu_cff as confALCARECOTkAlZMuMu
ALCARECOTkAlDiMuonHLT = confALCARECOTkAlZMuMu.ALCARECOTkAlZMuMuHLT.clone()
ALCARECOTkAlDiMuonDCSFilter = confALCARECOTkAlZMuMu.ALCARECOTkAlZMuMuDCSFilter.clone()
ALCARECOTkAlDiMuonGoodMuons = confALCARECOTkAlZMuMu.ALCARECOTkAlZMuMuGoodMuons.clone()
ALCARECOTkAlDiMuonRelCombIsoMuons = confALCARECOTkAlZMuMu.ALCARECOTkAlZMuMuRelCombIsoMuons.clone(src = 'ALCARECOTkAlDiMuonGoodMuons')
ALCARECOTkAlDiMuon = confALCARECOTkAlZMuMu.ALCARECOTkAlZMuMu.clone()
ALCARECOTkAlDiMuon.GlobalSelector.muonSource = 'ALCARECOTkAlDiMuonRelCombIsoMuons'
ALCARECOTkAlDiMuon.GlobalSelector.muonSource = 'TkAlRelCombIsoMuonSelector'

##################################################################
# Tracks from the selected vertex
Expand All @@ -31,8 +30,7 @@
#################################################################
seqALCARECOTkAlDiMuonAndVertex = cms.Sequence(ALCARECOTkAlDiMuonHLT+
ALCARECOTkAlDiMuonDCSFilter+
ALCARECOTkAlDiMuonGoodMuons+
ALCARECOTkAlDiMuonRelCombIsoMuons+
seqALCARECOTkAlRelCombIsoMuons+
ALCARECOTkAlDiMuon+
ALCARECOTkAlDiMuonVertexTracks+
TkAlDiMuonAndVertexGenMuonSelector)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,7 @@
DebugOn = cms.untracked.bool(False)
)

import Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi
ALCARECOTkAlMuonIsolatedGoodMuons = Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi.TkAlGoodIdMuonSelector.clone()
ALCARECOTkAlMuonIsolatedRelCombIsoMuons = Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi.TkAlRelCombIsoMuonSelector.clone(
src = 'ALCARECOTkAlMuonIsolatedGoodMuons'
)
from Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi import *

import Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi
ALCARECOTkAlMuonIsolated = Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi.AlignmentTrackSelector.clone(
Expand All @@ -37,7 +33,7 @@
nHitMin = 0
)

ALCARECOTkAlMuonIsolated.GlobalSelector.muonSource = 'ALCARECOTkAlMuonIsolatedRelCombIsoMuons'
ALCARECOTkAlMuonIsolated.GlobalSelector.muonSource = 'TkAlRelCombIsoMuonSelector'
# Isolation is shifted to the muon preselection, and then applied intrinsically if applyGlobalMuonFilter = True
ALCARECOTkAlMuonIsolated.GlobalSelector.applyIsolationtest = False
ALCARECOTkAlMuonIsolated.GlobalSelector.minJetDeltaR = 0.1
Expand All @@ -47,8 +43,10 @@
ALCARECOTkAlMuonIsolated.TwoBodyDecaySelector.applyChargeFilter = False
ALCARECOTkAlMuonIsolated.TwoBodyDecaySelector.applyAcoplanarityFilter = False

seqALCARECOTkAlMuonIsolated = cms.Sequence(ALCARECOTkAlMuonIsolatedHLT+ALCARECOTkAlMuonIsolatedDCSFilter+ALCARECOTkAlMuonIsolatedGoodMuons+ALCARECOTkAlMuonIsolatedRelCombIsoMuons+ALCARECOTkAlMuonIsolated)

seqALCARECOTkAlMuonIsolated = cms.Sequence(ALCARECOTkAlMuonIsolatedHLT+
ALCARECOTkAlMuonIsolatedDCSFilter+
seqALCARECOTkAlRelCombIsoMuons+
ALCARECOTkAlMuonIsolated)

## customizations for the pp_on_AA eras
from Configuration.Eras.Modifier_pp_on_XeXe_2017_cff import pp_on_XeXe_2017
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@

import Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi
ALCARECOTkAlUpsilonMuMuGoodMuons = Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi.TkAlGoodIdMuonSelector.clone()
ALCARECOTkAlUpsilonMuMuRelCombIsoMuons = Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi.TkAlRelCombIsoMuonSelector.clone(
src = 'ALCARECOTkAlUpsilonMuMuGoodMuons',
cut = '(isolationR03().sumPt + isolationR03().emEt + isolationR03().hadEt)/pt < 0.3'

)
ALCARECOTkAlUpsilonMuMuRelCombIsoMuons = Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi.TkAlRelCombIsoMuonSelector.clone(src = 'ALCARECOTkAlUpsilonMuMuGoodMuons')

import Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi
ALCARECOTkAlUpsilonMuMu = Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi.AlignmentTrackSelector.clone()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

ALCARECOTkAlZMuMuPADCSFilter = ALCARECOTkAlZMuMuDCSFilter.clone()

ALCARECOTkAlZMuMuPAGoodMuons = ALCARECOTkAlZMuMuGoodMuons.clone()
ALCARECOTkAlZMuMuPAGoodMuons = TkAlGoodIdMuonSelector.clone()

ALCARECOTkAlZMuMuPA = ALCARECOTkAlZMuMu.clone(
src = 'generalTracks'
Expand All @@ -18,6 +18,6 @@

seqALCARECOTkAlZMuMuPA = cms.Sequence(ALCARECOTkAlZMuMuPAHLT
+ALCARECOTkAlZMuMuPADCSFilter
+ALCARECOTkAlZMuMuPAGoodMuons
+TkAlGoodIdMuonSelector
+ALCARECOTkAlZMuMuPA
)
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@
DebugOn = cms.untracked.bool(False)
)

import Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi
ALCARECOTkAlZMuMuGoodMuons = Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi.TkAlGoodIdMuonSelector.clone()
ALCARECOTkAlZMuMuRelCombIsoMuons = Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi.TkAlRelCombIsoMuonSelector.clone(
src = 'ALCARECOTkAlZMuMuGoodMuons'
)
## standard muon selection
from Alignment.CommonAlignmentProducer.TkAlMuonSelectors_cfi import *

import Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi
ALCARECOTkAlZMuMu = Alignment.CommonAlignmentProducer.AlignmentTrackSelector_cfi.AlignmentTrackSelector.clone()
Expand All @@ -37,7 +34,7 @@
ALCARECOTkAlZMuMu.etaMax = 3.5
ALCARECOTkAlZMuMu.nHitMin = 0

ALCARECOTkAlZMuMu.GlobalSelector.muonSource = 'ALCARECOTkAlZMuMuRelCombIsoMuons'
ALCARECOTkAlZMuMu.GlobalSelector.muonSource = 'TkAlRelCombIsoMuonSelector'
# Isolation is shifted to the muon preselection, and then applied intrinsically if applyGlobalMuonFilter = True
ALCARECOTkAlZMuMu.GlobalSelector.applyIsolationtest = False
ALCARECOTkAlZMuMu.GlobalSelector.applyGlobalMuonFilter = True
Expand All @@ -58,7 +55,11 @@
filter = cms.bool(False),
throwOnMissing = cms.untracked.bool(False))

seqALCARECOTkAlZMuMu = cms.Sequence(ALCARECOTkAlZMuMuHLT+ALCARECOTkAlZMuMuDCSFilter+ALCARECOTkAlZMuMuGoodMuons+ALCARECOTkAlZMuMuRelCombIsoMuons+ALCARECOTkAlZMuMu+TkAlZMuMuGenMuonSelector)
seqALCARECOTkAlZMuMu = cms.Sequence(ALCARECOTkAlZMuMuHLT+
ALCARECOTkAlZMuMuDCSFilter+
seqALCARECOTkAlRelCombIsoMuons+
ALCARECOTkAlZMuMu+
TkAlZMuMuGenMuonSelector)

## customizations for the pp_on_AA eras
from Configuration.Eras.Modifier_pp_on_XeXe_2017_cff import pp_on_XeXe_2017
Expand Down
Loading

0 comments on commit d08538a

Please sign in to comment.