Skip to content

Commit ed0f8ab

Browse files
authored
Merge pull request #47686 from mseidel42/btvNano_150X_backport
btvNano backports (15_0_X)
2 parents c08da19 + b3a4deb commit ed0f8ab

9 files changed

+497
-188
lines changed

Diff for: PhysicsTools/NanoAOD/plugins/BuildFile.xml

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<use name="CommonTools/Utils"/>
3232
<use name="CommonTools/UtilAlgos"/>
3333
<use name="CommonTools/CandAlgos"/>
34+
<use name="PhysicsTools/JetMCUtils"/>
3435
<use name="RecoBTag/FeatureTools"/>
3536
<use name="RecoJets/JetAlgorithms"/>
3637
<use name="TrackingTools/Records"/>
+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#include "FWCore/Framework/interface/global/EDProducer.h"
2+
#include "FWCore/Framework/interface/Event.h"
3+
#include "FWCore/ParameterSet/interface/ParameterSet.h"
4+
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
5+
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
6+
#include "DataFormats/NanoAOD/interface/FlatTable.h"
7+
#include "DataFormats/Common/interface/View.h"
8+
#include "DataFormats/Candidate/interface/Candidate.h"
9+
#include "DataFormats/PatCandidates/interface/PackedGenParticle.h"
10+
#include "DataFormats/HepMCCandidate/interface/GenParticle.h"
11+
#include <DataFormats/Math/interface/deltaR.h>
12+
#include "DataFormats/JetReco/interface/GenJetCollection.h"
13+
#include "PhysicsTools/JetMCUtils/interface/CandMCTag.h"
14+
15+
#include <vector>
16+
#include <iostream>
17+
18+
class GenCandMotherTableProducer : public edm::global::EDProducer<> {
19+
public:
20+
GenCandMotherTableProducer(edm::ParameterSet const &params)
21+
: objName_(params.getParameter<std::string>("objName")),
22+
branchName_(params.getParameter<std::string>("branchName")),
23+
src_(consumes<edm::View<pat::PackedGenParticle>>(params.getParameter<edm::InputTag>("src"))),
24+
candMap_(consumes<edm::Association<reco::GenParticleCollection>>(params.getParameter<edm::InputTag>("mcMap"))) {
25+
produces<nanoaod::FlatTable>();
26+
}
27+
28+
~GenCandMotherTableProducer() override {}
29+
30+
void produce(edm::StreamID id, edm::Event &iEvent, const edm::EventSetup &iSetup) const override {
31+
edm::Handle<edm::View<pat::PackedGenParticle>> cands;
32+
iEvent.getByToken(src_, cands);
33+
unsigned int ncand = cands->size();
34+
35+
auto tab = std::make_unique<nanoaod::FlatTable>(ncand, objName_, false, true);
36+
37+
edm::Handle<edm::Association<reco::GenParticleCollection>> map;
38+
iEvent.getByToken(candMap_, map);
39+
40+
std::vector<int> key(ncand, -1), fromB(ncand, 0), fromC(ncand, 0);
41+
for (unsigned int i = 0; i < ncand; ++i) {
42+
reco::GenParticleRef motherRef = cands->at(i).motherRef();
43+
reco::GenParticleRef match = (*map)[motherRef];
44+
45+
if (match.isNull())
46+
continue;
47+
48+
key[i] = match.key();
49+
fromB[i] = isFromB(cands->at(i));
50+
fromC[i] = isFromC(cands->at(i));
51+
}
52+
53+
tab->addColumn<int>(branchName_ + "MotherIdx", key, "Mother index into GenPart list");
54+
tab->addColumn<uint8_t>("isFromB", fromB, "Is from B hadron: no: 0, any: 1, final: 2");
55+
tab->addColumn<uint8_t>("isFromC", fromC, "Is from C hadron: no: 0, any: 1, final: 2");
56+
iEvent.put(std::move(tab));
57+
}
58+
59+
bool isFinalB(const reco::Candidate &particle) const {
60+
if (!CandMCTagUtils::hasBottom(particle))
61+
return false;
62+
63+
// check if any of the daughters is also a b hadron
64+
unsigned int npart = particle.numberOfDaughters();
65+
66+
for (size_t i = 0; i < npart; ++i) {
67+
if (CandMCTagUtils::hasBottom(*particle.daughter(i)))
68+
return false;
69+
}
70+
71+
return true;
72+
}
73+
74+
int isFromB(const reco::Candidate &particle) const {
75+
int fromB = 0;
76+
77+
unsigned int npart = particle.numberOfMothers();
78+
for (size_t i = 0; i < npart; ++i) {
79+
const reco::Candidate &mom = *particle.mother(i);
80+
if (CandMCTagUtils::hasBottom(mom)) {
81+
fromB = isFinalB(mom) ? 2 : 1;
82+
break;
83+
} else
84+
fromB = isFromB(mom);
85+
}
86+
return fromB;
87+
}
88+
89+
bool isFinalC(const reco::Candidate &particle) const {
90+
if (!CandMCTagUtils::hasCharm(particle))
91+
return false;
92+
93+
// check if any of the daughters is also a c hadron
94+
unsigned int npart = particle.numberOfDaughters();
95+
96+
for (size_t i = 0; i < npart; ++i) {
97+
if (CandMCTagUtils::hasCharm(*particle.daughter(i)))
98+
return false;
99+
}
100+
101+
return true;
102+
}
103+
104+
int isFromC(const reco::Candidate &particle) const {
105+
int fromC = 0;
106+
107+
unsigned int npart = particle.numberOfMothers();
108+
for (size_t i = 0; i < npart; ++i) {
109+
const reco::Candidate &mom = *particle.mother(i);
110+
if (CandMCTagUtils::hasCharm(mom)) {
111+
fromC = isFinalC(mom) ? 2 : 1;
112+
break;
113+
} else
114+
fromC = isFromC(mom);
115+
}
116+
return fromC;
117+
}
118+
119+
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
120+
edm::ParameterSetDescription desc;
121+
desc.add<std::string>("objName", "GenCands")
122+
->setComment("name of the nanoaod::FlatTable to extend with this table");
123+
desc.add<std::string>("branchName", "GenPart")
124+
->setComment(
125+
"name of the column to write (the final branch in the nanoaod will be <objName>_<branchName>Idx and "
126+
"<objName>_<branchName>Flav");
127+
desc.add<edm::InputTag>("src", edm::InputTag("packedGenParticles"))
128+
->setComment("collection of the packedGenParticles, with association to prunedGenParticles");
129+
desc.add<edm::InputTag>("mcMap", edm::InputTag("finalGenParticles"))
130+
->setComment(
131+
"tag to an edm::Association<GenParticleCollection> mapping prunedGenParticles to finalGenParticles");
132+
desc.addOptional<edm::InputTag>("genparticles", edm::InputTag("finalGenparticles"))
133+
->setComment("Collection of genParticles to be mapped.");
134+
descriptions.add("genCandMotherTable", desc);
135+
}
136+
137+
protected:
138+
const std::string objName_, branchName_, doc_;
139+
const edm::EDGetTokenT<edm::View<pat::PackedGenParticle>> src_;
140+
const edm::EDGetTokenT<edm::Association<reco::GenParticleCollection>> candMap_;
141+
edm::EDGetTokenT<reco::GenParticleCollection> genPartsToken_;
142+
};
143+
144+
#include "FWCore/Framework/interface/MakerMacros.h"
145+
DEFINE_FWK_MODULE(GenCandMotherTableProducer);

