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

Enable boosted tau reco to run at miniAOD #34576

Merged
Merged
62 changes: 62 additions & 0 deletions PhysicsTools/PatAlgos/python/tools/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,3 +433,65 @@ def testListModules(self):
self.assertEqual([p.a,p.b,p.c], listModules(p.s))

unittest.main()

class CloneTaskVisitor(object):
"""Visitor that travels within a cms.Task, and returns a cloned version of the Task.
All modules are cloned and a postfix is added"""
def __init__(self, process, label, postfix, removePostfix="", noClones = [], verbose = False):
self._process = process
self._postfix = postfix
self._removePostfix = removePostfix
self._noClones = noClones
self._verbose = verbose
self._moduleLabels = []
self._clonedTask = cms.Task()
setattr(process, self._newLabel(label), self._clonedTask)

def enter(self, visitee):
if isinstance(visitee, cms._Module):
label = visitee.label()
newModule = None
if label in self._noClones: #keep unchanged
newModule = getattr(self._process, label)
elif label in self._moduleLabels: # has the module already been cloned ?
newModule = getattr(self._process, self._newLabel(label))
else:
self._moduleLabels.append(label)
newModule = visitee.clone()
setattr(self._process, self._newLabel(label), newModule)
self.__appendToTopTask(newModule)

def leave(self, visitee):
pass

def clonedTask(self):#FIXME: can the following be used for Task?
for label in self._moduleLabels:
massSearchReplaceAnyInputTag(self._clonedTask, label, self._newLabel(label), moduleLabelOnly=True, verbose=self._verbose)
self._moduleLabels = [] # prevent the InputTag replacement next time the 'clonedTask' function is called.
return self._clonedTask

def _newLabel(self, label):
if self._removePostfix != "":
if label[-len(self._removePostfix):] == self._removePostfix:
label = label[0:-len(self._removePostfix)]
else:
raise Exception("Tried to remove postfix %s from label %s, but it wasn't there" % (self._removePostfix, label))
return label + self._postfix

def __appendToTopTask(self, visitee):
self._clonedTask.add(visitee)

def cloneProcessingSnippetTask(process, task, postfix, removePostfix="", noClones = [], verbose = False):
"""
------------------------------------------------------------------
copy a task plus the modules therein (including modules in subtasks)
both are renamed by getting a postfix
input tags are automatically adjusted
------------------------------------------------------------------
"""
result = task
if not postfix == "":
visitor = CloneTaskVisitor(process, task.label(), postfix, removePostfix, noClones, verbose)
task.visit(visitor)
result = visitor.clonedTask()
return result
92 changes: 52 additions & 40 deletions RecoJets/JetProducers/plugins/BoostedTauSeedsProducer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include "DataFormats/JetReco/interface/PFJetCollection.h"
#include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
#include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
#include "DataFormats/PatCandidates/interface/Jet.h"
#include "DataFormats/PatCandidates/interface/PackedCandidate.h"
#include "DataFormats/Common/interface/AssociationMap.h"
#include "DataFormats/Common/interface/Ref.h"
#include "DataFormats/Common/interface/RefProd.h"
Expand All @@ -40,41 +42,46 @@
#include <iostream>
#include <iomanip>

