File indexing completed on 2024-07-03 04:17:53
0001 #include <memory>
0002
0003 #include "MergedGenParticleProducer.hh"
0004
0005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0006
0007 #include "FWCore/Utilities/interface/InputTag.h"
0008 #include "DataFormats/Common/interface/Handle.h"
0009 #include "DataFormats/Common/interface/View.h"
0010
0011 #include "HepPDT/ParticleID.hh"
0012
0013 MergedGenParticleProducer::MergedGenParticleProducer(const edm::ParameterSet& config) {
0014 input_pruned_ = consumes<edm::View<reco::GenParticle>>(config.getParameter<edm::InputTag>("inputPruned"));
0015 input_packed_ = consumes<edm::View<pat::PackedGenParticle>>(config.getParameter<edm::InputTag>("inputPacked"));
0016
0017 produces<reco::GenParticleCollection>();
0018 }
0019
0020 void MergedGenParticleProducer::produce(edm::Event& event, const edm::EventSetup& setup) {
0021
0022 auto ref = event.getRefBeforePut<reco::GenParticleCollection>();
0023
0024
0025 edm::Handle<edm::View<reco::GenParticle>> pruned_handle;
0026 event.getByToken(input_pruned_, pruned_handle);
0027
0028 edm::Handle<edm::View<pat::PackedGenParticle>> packed_handle;
0029 event.getByToken(input_packed_, packed_handle);
0030
0031
0032
0033 std::map<pat::PackedGenParticle const*, reco::GenParticle const*> st1_dup_map;
0034
0035
0036
0037 std::map<reco::Candidate const*, std::size_t> pruned_idx_map;
0038
0039 unsigned int nLeptonsFromPrunedPhoton = 0;
0040
0041 for (unsigned int i = 0, idx = 0; i < pruned_handle->size(); ++i) {
0042 reco::GenParticle const& src = pruned_handle->at(i);
0043 pruned_idx_map[&src] = idx;
0044 ++idx;
0045
0046
0047 if (isLeptonFromPrunedPhoton(src)) {
0048 ++nLeptonsFromPrunedPhoton;
0049 ++idx;
0050 }
0051
0052 if (src.status() != 1)
0053 continue;
0054
0055
0056
0057
0058
0059
0060 pat::PackedGenParticle pks(src, reco::GenParticleRef());
0061 unsigned found_matches = 0;
0062 for (unsigned j = 0; j < packed_handle->size(); ++j) {
0063 pat::PackedGenParticle const& pk = packed_handle->at(j);
0064 if (pks.pdgId() != pk.pdgId() or pks.p4() != pk.p4())
0065 continue;
0066 ++found_matches;
0067 st1_dup_map[&pk] = &src;
0068 }
0069 if (found_matches > 1) {
0070 edm::LogWarning("MergedGenParticleProducer") << "Found multiple packed matches for: " << i << "\t" << src.pdgId()
0071 << "\t" << src.pt() << "\t" << src.y() << "\n";
0072 } else if (found_matches == 0 && std::abs(src.y()) < 6.0) {
0073 edm::LogWarning("MergedGenParticleProducer")
0074 << "unmatched status 1: " << i << "\t" << src.pdgId() << "\t" << src.pt() << "\t" << src.y() << "\n";
0075 }
0076 }
0077
0078
0079 unsigned int nPhotonsFromPrunedHadron = 0;
0080 for (unsigned int j = 0; j < packed_handle->size(); ++j) {
0081 pat::PackedGenParticle const& pk = packed_handle->at(j);
0082 if (isPhotonFromPrunedHadron(pk))
0083 ++nPhotonsFromPrunedHadron;
0084 }
0085
0086
0087 const unsigned int n = pruned_handle->size() + (packed_handle->size() - st1_dup_map.size()) +
0088 nPhotonsFromPrunedHadron + nLeptonsFromPrunedPhoton;
0089 auto cands = std::make_unique<reco::GenParticleCollection>(n);
0090
0091
0092 unsigned idx = 0;
0093 for (unsigned i = 0; i < pruned_handle->size(); ++i) {
0094 reco::GenParticle const& old_cand = pruned_handle->at(i);
0095 reco::GenParticle& new_cand = cands->at(idx);
0096 new_cand = reco::GenParticle(pruned_handle->at(i));
0097
0098 new_cand.resetMothers(ref.id());
0099 new_cand.resetDaughters(ref.id());
0100
0101 if (isLeptonFromPrunedPhoton(old_cand)) {
0102 ++idx;
0103 reco::GenParticle& dummy_mother = cands->at(idx);
0104 dummy_mother = reco::GenParticle(0, old_cand.p4() * 1e-20, old_cand.vertex(), 22, 2, true);
0105 dummy_mother.addDaughter(reco::GenParticleRef(ref, idx - 1));
0106 new_cand.clearMothers();
0107 new_cand.addMother(reco::GenParticleRef(ref, idx));
0108
0109 for (unsigned m = 0; m < old_cand.numberOfMothers(); ++m) {
0110 dummy_mother.addMother(reco::GenParticleRef(ref, pruned_idx_map.at(old_cand.mother(m))));
0111 unsigned int midx = pruned_idx_map.at(old_cand.mother(m));
0112 if (midx < idx) {
0113 reco::GenParticle& mother = cands->at(midx);
0114 mother.addDaughter(reco::GenParticleRef(ref, idx));
0115 } else {
0116 edm::LogWarning("MergedGenParticleProducer")
0117 << "Cannot assign to dummy photon with index " << idx
0118 << " as daughter to unprocessed particle with index " << idx << "\n";
0119 }
0120 }
0121 } else {
0122 for (unsigned m = 0; m < old_cand.numberOfMothers(); ++m) {
0123 new_cand.addMother(reco::GenParticleRef(ref, pruned_idx_map.at(old_cand.mother(m))));
0124 }
0125 }
0126 for (unsigned d = 0; d < old_cand.numberOfDaughters(); ++d) {
0127 new_cand.addDaughter(reco::GenParticleRef(ref, pruned_idx_map.at(old_cand.daughter(d))));
0128 }
0129 ++idx;
0130 }
0131
0132
0133 for (unsigned i = 0; i < packed_handle->size(); ++i) {
0134 pat::PackedGenParticle const& pk = packed_handle->at(i);
0135 if (st1_dup_map.count(&pk))
0136 continue;
0137 reco::GenParticle& new_cand = cands->at(idx);
0138 new_cand = reco::GenParticle(pk.charge(), pk.p4(), pk.vertex(), pk.pdgId(), 1, true);
0139
0140
0141 if (isPhotonFromPrunedHadron(pk)) {
0142 ++idx;
0143 reco::GenParticle& dummy_mother = cands->at(idx);
0144 dummy_mother = reco::GenParticle(0, pk.p4(), pk.vertex(), 111, 2, true);
0145 for (unsigned m = 0; m < pk.numberOfMothers(); ++m) {
0146 new_cand.addMother(reco::GenParticleRef(ref, idx));
0147
0148 if (m == 0) {
0149 dummy_mother.setP4(pk.mother(m)->p4());
0150 dummy_mother.setVertex(pk.mother(m)->vertex());
0151 new_cand.setVertex(pk.mother(m)->vertex());
0152 }
0153
0154 dummy_mother.addDaughter(reco::GenParticleRef(ref, idx - 1));
0155 }
0156 }
0157
0158 reco::GenParticle& daughter = cands->at(idx);
0159 for (unsigned m = 0; m < pk.numberOfMothers(); ++m) {
0160 daughter.addMother(reco::GenParticleRef(ref, pruned_idx_map.at(pk.mother(m))));
0161
0162 if (m == 0) {
0163 daughter.setVertex(pk.mother(m)->vertex());
0164 }
0165
0166 cands->at(pruned_idx_map.at(pk.mother(m))).addDaughter(reco::GenParticleRef(ref, idx));
0167 }
0168 ++idx;
0169 }
0170
0171 event.put(std::move(cands));
0172 }
0173
0174 bool MergedGenParticleProducer::isPhotonFromPrunedHadron(const pat::PackedGenParticle& pk) const {
0175 if (pk.pdgId() == 22 and pk.statusFlags().isDirectHadronDecayProduct()) {
0176
0177 if (pk.numberOfMothers() == 0)
0178 return true;
0179
0180 HepPDT::ParticleID motherid(pk.mother(0)->pdgId());
0181 if (not(motherid.isHadron() and pk.mother(0)->status() == 2))
0182 return true;
0183 }
0184 return false;
0185 }
0186
0187 bool MergedGenParticleProducer::isLeptonFromPrunedPhoton(const reco::GenParticle& pk) const {
0188 if ((abs(pk.pdgId()) == 11 or abs(pk.pdgId()) == 13) and
0189 not(pk.statusFlags().fromHardProcess() or pk.statusFlags().isDirectTauDecayProduct())) {
0190
0191 if (pk.numberOfMothers() > 0 and pk.mother(0)->pdgId() != 22) {
0192 return true;
0193 }
0194 }
0195 return false;
0196 }
0197
0198 #include "FWCore/Framework/interface/MakerMacros.h"
0199 DEFINE_FWK_MODULE(MergedGenParticleProducer);