Skip to content

Commit 9cabbf1

Browse files
committed
Rewrite SimpleJetConstituentTableProducer to be able to cut on constituents. Move jet constituents set up to its own file. Add functions to add AK4 jet and genjets constituents for private production
1 parent 2f1e918 commit 9cabbf1

File tree

4 files changed

+249
-72
lines changed

4 files changed

+249
-72
lines changed

PhysicsTools/NanoAOD/plugins/SimpleJetConstituentTableProducer.cc

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616
#include "CommonTools/Utils/interface/StringCutObjectSelector.h"
1717
#include "DataFormats/NanoAOD/interface/FlatTable.h"
1818

19-
template <typename T>
19+
template <typename T, typename C = std::vector<typename T::ConstituentTypeFwdPtr>>
2020
class SimpleJetConstituentTableProducer : public edm::stream::EDProducer<> {
2121
public:
22+
23+
using ConstituentsOutput = C;
24+
using ConstituentValueType = typename C::value_type;
25+
2226
explicit SimpleJetConstituentTableProducer(const edm::ParameterSet &);
2327
~SimpleJetConstituentTableProducer() override;
2428

29+
ConstituentValueType const initptr(edm::Ptr<reco::Candidate> const&) const;
2530
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions);
2631

2732
private:
@@ -35,41 +40,40 @@ class SimpleJetConstituentTableProducer : public edm::stream::EDProducer<> {
3540
edm::EDGetTokenT<reco::CandidateView> cand_token_;
3641

3742
const StringCutObjectSelector<T> jetCut_;
38-
39-
edm::Handle<reco::CandidateView> cands_;
43+
const StringCutObjectSelector<ConstituentValueType> jetConstCut_;
4044
};
4145