class BoostedTauSeedsProducer : public edm::stream::EDProducer<> {
template <class JetType, class CandType>
class GenericBoostedTauSeedsProducer : public edm::stream::EDProducer<> {
public:
explicit BoostedTauSeedsProducer(const edm::ParameterSet&);
~BoostedTauSeedsProducer() override {}
explicit GenericBoostedTauSeedsProducer(const edm::ParameterSet&);
~GenericBoostedTauSeedsProducer() override {}
void produce(edm::Event&, const edm::EventSetup&) override;

private:
typedef edm::AssociationMap<edm::OneToMany<std::vector<reco::PFJet>, std::vector<reco::PFCandidate>, unsigned int> >
typedef edm::AssociationMap<edm::OneToMany<std::vector<JetType>, std::vector<CandType>, unsigned int>>
JetToPFCandidateAssociation;
typedef std::vector<JetType> JetTypeCollection;
typedef std::vector<CandType> CandTypeCollection;

std::string moduleLabel_;

typedef edm::View<reco::Jet> JetView;
edm::EDGetTokenT<JetView> srcSubjets_;
edm::EDGetTokenT<reco::PFCandidateCollection> srcPFCandidates_;
edm::EDGetTokenT<CandTypeCollection> srcPFCandidates_;

int verbosity_;
};

BoostedTauSeedsProducer::BoostedTauSeedsProducer(const edm::ParameterSet& cfg)
template <class JetType, class CandType>
GenericBoostedTauSeedsProducer<JetType, CandType>::GenericBoostedTauSeedsProducer(const edm::ParameterSet& cfg)
: moduleLabel_(cfg.getParameter<std::string>("@module_label")) {
srcSubjets_ = consumes<JetView>(cfg.getParameter<edm::InputTag>("subjetSrc"));
srcPFCandidates_ = consumes<reco::PFCandidateCollection>(cfg.getParameter<edm::InputTag>("pfCandidateSrc"));
srcPFCandidates_ = consumes<CandTypeCollection>(cfg.getParameter<edm::InputTag>("pfCandidateSrc"));

verbosity_ = (cfg.exists("verbosity")) ? cfg.getParameter<int>("verbosity") : 0;

produces<reco::PFJetCollection>();
produces<JetTypeCollection>();
produces<JetToPFCandidateAssociation>("pfCandAssocMapForIsolation");
//produces<JetToPFCandidateAssociation>("pfCandAssocMapForIsoDepositVetos");
}

namespace {
typedef std::vector<std::unordered_set<uint32_t> > JetToConstitMap;
typedef std::vector<std::unordered_set<uint32_t>> JetToConstitMap;

reco::PFJet convertToPFJet(const reco::Jet& jet, const reco::Jet::Constituents& jetConstituents) {
template <class JetType, class CandType>
JetType convertToPFJet(const reco::Jet& jet, const reco::Jet::Constituents& jetConstituents) {
// CV: code for filling pfJetSpecific objects taken from
// RecoParticleFlow/PFRootEvent/src/JetMaker.cc
double chargedHadronEnergy = 0.;
Expand All @@ -86,37 +93,36 @@ namespace {
int neutralMultiplicity = 0;
int muonMultiplicity = 0;
for (auto const& jetConstituent : jetConstituents) {
const reco::PFCandidate* pfCandidate = dynamic_cast<const reco::PFCandidate*>(jetConstituent.get());
const CandType* pfCandidate = dynamic_cast<const CandType*>(jetConstituent.get());
if (pfCandidate) {
switch (pfCandidate->particleId()) {
case reco::PFCandidate::h: // charged hadron
switch (std::abs(pfCandidate->pdgId())) {
case 211: // charged hadron
chargedHadronEnergy += pfCandidate->energy();
++chargedMultiplicity;
break;
case reco::PFCandidate::e: // electron
case 11: // electron
chargedEmEnergy += pfCandidate->energy();
++chargedMultiplicity;
break;
case reco::PFCandidate::mu: // muon
case 13: // muon
chargedMuEnergy += pfCandidate->energy();
++chargedMultiplicity;
++muonMultiplicity;
break;
case reco::PFCandidate::gamma: // photon
case reco::PFCandidate::egamma_HF: // electromagnetic in HF
case 22: // photon
case 2: // electromagnetic in HF
neutralEmEnergy += pfCandidate->energy();
++neutralMultiplicity;
break;
case reco::PFCandidate::h0: // neutral hadron
case reco::PFCandidate::h_HF: // hadron in HF
case 130: // neutral hadron
case 1: // hadron in HF
neutralHadronEnergy += pfCandidate->energy();
++neutralMultiplicity;
break;
default:
edm::LogWarning("convertToPFJet")
<< "PFCandidate: Pt = " << pfCandidate->pt() << ", eta = " << pfCandidate->eta()
<< ", phi = " << pfCandidate->phi() << " has invalid particleID = " << pfCandidate->particleId()
<< " !!" << std::endl;
edm::LogWarning("convertToPFJet") << "PFCandidate: Pt = " << pfCandidate->pt()
<< ", eta = " << pfCandidate->eta() << ", phi = " << pfCandidate->phi()
<< " has invalid pdgID = " << pfCandidate->pdgId() << " !!" << std::endl;
break;
}
} else {
Expand All @@ -138,7 +144,7 @@ namespace {
reco::PFJet pfJet(jet.p4(), jet.vertex(), pfJetSpecific, jetConstituents);
pfJet.setJetArea(jet.jetArea());

return pfJet;
return JetType(pfJet);
}

void getJetConstituents(const reco::Jet& jet, reco::Jet::Constituents& jet_and_subjetConstituents) {
Expand All @@ -153,20 +159,21 @@ namespace {
}
}

std::vector<reco::PFCandidateRef> getPFCandidates_exclJetConstituents(
template <class CandType>
std::vector<edm::Ref<std::vector<CandType>>> getPFCandidates_exclJetConstituents(
const reco::Jet& jet,
const edm::Handle<reco::PFCandidateCollection>& pfCandidates,
const edm::Handle<std::vector<CandType>>& pfCandidates,
const JetToConstitMap::value_type& constitmap,
bool invert) {
auto const& collection_cand = (*pfCandidates);
std::vector<reco::PFCandidateRef> pfCandidates_exclJetConstituents;
std::vector<edm::Ref<std::vector<CandType>>> pfCandidates_exclJetConstituents;
size_t numPFCandidates = pfCandidates->size();
for (size_t pfCandidateIdx = 0; pfCandidateIdx < numPFCandidates; ++pfCandidateIdx) {
if (!(deltaR2(collection_cand[pfCandidateIdx], jet) < 1.0))
continue;
bool isJetConstituent = constitmap.count(pfCandidateIdx);
if (!(isJetConstituent ^ invert)) {
reco::PFCandidateRef pfCandidate(pfCandidates, pfCandidateIdx);
edm::Ref<std::vector<CandType>> pfCandidate(pfCandidates, pfCandidateIdx);
pfCandidates_exclJetConstituents.push_back(pfCandidate);
}
}
Expand All @@ -184,7 +191,8 @@ namespace {
}
} // namespace

void BoostedTauSeedsProducer::produce(edm::Event& evt, const edm::EventSetup& es) {
template <class JetType, class CandType>
void GenericBoostedTauSeedsProducer<JetType, CandType>::produce(edm::Event& evt, const edm::EventSetup& es) {
if (verbosity_ >= 1) {
std::cout << "<BoostedTauSeedsProducer::produce (moduleLabel = " << moduleLabel_ << ")>:" << std::endl;
}
Expand All @@ -196,14 +204,14 @@ void BoostedTauSeedsProducer::produce(edm::Event& evt, const edm::EventSetup& es
}
assert((subjets->size() % 2) == 0); // CV: ensure that subjets come in pairs

edm::Handle<reco::PFCandidateCollection> pfCandidates;
edm::Handle<CandTypeCollection> pfCandidates;
evt.getByToken(srcPFCandidates_, pfCandidates);
if (verbosity_ >= 1) {
std::cout << "#pfCandidates = " << pfCandidates->size() << std::endl;
}

auto selectedSubjets = std::make_unique<reco::PFJetCollection>();
edm::RefProd<reco::PFJetCollection> selectedSubjetRefProd = evt.getRefBeforePut<reco::PFJetCollection>();
auto selectedSubjets = std::make_unique<JetTypeCollection>();
edm::RefProd<JetTypeCollection> selectedSubjetRefProd = evt.getRefBeforePut<JetTypeCollection>();

auto selectedSubjetPFCandidateAssociationForIsolation =
std::make_unique<JetToPFCandidateAssociation>(&evt.productGetter());
Expand Down Expand Up @@ -247,16 +255,16 @@ void BoostedTauSeedsProducer::produce(edm::Event& evt, const edm::EventSetup& es
printJetConstituents("subjetConstituents2", subjetConstituents2);
}

selectedSubjets->push_back(convertToPFJet(*subjet1, subjetConstituents1));
edm::Ref<reco::PFJetCollection> subjetRef1(selectedSubjetRefProd, selectedSubjets->size() - 1);
selectedSubjets->push_back(convertToPFJet(*subjet2, subjetConstituents2));
edm::Ref<reco::PFJetCollection> subjetRef2(selectedSubjetRefProd, selectedSubjets->size() - 1);
selectedSubjets->push_back(convertToPFJet<JetType, CandType>(*subjet1, subjetConstituents1));
edm::Ref<JetTypeCollection> subjetRef1(selectedSubjetRefProd, selectedSubjets->size() - 1);
selectedSubjets->push_back(convertToPFJet<JetType, CandType>(*subjet2, subjetConstituents2));
edm::Ref<JetTypeCollection> subjetRef2(selectedSubjetRefProd, selectedSubjets->size() - 1);

// find all PFCandidates that are not constituents of the **other** subjet
std::vector<reco::PFCandidateRef> pfCandidatesNotInSubjet1 =
getPFCandidates_exclJetConstituents(*subjet1, pfCandidates, constitmap[2 * idx + 1], false);
std::vector<reco::PFCandidateRef> pfCandidatesNotInSubjet2 =
getPFCandidates_exclJetConstituents(*subjet2, pfCandidates, constitmap[2 * idx], false);
std::vector<edm::Ref<std::vector<CandType>>> pfCandidatesNotInSubjet1 =
getPFCandidates_exclJetConstituents<CandType>(*subjet1, pfCandidates, constitmap[2 * idx + 1], false);
std::vector<edm::Ref<std::vector<CandType>>> pfCandidatesNotInSubjet2 =
getPFCandidates_exclJetConstituents<CandType>(*subjet2, pfCandidates, constitmap[2 * idx], false);
if (verbosity_ >= 1) {
std::cout << "#pfCandidatesNotInSubjet1 = " << pfCandidatesNotInSubjet1.size() << std::endl;
std::cout << "#pfCandidatesNotInSubjet2 = " << pfCandidatesNotInSubjet2.size() << std::endl;
Expand All @@ -276,5 +284,9 @@ void BoostedTauSeedsProducer::produce(edm::Event& evt, const edm::EventSetup& es
evt.put(std::move(selectedSubjetPFCandidateAssociationForIsolation), "pfCandAssocMapForIsolation");
}

typedef GenericBoostedTauSeedsProducer<reco::PFJet, reco::PFCandidate> BoostedTauSeedsProducer;
typedef GenericBoostedTauSeedsProducer<pat::Jet, pat::PackedCandidate> PATBoostedTauSeedsProducer;

#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(BoostedTauSeedsProducer);
DEFINE_FWK_MODULE(PATBoostedTauSeedsProducer);
Loading