Diff for: PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc

+23-2
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ void JetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm::Even
118118
// PF Cands
119119
std::vector<float> btagEtaRel, btagPtRatio, btagPParRatio, btagSip3dVal, btagSip3dSig, btagJetDistVal,
120120
btagDecayLenVal, cand_pt, cand_dzFromPV, cand_dxyFromPV, cand_dzErrFromPV, cand_dxyErrFromPV;
121+
std::vector<int> cand_jetSVIdx;
121122
// Secondary vertices
122123
std::vector<float> sv_mass, sv_pt, sv_ntracks, sv_chi2, sv_normchi2, sv_dxy, sv_dxysig, sv_d3d, sv_d3dsig,
123124
sv_costhetasvpv;
@@ -146,6 +147,7 @@ void JetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm::Even
146147
std::vector<const reco::VertexCompositePtrCandidate *> allSVs;
147148
for (const auto &sv : *svs_) {
148149
// Factor in cuts in NanoAOD for indexing
150+
// TODO: seems fragile, better use NanoAOD vertexTable instead of slimmedSecondaryVertices as input?
149151
Measurement1D dl = vdist.distance(
150152
vtxs_->front(), VertexState(RecoVertex::convertPos(sv.position()), RecoVertex::convertError(sv.error())));
151153
if (dl.significance() > 3) {
@@ -274,6 +276,23 @@ void JetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm::Even
274276
else
275277
decayLength = -1;
276278
btagDecayLenVal.push_back(decayLength);
279+
// Associate PF candidates to secondary vertices (SVs) by matching their tracks
280+
int jsvMatchIndex = -1;
281+
int jsvIndex = 0;
282+
for (const auto &sv : *outSVs) {
283+
for (const auto &track : sv->daughterPtrVector()) {
284+
double eps = 1e-3;
285+
double dR = deltaR(track->eta(), track->phi(), cand->eta(), cand->phi());
286+
if (dR < eps && abs(track->pt() - cand->pt()) < eps) {
287+
jsvMatchIndex = jsvIndex;
288+
break;
289+
}
290+
}
291+
if (jsvMatchIndex >= 0)
292+
break;
293+
jsvIndex++;
294+
}
295+
cand_jetSVIdx.push_back(jsvMatchIndex);
277296
} else {
278297
btagEtaRel.push_back(0);
279298
btagPtRatio.push_back(0);
@@ -282,6 +301,7 @@ void JetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm::Even
282301
btagSip3dSig.push_back(0);
283302
btagJetDistVal.push_back(0);
284303
btagDecayLenVal.push_back(0);
304+
cand_jetSVIdx.push_back(-1);
285305
}
286306
}
287307
} // end jet loop
@@ -291,8 +311,8 @@ void JetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm::Even
291311
// We fill from here only stuff that cannot be created with the SimpleFlatTableProducer
292312
candTable->addColumn<int>(idx_name_, pfcandIdx, "Index in the candidate list");
293313
candTable->addColumn<int>("jetIdx", jetIdx_pf, "Index of the parent jet");
314+
candTable->addColumn<float>("pt", cand_pt, "pt", 10); // to check matching down the line
294315
if (readBtag_) {
295-
candTable->addColumn<float>("pt", cand_pt, "pt", 10); // to check matchind down the line
296316
candTable->addColumn<float>("dzFromPV", cand_dzFromPV, "dzFromPV", 10);
297317
candTable->addColumn<float>("dxyFromPV", cand_dxyFromPV, "dxyFromPV", 10);
298318
candTable->addColumn<float>("dzErrFromPV", cand_dzErrFromPV, "dzErrFromPV", 10);
@@ -304,6 +324,7 @@ void JetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm::Even
304324
candTable->addColumn<float>("btagSip3dSig", btagSip3dSig, "btagSip3dSig", 10);
305325
candTable->addColumn<float>("btagJetDistVal", btagJetDistVal, "btagJetDistVal", 10);
306326
candTable->addColumn<float>("btagDecayLenVal", btagDecayLenVal, "btagDecayLenVal", 10);
327+
candTable->addColumn<int>("jetSVIdx", cand_jetSVIdx, "Index of the parent in the " + nameSV_ + " list");
307328
}
308329
iEvent.put(std::move(candTable), name_);
309330

