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

[124X backport] Keep Run2 EGamma IDs in Run3 nano(v10) #38871

Merged
merged 3 commits into from Aug 5, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 43 additions & 7 deletions PhysicsTools/NanoAOD/plugins/VIDNestedWPBitmapProducer.cc
Expand Up @@ -33,16 +33,46 @@
#include "DataFormats/PatCandidates/interface/Photon.h"

#include "DataFormats/PatCandidates/interface/VIDCutFlowResult.h"
#include "DataFormats/Common/interface/Ptr.h"

//
// class declaration
//

namespace {

//will fail for non-electrons/photons (which so far are not used for this class)
//when we want to use non-electrons/photons, template specalisation will be necessary
template <typename T>
bool equal(const T& lhs, const T& rhs) {
return lhs.superCluster()->seed()->seed().rawId() == rhs.superCluster()->seed()->seed().rawId();
}

//returns a edm::Ptr to the object matching the passed in object in object coll
//if objColl is invalid, passes the original pointer back
//if valid but not found, returns null
template <typename T>
edm::Ptr<T> getObjInColl(edm::Ptr<T> obj, edm::Handle<edm::View<T>> objColl) {
if (objColl.isValid()) {
for (auto& objToMatch : objColl->ptrs()) {
if (equal(*obj, *objToMatch)) {
return objToMatch;
}
}
return edm::Ptr<T>(objColl.id());
}
return obj;
}

} // namespace