4246
//
4347
// constructors and destructor
4448
//
45-
template <typename T>
46-
SimpleJetConstituentTableProducer<T>::SimpleJetConstituentTableProducer(const edm::ParameterSet &iConfig)
49+
template <typename T, typename C>
50+
SimpleJetConstituentTableProducer<T,C>::SimpleJetConstituentTableProducer(const edm::ParameterSet &iConfig)
4751
: name_(iConfig.getParameter<std::string>("name")),
4852
candIdxName_(iConfig.getParameter<std::string>("candIdxName")),
4953
candIdxDoc_(iConfig.getParameter<std::string>("candIdxDoc")),
5054
jet_token_(consumes<edm::View<T>>(iConfig.getParameter<edm::InputTag>("jets"))),
5155
cand_token_(consumes<reco::CandidateView>(iConfig.getParameter<edm::InputTag>("candidates"))),
52-
jetCut_(iConfig.getParameter<std::string>("jetCut")) {
56+
jetCut_(iConfig.getParameter<std::string>("jetCut")),
57+
jetConstCut_(iConfig.getParameter<std::string>("jetConstCut")) {
5358
produces<nanoaod::FlatTable>(name_);
54-
produces<std::vector<reco::CandidatePtr>>();
59+
produces<ConstituentsOutput>();
5560
}
5661

57-
template <typename T>
58-
SimpleJetConstituentTableProducer<T>::~SimpleJetConstituentTableProducer() {}
62+
template <typename T, typename C>
63+
SimpleJetConstituentTableProducer<T,C>::~SimpleJetConstituentTableProducer() {}
5964

60-
template <typename T>
61-
void SimpleJetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
65+
template <typename T, typename C>
66+
void SimpleJetConstituentTableProducer<T,C>::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
6267
// elements in all these collections must have the same order!
63-
auto outCands = std::make_unique<std::vector<reco::CandidatePtr>>();
68+
auto outCands = std::make_unique<ConstituentsOutput>();
6469

6570
auto jets = iEvent.getHandle(jet_token_);
6671

72+
edm::Handle<reco::CandidateView> cands_;
6773
iEvent.getByToken(cand_token_, cands_);
6874
auto candPtrs = cands_->ptrs();
6975

70-
//
7176
// First, select jets
72-
//
7377
std::vector<T> jetsPassCut;
7478
for (unsigned jetIdx = 0; jetIdx < jets->size(); ++jetIdx) {
7579
const auto &jet = jets->at(jetIdx);
@@ -78,23 +82,27 @@ void SimpleJetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm
7882
jetsPassCut.push_back(jets->at(jetIdx));
7983
}
8084

81-
//
8285
// Then loop over selected jets
83-
//
8486
std::vector<int> parentJetIdx;
8587
std::vector<int> candIdx;
8688
for (unsigned jetIdx = 0; jetIdx < jetsPassCut.size(); ++jetIdx) {
8789
const auto &jet = jetsPassCut.at(jetIdx);
8890

89-
//
9091
// Loop over jet constituents
91-
//
9292
std::vector<reco::CandidatePtr> const &daughters = jet.daughterPtrVector();
93-
for (const auto &cand : daughters) {
94-
auto candInNewList = std::find(candPtrs.begin(), candPtrs.end(), cand);
93+
for (const auto &dauPtr : daughters) {
94+
95+
// Apply cut on jet constituent
96+
typename C::value_type cand = initptr(dauPtr);
97+
if (!jetConstCut_(cand))
98+
continue;
99+
100+
// Find jet constituent in candidate collection
101+
auto candInNewList = std::find(candPtrs.begin(), candPtrs.end(), dauPtr);
95102
if (candInNewList == candPtrs.end()) {
96103
continue;
97104
}
105+
98106
outCands->push_back(cand);
99107
parentJetIdx.push_back(jetIdx);
100108
candIdx.push_back(candInNewList - candPtrs.begin());
@@ -103,34 +111,49 @@ void SimpleJetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm
103111

104112
auto candTable = std::make_unique<nanoaod::FlatTable>(outCands->size(), name_, false);
105113
// We fill from here only stuff that cannot be created with the SimpleFlatTableProducer
106-
candTable->addColumn<int>(candIdxName_, candIdx, candIdxDoc_);
114+
candTable->template addColumn<int>(candIdxName_, candIdx, candIdxDoc_);
107115

108116
std::string parentJetIdxName("jetIdx");
109117
std::string parentJetIdxDoc("Index of the parent jet");
110118
if constexpr (std::is_same<T, reco::GenJet>::value) {
111119
parentJetIdxName = "genJetIdx";
112120
parentJetIdxDoc = "Index of the parent gen jet";
113121
}
114-
candTable->addColumn<int>(parentJetIdxName, parentJetIdx, parentJetIdxDoc);
122+
candTable->template addColumn<int>(parentJetIdxName, parentJetIdx, parentJetIdxDoc);
115123

116124
iEvent.put(std::move(candTable), name_);
117125
iEvent.put(std::move(outCands));
118126
}
119127

120-
template <typename T>
121-
void SimpleJetConstituentTableProducer<T>::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
128+
template <>
129+
edm::Ptr<pat::PackedCandidate> const
130+
SimpleJetConstituentTableProducer<pat::Jet, std::vector<edm::Ptr<pat::PackedCandidate>>>::initptr(edm::Ptr<reco::Candidate> const& dau) const {
131+
edm::Ptr<pat::PackedCandidate> retval(dau);
132+
return retval;
133+
}
134+
135+
template <>
136+
edm::Ptr<pat::PackedGenParticle> const
137+
SimpleJetConstituentTableProducer<reco::GenJet, std::vector<edm::Ptr<pat::PackedGenParticle>>>::initptr(edm::Ptr<reco::Candidate> const& dau) const {
138+
edm::Ptr<pat::PackedGenParticle> retval(dau);
139+
return retval;
140+
}
141+
142+
template <typename T, typename C>
143+
void SimpleJetConstituentTableProducer<T,C>::fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
122144
edm::ParameterSetDescription desc;
123145
desc.add<std::string>("name", "FatJetPFCand");
124146
desc.add<std::string>("candIdxName", "PFCandIdx");
125147
desc.add<std::string>("candIdxDoc", "Index in PFCand table");
126148
desc.add<edm::InputTag>("jets", edm::InputTag("finalJetsAK8"));
127149
desc.add<edm::InputTag>("candidates", edm::InputTag("packedPFCandidates"));
128150
desc.add<std::string>("jetCut", "");
151+
desc.add<std::string>("jetConstCut", "");
129152
descriptions.addWithDefaultLabel(desc);
130153
}
131154

132-
typedef SimpleJetConstituentTableProducer<pat::Jet> SimplePatJetConstituentTableProducer;
133-
typedef SimpleJetConstituentTableProducer<reco::GenJet> SimpleGenJetConstituentTableProducer;
155+
typedef SimpleJetConstituentTableProducer<pat::Jet, std::vector<edm::Ptr<pat::PackedCandidate>>> SimplePatJetConstituentTableProducer;
156+
typedef SimpleJetConstituentTableProducer<reco::GenJet, std::vector<edm::Ptr<pat::PackedGenParticle>>> SimpleGenJetConstituentTableProducer;
134157

135158
DEFINE_FWK_MODULE(SimplePatJetConstituentTableProducer);
136159
DEFINE_FWK_MODULE(SimpleGenJetConstituentTableProducer);
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
import FWCore.ParameterSet.Config as cms
2+
3+
from PhysicsTools.NanoAOD.common_cff import *
4+
from PhysicsTools.NanoAOD.jetsAK8_cff import fatJetTable as _fatJetTable
5+
6+
##############################################################
7+
# Take AK8 jets and collect their PF constituents
8+
###############################################################
9+
finalJetsAK8PFConstituents = cms.EDProducer("PatJetConstituentPtrSelector",
10+
src = _fatJetTable.src,
11+
cut = cms.string("abs(eta) <= 2.5")
12+
)
13+
14+
selectedFinalJetsAK8PFConstituents = cms.EDFilter("PATPackedCandidatePtrSelector",
15+
src = cms.InputTag("finalJetsAK8PFConstituents", "constituents"),
16+
cut = cms.string("")
17+
)
18+
19+
##############################################################
20+
# Setup PF candidates table
21+
##############################################################
22+
finalPFCandidates = cms.EDProducer("PackedCandidatePtrMerger",
23+
src = cms.VInputTag(cms.InputTag("selectedFinalJetsAK8PFConstituents")),
24+
skipNulls = cms.bool(True),
25+
warnOnSkip = cms.bool(True)
26+
)
27+
28+
pfCandidatesTable = cms.EDProducer("SimplePATCandidateFlatTableProducer",
29+
src = cms.InputTag("finalPFCandidates"),
30+
cut = cms.string(""),
31+
name = cms.string("PFCand"),
32+
doc = cms.string("PF candidate constituents of AK8 puppi jets (FatJet) with |eta| <= 2.5"),
33+
singleton = cms.bool(False),
34+
extension = cms.bool(False),
35+
variables = cms.PSet(
36+
pt = Var("pt * puppiWeight()", float, doc="Puppi-weighted pt", precision=10),
37+
mass = Var("mass * puppiWeight()", float, doc="Puppi-weighted mass", precision=10),
38+
eta = Var("eta", float, precision=12),
39+
phi = Var("phi", float, precision=12),
40+
pdgId = Var("pdgId", int, doc="PF candidate type (+/-211 = ChgHad, 130 = NeuHad, 22 = Photon, +/-11 = Electron, +/-13 = Muon, 1 = HFHad, 2 = HFEM)")
41+
)
42+
)
43+
44+
##############################################################
45+
# Setup AK8 jet constituents table
46+
##############################################################
47+
finalJetsAK8ConstituentsTable = cms.EDProducer("SimplePatJetConstituentTableProducer",
48+
name = cms.string(_fatJetTable.name.value()+"PFCand"),
49+
candIdxName = cms.string("pfCandIdx"),
50+
candIdxDoc = cms.string("Index in the PFCand table"),
51+
candidates = pfCandidatesTable.src,
52+
jets = _fatJetTable.src,
53+
jetCut = _fatJetTable.cut,
54+
jetConstCut = selectedFinalJetsAK8PFConstituents.cut
55+
)
56+
57+
jetConstituentsTask = cms.Task(finalJetsAK8PFConstituents,selectedFinalJetsAK8PFConstituents)
58+
jetConstituentsTablesTask = cms.Task(finalPFCandidates,pfCandidatesTable,finalJetsAK8ConstituentsTable)
59+
60+
61+
def SaveAK4JetConstituents(process, jetCut="", jetConstCut=""):
62+
"""
63+
This function can be used as a cmsDriver customization
64+
function to add AK4 jet constituents, on top of the AK8
65+
jet constituents.
66+
"""
67+
process.finalJetsPuppiPFConstituents = process.finalJetsAK8PFConstituents.clone(
68+
src = process.jetPuppiTable.src,
69+
cut = jetCut
70+
)
71+
process.jetConstituentsTask.add(process.finalJetsPuppiPFConstituents)
72+
73+
process.selectedFinalJetsPuppiPFConstituents = process.selectedFinalJetsAK8PFConstituents.clone(
74+
src = cms.InputTag("finalJetsPuppiPFConstituents", "constituents"),
75+
cut = jetConstCut
76+
)
77+
process.jetConstituentsTask.add(process.selectedFinalJetsPuppiPFConstituents)
78+
79+
process.finalPFCandidates.src += ["selectedFinalJetsPuppiPFConstituents"]
80+
process.pfCandidatesTable.doc = pfCandidatesTable.doc.value()+" and AK4 puppi jets (Jet)"
81+
82+
process.finalJetsPuppiConstituentsTable = process.finalJetsAK8ConstituentsTable.clone(
83+
name = process.jetPuppiTable.name.value()+"PFCand",
84+
jets = process.jetPuppiTable.src,
85+
jetCut = process.jetPuppiTable.cut,
86+
jetConstCut = process.selectedFinalJetsPuppiPFConstituents.cut
87+
)
88+
process.jetConstituentsTablesTask.add(process.finalJetsPuppiConstituentsTable)
89+
90+
return process
91+
92+
def SaveGenJetConstituents(process, addGenJetConst, addGenJetAK8Const, genJetConstCut="",genJetAK8ConstCut=""):
93+
"""
94+
This function can be used as a cmsDriver
95+
customization function to add gen jet
96+
constituents.
97+
"""
98+
process.genjetConstituentsTask = cms.Task()
99+
process.genjetConstituentsTableTask = cms.Task()
100+
101+
if addGenJetConst:
102+
process.genJetConstituents = cms.EDProducer("GenJetPackedConstituentPtrSelector",
103+
src = process.genJetTable.src,
104+
cut = process.genJetTable.cut,
105+
)
106+
process.genjetConstituentsTask.add(process.genJetConstituents)
107+
108+
process.selectedGenJetConstituents = cms.EDFilter("PATPackedGenParticlePtrSelector",
109+
src = cms.InputTag("genJetConstituents", "constituents"),
110+
cut = cms.string(genJetConstCut)
111+
)
112+
process.genjetConstituentsTask.add(process.selectedGenJetConstituents)
113+
114+
if addGenJetAK8Const:
115+
process.genJetAK8Constituents = cms.EDProducer("GenJetPackedConstituentPtrSelector",
116+
src = process.genJetAK8Table.src,
117+
cut = process.genJetAK8Table.cut,
118+
)
119+
process.genjetConstituentsTask.add(process.genJetAK8Constituents)
120+
121+
process.selectedGenJetAK8Constituents = cms.EDFilter("PATPackedGenParticlePtrSelector",
122+
src = cms.InputTag("genJetAK8Constituents", "constituents"),
123+
cut = cms.string(genJetConstCut)
124+
)
125+
process.genjetConstituentsTask.add(process.selectedGenJetAK8Constituents)
126+
127+
if addGenJetConst or addGenJetConst:
128+
process.finalGenPartCandidates = cms.EDProducer("PackedGenParticlePtrMerger",
129+
src = cms.VInputTag(),
130+
skipNulls = cms.bool(True),
131+
warnOnSkip = cms.bool(True)
132+
)
133+
process.genjetConstituentsTableTask.add(process.finalGenPartCandidates)
134+
135+
process.genPartCandidatesTable = cms.EDProducer("SimplePATGenParticleFlatTableProducer",
136+
src = cms.InputTag("finalGenPartCandidates"),
137+
cut = cms.string(""),
138+
name = cms.string("GenPartCand"),
139+
doc = cms.string("Gen particle constituents:"),
140+
singleton = cms.bool(False),
141+
extension = cms.bool(False),
142+
variables = cms.PSet(P4Vars,
143+
pdgId = Var("pdgId", int, doc="pdgId")
144+
)
145+
)
146+
process.genjetConstituentsTableTask.add(process.genPartCandidatesTable)
147+
process.genPartCandidatesTable.variables.pt.precision=10
148+
process.genPartCandidatesTable.variables.mass.precision=10
149+
150+
if addGenJetConst:
151+
process.finalGenPartCandidates.src += ["selectedGenJetConstituents"]
152+
process.genPartCandidatesTable.doc = process.genPartCandidatesTable.doc.value()+" AK4 Gen jets (GenJet) "
153+
154+
process.genJetConstituentsTable = cms.EDProducer("SimpleGenJetConstituentTableProducer",
155+
name = cms.string(process.genJetTable.name.value()+"GenPartCand"),
156+
candIdxName = cms.string("genPartCandIdx"),
157+
candIdxDoc = cms.string("Index in the GenPartCand table"),
158+
candidates = pfCandidatesTable.src,
159+
jets = process.genJetTable.src,
160+
jetCut = process.genJetTable.cut,
161+
jetConstCut = process.selectedGenJetConstituents.cut
162+
)
163+
process.genjetConstituentsTableTask.add(process.genJetConstituentsTable)
164+
165+
if addGenJetAK8Const:
166+
process.finalGenPartCandidates.src += ["selectedGenJetAK8Constituents"]
167+
process.genPartCandidatesTable.doc = process.genPartCandidatesTable.doc.value()+" AK8 Gen jets (GenJetAK8)"
168+
169+
process.genJetAK8ConstituentsTable = cms.EDProducer("SimpleGenJetConstituentTableProducer",
170+
name = cms.string(process.genJetAK8Table.name.value()+"GenPartCand"),
171+
candIdxName = cms.string("genPartCandIdx"),
172+
candIdxDoc = cms.string("Index in the GenPartCand table"),
173+
candidates = pfCandidatesTable.src,
174+
jets = process.genJetAK8Table.src,
175+
jetCut = process.genJetAK8Table.cut,
176+
jetConstCut = process.selectedGenJetConstituents.cut
177+
)
178+
process.genjetConstituentsTableTask.add(process.genJetAK8ConstituentsTable)
179+
180+
process.nanoTableTaskFS.add(process.genjetConstituentsTask)
181+
process.nanoTableTaskFS.add(process.genjetConstituentsTableTask)
182+
183+
return process
184+
185+
def SaveGenJetAK4Constituents(process):
186+
process = SaveGenJetConstituents(process,True,False)
187+
return process
188+
def SaveGenJetAK8Constituents(process):
189+
process = SaveGenJetConstituents(process,True,False)
190+
return process
191+
def SaveGenJetAK4AK8Constituents(process):
192+
process = SaveGenJetConstituents(process,True,True)
193+
return process
194+

0 commit comments

Comments
 (0)