@@ -326,7 +347,7 @@ void JetConstituentTableProducer<T>::produce(edm::Event &iEvent, const edm::Even
326347
// Jet related
327348
svTable->addColumn<float>("phirel", sv_phirel, "DeltaPhi(sv, jet)", 10);
328349
svTable->addColumn<float>("ptrel", sv_ptrel, "pT relative to parent jet", 10);
329-
svTable->addColumn<float>("deltaR", sv_deltaR, "dR from parent jet", 10);
350+
svTable->addColumn<float>("deltaR", sv_deltaR, "dR from parent jet - 0.5", 10);
330351
svTable->addColumn<float>("enration", sv_enratio, "energy relative to parent jet", 10);
331352
}
332353
iEvent.put(std::move(svTable), nameSV_);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include "FWCore/Framework/interface/global/EDProducer.h"
2+
#include "FWCore/Framework/interface/Event.h"
3+
#include "FWCore/ParameterSet/interface/ParameterSet.h"
4+
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
5+
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
6+
#include "DataFormats/NanoAOD/interface/FlatTable.h"
7+
#include "DataFormats/Common/interface/View.h"
8+
#include "DataFormats/Candidate/interface/Candidate.h"
9+
#include "DataFormats/PatCandidates/interface/PackedGenParticle.h"
10+
#include <DataFormats/Math/interface/deltaR.h>
11+
#include "DataFormats/JetReco/interface/GenJetCollection.h"
12+
13+
#include <vector>
14+
#include <iostream>
15+
16+
class PackedCandMCMatchTableProducer : public edm::global::EDProducer<> {
17+
public:
18+
PackedCandMCMatchTableProducer(edm::ParameterSet const& params)
19+
: objName_(params.getParameter<std::string>("objName")),
20+
branchName_(params.getParameter<std::string>("branchName")),
21+
doc_(params.getParameter<std::string>("docString")),
22+
src_(consumes<reco::CandidateView>(params.getParameter<edm::InputTag>("src"))),
23+
genPartsToken_(
24+
consumes<edm::View<pat::PackedGenParticle>>(params.getParameter<edm::InputTag>("genparticles"))) {
25+
produces<nanoaod::FlatTable>();
26+
}
27+
28+
~PackedCandMCMatchTableProducer() override {}
29+
30+
void produce(edm::StreamID id, edm::Event& iEvent, const edm::EventSetup& iSetup) const override {
31+
edm::Handle<reco::CandidateView> cands;
32+
iEvent.getByToken(src_, cands);
33+
unsigned int ncand = cands->size();
34+
35+
auto tab = std::make_unique<nanoaod::FlatTable>(ncand, objName_, false, true);
36+
37+
edm::Handle<edm::View<pat::PackedGenParticle>> genParts;
38+
iEvent.getByToken(genPartsToken_, genParts);
39+
40+
std::vector<int> key(ncand, -1), flav(ncand, 0);
41+
for (unsigned int i = 0; i < ncand; ++i) {
42+
auto cand = cands->ptrAt(i);
43+
44+
auto iter = std::find_if(genParts->begin(), genParts->end(), [cand](pat::PackedGenParticle genp) {
45+
return (genp.charge() == cand->charge()) && (deltaR(genp.eta(), genp.phi(), cand->eta(), cand->phi()) < 0.02) &&
46+
(abs(genp.pt() - cand->pt()) / cand->pt() < 0.2);
47+
});
48+
if (iter != genParts->end()) {
49+
key[i] = iter - genParts->begin();
50+
}
51+
}
52+
tab->addColumn<int>(branchName_ + "Idx", key, "Index into GenCands list for " + doc_);
53+
iEvent.put(std::move(tab));
54+
}
55+
56+
static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
57+
edm::ParameterSetDescription desc;
58+
desc.add<std::string>("objName")->setComment("name of the nanoaod::FlatTable to extend with this table");
59+
desc.add<std::string>("branchName")
60+
->setComment(
61+
"name of the column to write (the final branch in the nanoaod will be <objName>_<branchName>Idx and "
62+
"<objName>_<branchName>Flav");
63+
desc.add<std::string>("docString")->setComment("documentation to forward to the output");
64+
desc.add<edm::InputTag>("src")->setComment(
65+
"physics object collection for the reconstructed objects (e.g. leptons)");
66+
desc.addOptional<edm::InputTag>("genparticles")->setComment("Collection of genParticles to be stored.");
67+
descriptions.add("packedCandMcMatchTable", desc);
68+
}
69+
70+
protected:
71+
const std::string objName_, branchName_, doc_;
72+
const edm::EDGetTokenT<reco::CandidateView> src_;
73+
edm::EDGetTokenT<edm::View<pat::PackedGenParticle>> genPartsToken_;
74+
};
75+
76+
#include "FWCore/Framework/interface/MakerMacros.h"
77+
DEFINE_FWK_MODULE(PackedCandMCMatchTableProducer);

0 commit comments

Comments
 (0)