template <typename T>
class VIDNestedWPBitmapProducer : public edm::stream::EDProducer<> {
public:
explicit VIDNestedWPBitmapProducer(const edm::ParameterSet& iConfig)
: src_(consumes<edm::View<T>>(iConfig.getParameter<edm::InputTag>("src"))), isInit_(false) {
: src_(consumes<edm::View<T>>(iConfig.getParameter<edm::InputTag>("src"))),
srcForIDToken_(consumes<edm::View<T>>(iConfig.getParameter<edm::InputTag>("srcForID"))),
isInit_(false) {
auto const& vwp = iConfig.getParameter<std::vector<std::string>>("WorkingPoints");
for (auto const& wp : vwp) {
src_bitmaps_.push_back(consumes<edm::ValueMap<unsigned int>>(edm::InputTag(wp + std::string("Bitmap"))));
Expand All @@ -60,6 +90,7 @@ class VIDNestedWPBitmapProducer : public edm::stream::EDProducer<> {
// ----------member data ---------------------------

edm::EDGetTokenT<edm::View<T>> src_;
edm::EDGetTokenT<edm::View<T>> srcForIDToken_;
std::vector<edm::EDGetTokenT<edm::ValueMap<unsigned int>>> src_bitmaps_;
std::vector<edm::EDGetTokenT<edm::ValueMap<vid::CutFlowResult>>> src_cutflows_;

Expand All @@ -76,6 +107,9 @@ template <typename T>
void VIDNestedWPBitmapProducer<T>::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
edm::Handle<edm::View<T>> src;
iEvent.getByToken(src_, src);

auto srcForIDHandle = iEvent.getHandle(srcForIDToken_);

std::vector<edm::Handle<edm::ValueMap<unsigned int>>> src_bitmaps(nWP);
for (unsigned int i = 0; i < nWP; i++)
iEvent.getByToken(src_bitmaps_[i], src_bitmaps[i]);
Expand All @@ -86,13 +120,14 @@ void VIDNestedWPBitmapProducer<T>::produce(edm::Event& iEvent, const edm::EventS
std::vector<unsigned int> res;

for (auto const& obj : src->ptrs()) {
auto objForID = getObjInColl(obj, srcForIDHandle);
for (unsigned int j = 0; j < nWP; j++) {
auto cutflow = (*(src_cutflows[j]))[obj];
auto cutflow = (*(src_cutflows[j]))[objForID];
if (!isInit_)
initNCuts(cutflow.cutFlowSize());
if (cutflow.cutFlowSize() != nCuts)
throw cms::Exception("Configuration", "Trying to compress VID bitmaps for cutflows of different size");
auto bitmap = (*(src_bitmaps[j]))[obj];
auto bitmap = (*(src_bitmaps[j]))[objForID];
for (unsigned int k = 0; k < nCuts; k++) {
if (j == 0)
res_[k] = 0;
Expand Down Expand Up @@ -135,18 +170,19 @@ template <typename T>
void VIDNestedWPBitmapProducer<T>::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.add<edm::InputTag>("src")->setComment("input physics object collection");
desc.add<edm::InputTag>("srcForID", edm::InputTag())->setComment("physics object collection the ID value maps are ");
desc.add<std::vector<std::string>>("WorkingPoints")->setComment("working points to be saved in the bitmask");
std::string modname;
if (typeid(T) == typeid(pat::Electron))
if (typeid(T) == typeid(reco::GsfElectron))
modname += "Ele";
else if (typeid(T) == typeid(pat::Photon))
else if (typeid(T) == typeid(reco::Photon))
modname += "Pho";
modname += "VIDNestedWPBitmapProducer";
descriptions.add(modname, desc);
}

typedef VIDNestedWPBitmapProducer<pat::Electron> EleVIDNestedWPBitmapProducer;
typedef VIDNestedWPBitmapProducer<pat::Photon> PhoVIDNestedWPBitmapProducer;
typedef VIDNestedWPBitmapProducer<reco::GsfElectron> EleVIDNestedWPBitmapProducer;
typedef VIDNestedWPBitmapProducer<reco::Photon> PhoVIDNestedWPBitmapProducer;

//define this as a plug-in
DEFINE_FWK_MODULE(EleVIDNestedWPBitmapProducer);
Expand Down
36 changes: 2 additions & 34 deletions PhysicsTools/NanoAOD/python/electrons_cff.py
Expand Up @@ -94,6 +94,7 @@ def _get_bitmapVIDForEle_docstring(modules,WorkingPoints):

bitmapVIDForEle = cms.EDProducer("EleVIDNestedWPBitmapProducer",
src = cms.InputTag("slimmedElectrons"),
srcForID = cms.InputTag("reducedEgamma","reducedGedGsfElectrons"),
WorkingPoints = electron_id_modules_WorkingPoints_nanoAOD.WorkingPoints,
)
_bitmapVIDForEle_docstring = _get_bitmapVIDForEle_docstring(electron_id_modules_WorkingPoints_nanoAOD.modules,bitmapVIDForEle.WorkingPoints)
Expand Down Expand Up @@ -194,6 +195,7 @@ def _get_bitmapVIDForEle_docstring(modules,WorkingPoints):
##import from PhysicsTools/PatAlgos/python/electronsWithUserData_cfi.py
slimmedElectronsWithUserData = cms.EDProducer("PATElectronUserDataEmbedder",
src = cms.InputTag("slimmedElectrons"),
parentSrcs = cms.VInputTag("reducedEgamma:reducedGedGsfElectrons"),
userFloats = cms.PSet(
mvaFall17V1Iso = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17IsoV1Values"),
mvaFall17V1noIso = cms.InputTag("electronMVAValueMapProducer:ElectronMVAEstimatorRun2Fall17NoIsoV1Values"),
Expand Down Expand Up @@ -541,40 +543,6 @@ def _get_bitmapVIDForEle_docstring(modules,WorkingPoints):
electronTablesTask = cms.Task(electronMVATTH, electronTable)
electronMCTask = cms.Task(tautaggerForMatching, matchingElecPhoton, electronsMCMatchForTable, electronsMCMatchForTableAlt, electronMCTable)

## TEMPORARY as no ID for Run3 yet
(run3_nanoAOD_devel).toReplaceWith(electronTask, electronTask.copyAndExclude([bitmapVIDForEle,bitmapVIDForEleHEEP]))
(run3_nanoAOD_devel).toModify(slimmedElectronsWithUserData, userIntFromBools = cms.PSet())
(run3_nanoAOD_devel).toModify(slimmedElectronsWithUserData.userInts,
VIDNestedWPBitmap = None,
VIDNestedWPBitmapHEEP = None)
(run3_nanoAOD_devel).toModify(slimmedElectronsWithUserData.userFloats,
mvaFall17V1Iso = None,
mvaFall17V1noIso = None,
mvaIso = None,
mvaNoIso = None,
mvaHZZIso = None,
)
(run3_nanoAOD_devel).toModify(electronTable.variables,
mvaIso = None,
mvaIso_WP80 = None,
mvaIso_WP90 = None,
mvaIso_WPL = None,
mvaNoIso = None,
mvaNoIso_WP80 = None,
mvaNoIso_WP90 = None,
mvaNoIso_WPL = None,
vidNestedWPBitmapHEEP = None,
vidNestedWPBitmap = None,
cutBased = None,
cutBased_HEEP = None,
mvaHZZIso = None,
)

(run3_nanoAOD_devel).toReplaceWith(electronTablesTask, electronTablesTask.copyAndExclude([electronMVATTH]))
(run3_nanoAOD_devel).toModify(electronTable, externalVariables = cms.PSet(fsrPhotonIdx = ExtVar(cms.InputTag("leptonFSRphotons:eleFsrIndex"),int, doc="Index of the lowest-dR/ET2 among associated FSR photons")),
)
##### end TEMPORARY Run3

# Revert back to AK4 CHS jets for Run 2
run2_nanoAOD_ANY.toModify(ptRatioRelForEle,srcJet="updatedJets")

Expand Down
3 changes: 0 additions & 3 deletions PhysicsTools/NanoAOD/python/nanoDQM_cff.py
Expand Up @@ -137,9 +137,6 @@
verboseQT = cms.untracked.bool(True)
)

(run3_nanoAOD_devel).toModify(nanoDQM.vplots, Electron = None)
(run3_nanoAOD_devel).toModify(nanoDQMMC.vplots, Electron = None)

_modifiers = ( run2_miniAOD_80XLegacy |
run2_nanoAOD_94XMiniAODv1 |
run2_nanoAOD_94XMiniAODv2 |
Expand Down
18 changes: 2 additions & 16 deletions PhysicsTools/NanoAOD/python/photons_cff.py
Expand Up @@ -45,6 +45,7 @@ def make_bitmapVID_docstring(id_modules_working_points_pset):

bitmapVIDForPho = cms.EDProducer("PhoVIDNestedWPBitmapProducer",
src = cms.InputTag("slimmedPhotons"),
srcForID = cms.InputTag("reducedEgamma","reducedGedPhotons"),
WorkingPoints = photon_id_modules_WorkingPoints_nanoAOD.WorkingPoints,
)

Expand Down Expand Up @@ -116,6 +117,7 @@ def make_bitmapVID_docstring(id_modules_working_points_pset):

slimmedPhotonsWithUserData = cms.EDProducer("PATPhotonUserDataEmbedder",
src = cms.InputTag("slimmedPhotons"),
parentSrcs = cms.VInputTag("reducedEgamma:reducedGedPhotons"),
userFloats = cms.PSet(
mvaID = cms.InputTag("photonMVAValueMapProducer:PhotonMVAEstimatorRunIIFall17v2Values"),
PFIsoChg = cms.InputTag("isoForPho:PFIsoChg"),
Expand Down Expand Up @@ -340,22 +342,6 @@ def make_bitmapVID_docstring(id_modules_working_points_pset):
photonMCTask = cms.Task(photonsMCMatchForTable, photonMCTable)


## TEMPORARY as no ID for Run3 yet
(run3_nanoAOD_devel).toReplaceWith(photonTask, photonTask.copyAndExclude([bitmapVIDForPho]))
(run3_nanoAOD_devel).toModify(slimmedPhotonsWithUserData, userIntFromBools = cms.PSet())
(run3_nanoAOD_devel).toModify(slimmedPhotonsWithUserData.userInts,
VIDNestedWPBitmap = None,)
(run3_nanoAOD_devel).toModify(slimmedPhotonsWithUserData.userFloats,
mvaID = None)
(run3_nanoAOD_devel).toModify(photonTable.variables,
cutBased = None,
cutBased_Fall17V1Bitmap = None,
vidNestedWPBitmap = None,
mvaID = None,
mvaID_WP90 = None,
mvaID_WP80 = None,
)
#### end TEMPORARY Run3

from RecoEgamma.EgammaIsolationAlgos.egmPhotonIsolationMiniAOD_cff import egmPhotonIsolation
from RecoEgamma.PhotonIdentification.photonIDValueMapProducer_cff import photonIDValueMapProducer
Expand Down
88 changes: 76 additions & 12 deletions PhysicsTools/PatAlgos/plugins/PATObjectUserDataEmbedder.cc
Expand Up @@ -13,6 +13,24 @@
#include "DataFormats/PatCandidates/interface/Tau.h"
#include "DataFormats/PatCandidates/interface/Jet.h"

namespace {
template <typename T>
bool equal(const T &lhs, const T &rhs) {
throw cms::Exception("NotImplimented")
<< " equal in PATObjectUserDataEmbedder is not implimented for objects of type " << typeid(lhs).name()
<< " and thus their src coll must be the same collection the valuemaps are keyed off";
}
template <>
bool equal(const reco::GsfElectron &lhs, const reco::GsfElectron &rhs) {
return lhs.superCluster()->seed()->seed().rawId() == rhs.superCluster()->seed()->seed().rawId();
}
template <>
bool equal(const reco::Photon &lhs, const reco::Photon &rhs) {
return lhs.superCluster()->seed()->seed().rawId() == rhs.superCluster()->seed()->seed().rawId();
}

} // namespace

namespace pat {

namespace helper {
Expand All @@ -26,6 +44,31 @@ namespace pat {
}
};

template <typename T, typename TParent, typename TProd>
edm::Ptr<TParent> getPtrForProd(edm::Ptr<T> ptr,
const std::vector<edm::Handle<edm::View<TParent>>> &parentColls,
const TProd &prod) {
if (prod.contains(ptr.id())) {
return edm::Ptr<TParent>(ptr);
} else {
for (const auto &parentColl : parentColls) {
if (parentColl.isValid() && prod.contains(parentColl.id())) {
for (size_t indx = 0; indx < parentColl->size(); indx++) {
if (equal<TParent>(*ptr, (*parentColl)[indx])) {
return edm::Ptr<TParent>(parentColl, indx);
}
}
//note this assumes that another parent coll isnt in the value map
//it if its, it'll return null when the other one might work
return edm::Ptr<TParent>(parentColl.id());
}
}
}
throw cms::Exception("ConfigurationError")
<< "When accessing value maps in PATObjectUserDataEmbedder, the collection the valuemap was keyed off is not "
"either the input src or listed in one of the parentSrcs";
}

template <typename A>
class NamedUserDataLoader {
public:
Expand All @@ -38,15 +81,19 @@ namespace pat {
}
}
}
template <typename T>
void addData(const edm::Event &iEvent, const std::vector<edm::Ptr<T>> &ptrs, std::vector<T> &out) const {
template <typename T, typename TParent = T>
void addData(const edm::Event &iEvent,
const std::vector<edm::Ptr<T>> &ptrs,
std::vector<edm::Handle<edm::View<TParent>>> parents,
std::vector<T> &out) const {
A adder;
unsigned int n = ptrs.size();
edm::Handle<typename A::product_type> handle;
for (const auto &pair : labelsAndTokens_) {
iEvent.getByToken(pair.second, handle);
for (unsigned int i = 0; i < n; ++i) {
adder.addData(out[i], pair.first, (*handle)[ptrs[i]]);
auto ptr = getPtrForProd(ptrs[i], parents, *handle);
adder.addData(out[i], pair.first, (*handle)[ptr]);
}
}
}
Expand All @@ -56,7 +103,7 @@ namespace pat {
}; // class NamedUserDataLoader
} // namespace helper

template <typename T>
template <typename T, typename ParentType = T>
class PATObjectUserDataEmbedder : public edm::stream::EDProducer<> {
public:
explicit PATObjectUserDataEmbedder(const edm::ParameterSet &iConfig)
Expand All @@ -65,6 +112,9 @@ namespace pat {
userInts_(iConfig, "userInts", consumesCollector()),
userIntFromBools_(iConfig, "userIntFromBools", consumesCollector()),
userCands_(iConfig, "userCands", consumesCollector()) {
for (const auto &parentSrc : iConfig.getParameter<std::vector<edm::InputTag>>("parentSrcs")) {
parentSrcs_.push_back(consumes<edm::View<ParentType>>(parentSrc));
}
produces<std::vector<T>>();
}

Expand All @@ -75,6 +125,7 @@ namespace pat {
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
edm::ParameterSetDescription desc;
desc.add<edm::InputTag>("src");
desc.add<std::vector<edm::InputTag>>("parentSrcs", std::vector<edm::InputTag>());
for (auto &&what : {"userFloats", "userInts", "userIntFromBools", "userCands"}) {
edm::ParameterSetDescription descNested;
descNested.addWildcard<edm::InputTag>("*");
Expand All @@ -95,6 +146,13 @@ namespace pat {
private:
// configurables
edm::EDGetTokenT<edm::View<T>> src_;
//so valuemaps are keyed to a given collection so if we remake the objects,
//are valuemaps are pointing to the wrong collection
//this allows us to pass in past collections to try them to see if they are the ones
//a valuemap is keyed to
//note ParentType must inherit from T
std::vector<edm::EDGetTokenT<edm::View<ParentType>>> parentSrcs_;

helper::NamedUserDataLoader<pat::helper::AddUserFloat> userFloats_;
helper::NamedUserDataLoader<pat::helper::AddUserInt> userInts_;
helper::NamedUserDataLoader<pat::helper::AddUserIntFromBool> userIntFromBools_;
Expand All @@ -103,11 +161,16 @@ namespace pat {

} // namespace pat

template <typename T>
void pat::PATObjectUserDataEmbedder<T>::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
template <typename T, typename ParentType>
void pat::PATObjectUserDataEmbedder<T, ParentType>::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
edm::Handle<edm::View<T>> src;
iEvent.getByToken(src_, src);

std::vector<edm::Handle<edm::View<ParentType>>> parentSrcs;
for (const auto &src : parentSrcs_) {
parentSrcs.push_back(iEvent.getHandle(src));
}

std::unique_ptr<std::vector<T>> out(new std::vector<T>());
out->reserve(src->size());

Expand All @@ -118,17 +181,18 @@ void pat::PATObjectUserDataEmbedder<T>::produce(edm::Event &iEvent, const edm::E
out->push_back((*src)[i]);
ptrs.push_back(src->ptrAt(i));
}
userFloats_.addData(iEvent, ptrs, *out);
userInts_.addData(iEvent, ptrs, *out);
userIntFromBools_.addData(iEvent, ptrs, *out);
userCands_.addData(iEvent, ptrs, *out);

userFloats_.addData(iEvent, ptrs, parentSrcs, *out);
userInts_.addData(iEvent, ptrs, parentSrcs, *out);
userIntFromBools_.addData(iEvent, ptrs, parentSrcs, *out);
userCands_.addData(iEvent, ptrs, parentSrcs, *out);

iEvent.put(std::move(out));
}

typedef pat::PATObjectUserDataEmbedder<pat::Electron> PATElectronUserDataEmbedder;
typedef pat::PATObjectUserDataEmbedder<pat::Electron, reco::GsfElectron> PATElectronUserDataEmbedder;
typedef pat::PATObjectUserDataEmbedder<pat::Muon> PATMuonUserDataEmbedder;
typedef pat::PATObjectUserDataEmbedder<pat::Photon> PATPhotonUserDataEmbedder;
typedef pat::PATObjectUserDataEmbedder<pat::Photon, reco::Photon> PATPhotonUserDataEmbedder;
typedef pat::PATObjectUserDataEmbedder<pat::Tau> PATTauUserDataEmbedder;
typedef pat::PATObjectUserDataEmbedder<pat::Jet> PATJetUserDataEmbedder;

Expand Down