Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework Muon candidate selection in few tracker ALCARECO #46574

Merged
merged 3 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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