From 0e606d5e08a7a693a9cb71dec662339cc656535e Mon Sep 17 00:00:00 2001 From: Huilin Qu Date: Fri, 4 Oct 2024 17:54:13 +0200 Subject: [PATCH 1/6] Set input shapes explicitly for fixed padding. --- RecoBTag/FeatureTools/src/deep_helpers.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/RecoBTag/FeatureTools/src/deep_helpers.cc b/RecoBTag/FeatureTools/src/deep_helpers.cc index 0c149d59df562..d8e4d9321f2b5 100644 --- a/RecoBTag/FeatureTools/src/deep_helpers.cc +++ b/RecoBTag/FeatureTools/src/deep_helpers.cc @@ -279,6 +279,7 @@ namespace btagbtvdeep { if (group_pset.contains("var_length")) { prep_params.min_length = group_pset.at("var_length"); prep_params.max_length = prep_params.min_length; + input_shapes_.push_back({1, (int64_t)prep_params.var_names.size(), prep_params.max_length}); } else { prep_params.min_length = group_pset.at("min_length"); prep_params.max_length = group_pset.at("max_length"); From e16e311826fd062f31d49394fda3c9c854300709 Mon Sep 17 00:00:00 2001 From: Huilin Qu Date: Fri, 4 Oct 2024 17:55:27 +0200 Subject: [PATCH 2/6] Add DeepBoostedJetFeatures to classdef. --- DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h | 3 +++ DataFormats/BTauReco/src/classes_def.xml | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h b/DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h index fb06d9c8a6c47..a49e889805e3f 100644 --- a/DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h +++ b/DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h @@ -5,6 +5,7 @@ #include #include #include "FWCore/Utilities/interface/Exception.h" +#include "DataFormats/BTauReco/interface/RefMacros.h" namespace btagbtvdeep { @@ -57,6 +58,8 @@ namespace btagbtvdeep { std::unordered_map> feature_map_; }; + DECLARE_EDM_REFS(DeepBoostedJetFeatures) + } // namespace btagbtvdeep #endif // DataFormats_BTauReco_DeepBoostedJetFeatures_h diff --git a/DataFormats/BTauReco/src/classes_def.xml b/DataFormats/BTauReco/src/classes_def.xml index f5f697a7a2c98..895e486f1e144 100644 --- a/DataFormats/BTauReco/src/classes_def.xml +++ b/DataFormats/BTauReco/src/classes_def.xml @@ -489,7 +489,15 @@ + + + + + + + + From 518a46c0208cb7c0a8f71efa90594357b3f58c31 Mon Sep 17 00:00:00 2001 From: jlidrych Date: Mon, 30 Sep 2024 11:41:47 +0200 Subject: [PATCH 3/6] PNet Muon Id implementation --- PhysicsTools/NanoAOD/python/muons_cff.py | 76 ++++++- PhysicsTools/PatAlgos/BuildFile.xml | 3 + .../LeptonTagInfoCollectionProducer.h | 112 +++++++++ .../PatAlgos/interface/PNETLeptonProducer.h | 89 ++++++++ .../LeptonTagInfoCollectionProducer.cc | 214 ++++++++++++++++++ .../PatAlgos/plugins/PNETLeptonProducer.cc | 163 +++++++++++++ PhysicsTools/PatAlgos/src/classes.h | 3 + PhysicsTools/PatAlgos/src/classes_def.xml | 8 + 8 files changed, 667 insertions(+), 1 deletion(-) create mode 100644 PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h create mode 100644 PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h create mode 100644 PhysicsTools/PatAlgos/plugins/LeptonTagInfoCollectionProducer.cc create mode 100644 PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc create mode 100644 PhysicsTools/PatAlgos/src/classes.h create mode 100644 PhysicsTools/PatAlgos/src/classes_def.xml diff --git a/PhysicsTools/NanoAOD/python/muons_cff.py b/PhysicsTools/NanoAOD/python/muons_cff.py index 073b8c331d6e5..fa3bb9c8b21e6 100644 --- a/PhysicsTools/NanoAOD/python/muons_cff.py +++ b/PhysicsTools/NanoAOD/python/muons_cff.py @@ -145,6 +145,66 @@ variables = _legacy_muon_BDT_variable ) +pnetMuonVariables = cms.EDProducer("MuonInfoCollectionProducer", + src = cms.InputTag("linkedObjects","muons"), + secondary_vertices=cms.InputTag("slimmedSecondaryVertices"), + pvSrc = cms.InputTag("offlineSlimmedPrimaryVertices"), + pfCandidates=cms.InputTag("packedPFCandidates"), + leptonVars = cms.PSet( + MuonSelected_LepGood_pt = cms.string("pt"), + MuonSelected_LepGood_eta = cms.string("eta"), + MuonSelected_LepGood_jetNDauChargedMVASel = cms.string("?userCand('jetForLepJetVar').isNonnull()?userFloat('jetNDauChargedMVASel'):0"), + MuonSelected_LepGood_miniRelIsoCharged = cms.string("userFloat('miniIsoChg')/pt"), + MuonSelected_LepGood_miniRelIsoNeutral = cms.string("(userFloat('miniIsoAll')-userFloat('miniIsoChg'))/pt"), + MuonSelected_LepGood_jetPtRelv2 = cms.string("?userCand('jetForLepJetVar').isNonnull()?userFloat('ptRel'):0"), + MuonSelected_LepGood_jetDF = cms.string("?userCand('jetForLepJetVar').isNonnull()?max(userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:probbb')+userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:probb')+userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:problepb'),0.0):0.0"), + MuonSelected_LepGood_jetPtRatio = cms.string("?userCand('jetForLepJetVar').isNonnull()?min(userFloat('ptRatio'),1.5):1.0/(1.0+(pfIsolationR04().sumChargedHadronPt + max(pfIsolationR04().sumNeutralHadronEt + pfIsolationR04().sumPhotonEt - pfIsolationR04().sumPUPt/2,0.0))/pt)"), + MuonSelected_dxy = cms.string("log(abs(dB('PV2D')))"), + MuonSelected_sip3d = cms.string("abs(dB('PV3D')/edB('PV3D'))"), + MuonSelected_dz = cms.string("log(abs(dB('PVDZ')))"), + MuonSelected_LepGood_dz = cms.string("log(abs(dB('PVDZ')))"), + MuonSelected_segmentComp = cms.string("segmentCompatibility"), + MuonSelected_global_muon = cms.string("isGlobalMuon"), + MuonSelected_validFraction = cms.string("?innerTrack.isNonnull?innerTrack().validFraction:-99"), + MuonSelected_local_chi2 = cms.string("combinedQuality().chi2LocalPosition"), + MuonSelected_kink = cms.string("combinedQuality().trkKink"), + MuonSelected_n_MatchedStations = cms.string("numberOfMatchedStations()"), + MuonSelected_Valid_pixel = cms.string("?innerTrack.isNonnull()?innerTrack().hitPattern().numberOfValidPixelHits():-99"), + MuonSelected_tracker_layers = cms.string("?innerTrack.isNonnull()?innerTrack().hitPattern().trackerLayersWithMeasurement():-99"), + MuonSelected_mvaId=cms.string("userFloat('mvaIDMuon')"), + ), + leptonVarsExt = cms.PSet( + MuonSelected_mvaTTH=cms.InputTag("muonMVATTH"), + ), + pfVars = cms.PSet( + PF_pt=cms.string("pt"), + PF_charge=cms.string("charge"), + PF_isElectron=cms.string("?abs(pdgId)==11?1:0"), + PF_isMuon=cms.string("?abs(pdgId)==13?1:0"), + PF_isNeutralHadron=cms.string("?abs(pdgId)==130?1:0"), + PF_isPhoton=cms.string("?abs(pdgId)==22?1:0"), + PF_isChargedHadron=cms.string("?abs(pdgId)==211?1:0"), + PF_puppiWeightNoLep=cms.string("puppiWeightNoLep"), + PF_fromPV=cms.string("fromPV"), + PF_numberOfPixelHits=cms.string("numberOfPixelHits"), + PF_dzSig=cms.string("?hasTrackDetails?dz/max(dzError,1.e-6):0"), + PF_dxySig=cms.string("?hasTrackDetails?dxy/max(dxyError,1.e-6):0"), + PF_hcalFraction=cms.string("hcalFraction"), + PF_trackerLayersWithMeasurement=cms.string("?hasTrackDetails?bestTrack().hitPattern().trackerLayersWithMeasurement:0"), + pf_mask=cms.string("1"), + ), + svVars = cms.PSet( + SV_eta=cms.string("eta"), + SV_phi=cms.string("phi"), + SV_pt=cms.string("pt"), + SV_ndof=cms.string("vertexNdof"), + SV_chi2=cms.string("vertexChi2"), + SV_nTracks=cms.string("numberOfDaughters"), + SV_mass=cms.string("mass"), + SV_mask=cms.string("1"), + ), +) + from TrackingTools.TransientTrack.TransientTrackBuilder_cfi import * muonBSConstrain = cms.EDProducer("MuonBeamspotConstraintValueMapProducer", src = cms.InputTag("linkedObjects","muons"), @@ -213,6 +273,10 @@ externalVariables = cms.PSet( promptMVA = ExtVar(cms.InputTag("muonPROMPTMVA"),float, doc="Prompt MVA lepton ID score. Corresponds to the previous mvaTTH",precision=14), mvaLowPt = ExtVar(cms.InputTag("muonMVALowPt"),float, doc="Low pt muon ID score",precision=14), + pnScore_light = ExtVar(cms.InputTag("muonPNnorwwithtaus:pnScorelight"),float, doc="Score of PNet Muon id",precision=14), + pnScore_prompt = ExtVar(cms.InputTag("muonPNnorwwithtaus:pnScoreprompt"),float, doc="Score of PNet Muon id",precision=14), + pnScore_heavy = ExtVar(cms.InputTag("muonPNnorwwithtaus:pnScoreheavy"),float, doc="Score of PNet Muon id",precision=14), + pnScore_tau = ExtVar(cms.InputTag("muonPNnorwwithtaus:pnScoretau"),float, doc="Score of PNet Muon id",precision=14), fsrPhotonIdx = ExtVar(cms.InputTag("leptonFSRphotons:muFsrIndex"), "int16", doc="Index of the lowest-dR/ET2 among associated FSR photons"), bsConstrainedPt = ExtVar(cms.InputTag("muonBSConstrain:muonBSConstrainedPt"),float, doc="pT with beamspot constraint",precision=-1), bsConstrainedPtErr = ExtVar(cms.InputTag("muonBSConstrain:muonBSConstrainedPtErr"),float, doc="pT error with beamspot constraint ",precision=6), @@ -220,6 +284,16 @@ ), ) +muonPNnorwwithtaus = cms.EDProducer('PNETMuonProducer', + src = cms.InputTag("pnetMuonVariables"), + srcLeps = cms.InputTag("linkedObjects","muons"), + model_path=cms.FileInPath('PhysicsTools/NanoAOD/data/PNetMuonId/model.onnx'), + preprocess_json=cms.FileInPath('PhysicsTools/NanoAOD/data/PNetMuonId/preprocess.json'), + name=cms.string("PN_lepton"), + debugMode=cms.untracked.bool(True), + flav_names = cms.vstring(["light","prompt","tau","heavy"]), +) + # Increase precision of eta and phi muonTable.variables.eta.precision = 16 muonTable.variables.phi.precision = 16 @@ -254,5 +328,5 @@ muonTask = cms.Task(slimmedMuonsUpdated,isoForMu,ptRatioRelForMu,slimmedMuonsWithUserData,finalMuons,finalLooseMuons ) muonMCTask = cms.Task(muonsMCMatchForTable,muonMCTable) -muonTablesTask = cms.Task(muonPROMPTMVA,muonMVALowPt,muonBSConstrain,muonTable,muonMVAID) +muonTablesTask = cms.Task(muonPROMPTMVA,muonMVALowPt,muonBSConstrain,muonTable,muonMVAID,pnetMuonVariables,muonPNnorwwithtaus) diff --git a/PhysicsTools/PatAlgos/BuildFile.xml b/PhysicsTools/PatAlgos/BuildFile.xml index b0a2ac5138524..fc97d28c9ed4d 100644 --- a/PhysicsTools/PatAlgos/BuildFile.xml +++ b/PhysicsTools/PatAlgos/BuildFile.xml @@ -14,10 +14,13 @@ + + + diff --git a/PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h b/PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h new file mode 100644 index 0000000000000..0b5a485556701 --- /dev/null +++ b/PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h @@ -0,0 +1,112 @@ +// -*- C++ -*- +// +// Package: PhysicsTools/PatAlgos +// Class: LeptonTagInfoCollectionProducer +// +/**\class LeptonTagInfoCollectionProducer LeptonTagInfoCollectionProducer.cc PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc + + +*/ +// +// Original Author: Sergio Sanchez Cruz +// Created: Mon, 15 May 2023 08:32:03 GMT +// +// + +#ifndef PhysicsTools_PatAlgos_LeptonTagInfoCollectionProducer_h +#define PhysicsTools_PatAlgos_LeptonTagInfoCollectionProducer_h + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "FWCore/Utilities/interface/ESGetToken.h" + +#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" +#include "DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h" +#include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h" +#include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" +#include "DataFormats/BTauReco/interface/DeepBoostedJetTagInfo.h" // this is flexible enough for our purposes +#include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h" +#include "DataFormats/VertexReco/interface/Vertex.h" + +namespace pat { + template + + class FeaturesLepInfo { + public: + FeaturesLepInfo() {} + + FeaturesLepInfo(const Features& features, const edm::RefToBase& lep_ref) + : features_(features), lep_ref_(lep_ref) {} + + edm::RefToBase lep() const { return lep_ref_; } + + const Features& features() const { return features_; } + + ~FeaturesLepInfo() {} + FeaturesLepInfo* clone(void) const { return new FeaturesLepInfo(*this); } + + CMS_CLASS_VERSION(3); + + private: + Features features_; + edm::RefToBase lep_ref_; + }; + + template + using LeptonTagInfo = FeaturesLepInfo; + + template + using LeptonTagInfoCollection = std::vector>; + + template + using varWithName = std::pair>; + + template + using extVarWithName = std::pair>>; + + template + class LeptonTagInfoCollectionProducer : public edm::stream::EDProducer<> { + public: + explicit LeptonTagInfoCollectionProducer(const edm::ParameterSet& iConfig); + ~LeptonTagInfoCollectionProducer() override {}; + + private: + void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; + template + void parse_vars_into(const edm::ParameterSet&, std::vector>>&); + template + void parse_extvars_into(const edm::ParameterSet&, std::vector>>&); + void fill_lepton_features(const T&, btagbtvdeep::DeepBoostedJetFeatures&); + void fill_lepton_extfeatures(const edm::RefToBase&, btagbtvdeep::DeepBoostedJetFeatures&, edm::Event&); + void fill_pf_features(const T&, btagbtvdeep::DeepBoostedJetFeatures&); + void fill_sv_features(const T&, btagbtvdeep::DeepBoostedJetFeatures&); + + edm::EDGetTokenT> src_token_; + edm::EDGetTokenT pf_token_; + edm::EDGetTokenT sv_token_; + edm::EDGetTokenT> pv_token_; + + edm::ParameterSet lepton_varsPSet_; + edm::ParameterSet lepton_varsExtPSet_; + edm::ParameterSet pf_varsPSet_; + edm::ParameterSet sv_varsPSet_; + + std::vector>> lepton_vars_; + std::vector>> pf_vars_; + std::vector>> sv_vars_; + edm::Handle svs_; + edm::Handle pfs_; + edm::Handle> pvs_; + std::vector>> extLepton_vars_; + }; + +} // namespace pat + +#endif diff --git a/PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h b/PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h new file mode 100644 index 0000000000000..51ebeac9025c9 --- /dev/null +++ b/PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h @@ -0,0 +1,89 @@ +#ifndef PhysicsTools_PatAlgos_PNETLeptonProducer +#define PhysicsTools_PatAlgos_PNETLeptonProducer + +// -*- C++ -*- +// +// Package: PhysicsTools/PatAlgos +// Class: PNETLeptonProducer +// +/**\class PNETLeptonProducer PNETLeptonProducer.cc PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc + + +*/ +// +// Original Author: Sergio Sanchez Cruz +// Created: Mon, 15 May 2023 08:32:03 GMT +// +// + +#include + +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "CommonTools/Utils/interface/StringObjectFunction.h" +#include "DataFormats/Common/interface/ValueMap.h" + +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/PatCandidates/interface/Muon.h" +#include "DataFormats/PatCandidates/interface/Electron.h" +#include "PhysicsTools/ONNXRuntime/interface/ONNXRuntime.h" +#include "RecoBTag/FeatureTools/interface/deep_helpers.h" +#include "DataFormats/BTauReco/interface/DeepBoostedJetTagInfo.h" // this is flexible enough for our purposes +//#include "DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h" // this will need to be moved to the dedicated producer +#include "PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h" + +#include +// +// class declaration +// + +template +class PNETLeptonProducer : public edm::stream::EDProducer> { +public: + PNETLeptonProducer(const edm::ParameterSet&, const cms::Ort::ONNXRuntime*); + ~PNETLeptonProducer() override {} + + /* void setValue(const std::string var, float val) { */ + /* if (positions_.find(var) != positions_.end()) */ + /* values_[positions_[var]] = val; */ + /* } */ + + static std::unique_ptr initializeGlobalCache(const edm::ParameterSet& cfg); + static void globalEndJob(const cms::Ort::ONNXRuntime* cache); + + static edm::ParameterSetDescription getDescription(); + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + void beginStream(edm::StreamID) override{}; + void produce(edm::Event&, const edm::EventSetup&) override; + void endStream() override {}; + + ///to be implemented in derived classes, filling values for additional variables + virtual void readAdditionalCollections(edm::Event&, const edm::EventSetup&) {} + virtual void fillAdditionalVariables(const T&) {} + + edm::EDGetTokenT> src_; + edm::EDGetTokenT> leps_; + std::vector flav_names_; + std::string name_; + std::vector input_names_; // names of each input group - the ordering is important! + std::vector> input_shapes_; // shapes of each input group (-1 for dynamic axis) + std::vector input_sizes_; // total length of each input vector + std::unordered_map + prep_info_map_; // preprocessing info for each input group + + cms::Ort::FloatArrays data_; + bool debug_ = false; + + void make_inputs(const pat::LeptonTagInfo&); +}; + +#endif diff --git a/PhysicsTools/PatAlgos/plugins/LeptonTagInfoCollectionProducer.cc b/PhysicsTools/PatAlgos/plugins/LeptonTagInfoCollectionProducer.cc new file mode 100644 index 0000000000000..a1e74df3b1af3 --- /dev/null +++ b/PhysicsTools/PatAlgos/plugins/LeptonTagInfoCollectionProducer.cc @@ -0,0 +1,214 @@ +// -*- C++ -*- +// +// Package: PhysicsTools/PatAlgos +// Class: LeptonTagInfoCollectionProducer +// +/**\class LeptonTagInfoCollectionProducer LeptonTagInfoCollectionProducer.cc PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc + + +*/ +// +// Original Author: Sergio Sanchez Cruz +// Created: Mon, 15 May 2023 08:32:03 GMT +// +// + +#include "PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h" +#include "DataFormats/PatCandidates/interface/Electron.h" +#include "DataFormats/PatCandidates/interface/Muon.h" +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "PhysicsTools/NanoAOD/interface/MatchingUtils.h" +#include "DataFormats/Math/interface/deltaPhi.h" +#include "DataFormats/Math/interface/deltaR.h" + +#include "RecoVertex/VertexTools/interface/VertexDistance3D.h" +#include "RecoVertex/VertexTools/interface/VertexDistanceXY.h" +#include "RecoVertex/VertexPrimitives/interface/VertexState.h" +#include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h" + +namespace pat { + template + LeptonTagInfoCollectionProducer::LeptonTagInfoCollectionProducer(const edm::ParameterSet& iConfig) + : src_token_(consumes>(iConfig.getParameter("src"))), + pf_token_(consumes(iConfig.getParameter("pfCandidates"))), + sv_token_(consumes( + iConfig.getParameter("secondary_vertices"))), + pv_token_(consumes>(iConfig.getParameter("pvSrc"))), + lepton_varsPSet_(iConfig.getParameter("leptonVars")), + lepton_varsExtPSet_(iConfig.getParameter("leptonVarsExt")), + pf_varsPSet_(iConfig.getParameter("pfVars")), + sv_varsPSet_(iConfig.getParameter("svVars")) { + produces>(); + parse_vars_into(lepton_varsPSet_, lepton_vars_); + parse_vars_into(pf_varsPSet_, pf_vars_); + parse_vars_into(sv_varsPSet_, sv_vars_); + parse_extvars_into(lepton_varsExtPSet_, extLepton_vars_); + } + + template + void LeptonTagInfoCollectionProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto src = iEvent.getHandle(src_token_); + iEvent.getByToken(sv_token_, svs_); + iEvent.getByToken(pv_token_, pvs_); + iEvent.getByToken(pf_token_, pfs_); + + auto output_info = std::make_unique>(); + + for (size_t ilep = 0; ilep < src->size(); ilep++) { + const auto& lep = (*src)[ilep]; + edm::RefToBase lep_ref(src, ilep); + btagbtvdeep::DeepBoostedJetFeatures features; + fill_lepton_features(lep, features); + fill_lepton_extfeatures(lep_ref, features, iEvent); + fill_pf_features(lep, features); + fill_sv_features(lep, features); + + output_info->emplace_back(features, lep_ref); + } + iEvent.put(std::move(output_info)); + } + + template + template + void LeptonTagInfoCollectionProducer::parse_vars_into(const edm::ParameterSet& varsPSet, + std::vector>>& vars) { + for (const std::string& vname : varsPSet.getParameterNamesForType()) { + const std::string& func = varsPSet.getParameter(vname); + vars.push_back(std::make_unique>(vname, StringObjectFunction(func))); + } + } + + template + template + void LeptonTagInfoCollectionProducer::parse_extvars_into(const edm::ParameterSet& varsPSet, + std::vector>>& vars) { + for (const std::string& vname : varsPSet.getParameterNamesForType()) { + vars.push_back(std::make_unique>( + vname, consumes>(varsPSet.getParameter(vname)))); + } + } + + template + void LeptonTagInfoCollectionProducer::fill_lepton_features(const T& lep, + btagbtvdeep::DeepBoostedJetFeatures& features) { + for (auto& var : lepton_vars_) { + features.add(var->first); + features.reserve(var->first, 1); + features.fill(var->first, var->second(lep)); + } + } + + template + void LeptonTagInfoCollectionProducer::fill_lepton_extfeatures(const edm::RefToBase& lep, + btagbtvdeep::DeepBoostedJetFeatures& features, + edm::Event& iEvent) { + for (auto& var : extLepton_vars_) { + edm::Handle> vmap; + iEvent.getByToken(var->second, vmap); + + features.add(var->first); + features.reserve(var->first, 1); + features.fill(var->first, (*vmap)[lep]); + } + } + + template + void LeptonTagInfoCollectionProducer::fill_pf_features(const T& lep, + btagbtvdeep::DeepBoostedJetFeatures& features) { + pat::PackedCandidateCollection pfcands; + for (size_t ipf = 0; ipf < pfs_->size(); ++ipf) { + if (deltaR(pfs_->at(ipf), lep) < 0.4) + pfcands.push_back(pfs_->at(ipf)); + } + + for (auto& var : pf_vars_) { + features.add(var->first); + features.reserve(var->first, pfcands.size()); + for (const auto& _d : pfcands) { + features.fill(var->first, var->second(_d)); + } + } + + // afaik these need to be hardcoded because I cannot put userFloats to pat::packedCandidates + features.add("PF_phi_rel"); + features.reserve("PF_phi_rel", pfcands.size()); + features.add("PF_eta_rel"); + features.reserve("PF_eta_rel", pfcands.size()); + features.add("PF_dR_lep"); + features.reserve("PF_dR_lep", pfcands.size()); + features.add("PF_pt_rel_log"); + features.reserve("PF_pt_rel_log", pfcands.size()); + + for (const auto& _d : pfcands) { + features.fill("PF_phi_rel", deltaPhi(lep.phi(), _d.phi())); + features.fill("PF_eta_rel", lep.eta() - _d.eta()); + features.fill("PF_dR_lep", deltaR(lep, _d)); + features.fill("PF_pt_rel_log", log(_d.pt() / lep.pt())); + } + } + + template + void LeptonTagInfoCollectionProducer::fill_sv_features(const T& lep, + btagbtvdeep::DeepBoostedJetFeatures& features) { + reco::VertexCompositePtrCandidateCollection selectedSVs; + for (size_t isv = 0; isv < svs_->size(); ++isv) { + if (deltaR(lep, svs_->at(isv)) < 0.4) { + selectedSVs.push_back(svs_->at(isv)); + } + } + + for (auto& var : sv_vars_) { + features.add(var->first); + features.reserve(var->first, selectedSVs.size()); + for (auto& sv : selectedSVs) + features.fill(var->first, var->second(sv)); + } + + // afaik these need to be hardcoded + const auto& PV0 = pvs_->front(); + VertexDistance3D vdist; + VertexDistanceXY vdistXY; + + features.add("SV_dlenSig"); + features.reserve("SV_dlenSig", selectedSVs.size()); + features.add("SV_dxy"); + features.reserve("SV_dxy", selectedSVs.size()); + features.add("SV_eta_rel"); + features.reserve("SV_eta_rel", selectedSVs.size()); + features.add("SV_phi_rel"); + features.reserve("SV_phi_rel", selectedSVs.size()); + features.add("SV_dR_lep"); + features.reserve("SV_dR_lep", selectedSVs.size()); + features.add("SV_pt_rel"); + features.reserve("SV_pt_rel", selectedSVs.size()); + features.add("SV_cospAngle"); + features.reserve("SV_cospAngle", selectedSVs.size()); + features.add("SV_d3d"); + features.reserve("SV_d3d", selectedSVs.size()); + + for (auto& sv : selectedSVs) { + Measurement1D dl = + vdist.distance(PV0, VertexState(RecoVertex::convertPos(sv.position()), RecoVertex::convertError(sv.error()))); + features.fill("SV_d3d", dl.value()); + features.fill("SV_dlenSig", dl.significance()); + Measurement1D d2d = vdistXY.distance( + PV0, VertexState(RecoVertex::convertPos(sv.position()), RecoVertex::convertError(sv.error()))); + features.fill("SV_dxy", d2d.value()); + features.fill("SV_phi_rel", deltaPhi(lep.phi(), sv.phi())); + features.fill("SV_eta_rel", lep.eta() - sv.eta()); + features.fill("SV_dR_lep", deltaR(sv, lep)); + features.fill("SV_pt_rel", sv.pt() / lep.pt()); + double dx = (PV0.x() - sv.vx()), dy = (PV0.y() - sv.vy()), dz = (PV0.z() - sv.vz()); + double pdotv = (dx * sv.px() + dy * sv.py() + dz * sv.pz()) / sv.p() / sqrt(dx * dx + dy * dy + dz * dz); + features.fill("SV_cospAngle", pdotv); + } + } + + typedef LeptonTagInfoCollectionProducer MuonInfoCollectionProducer; + typedef LeptonTagInfoCollectionProducer ElectronInfoCollectionProducer; + +#include "FWCore/Framework/interface/MakerMacros.h" + DEFINE_FWK_MODULE(MuonInfoCollectionProducer); + DEFINE_FWK_MODULE(ElectronInfoCollectionProducer); + +} // namespace pat diff --git a/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc b/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc new file mode 100644 index 0000000000000..f3d1c9b891009 --- /dev/null +++ b/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc @@ -0,0 +1,163 @@ +// -*- C++ -*- +// +// Package: PhysicsTools/PatAlgos +// Class: PNETLeptonProducer +// +/**\class PNETLeptonProducer PNETLeptonProducer.cc PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc + + +*/ +// +// Original Author: Sergio Sanchez Cruz +// Created: Mon, 15 May 2023 08:32:03 GMT +// +// + +#include "PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h" +#include "PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h" + +template +PNETLeptonProducer::PNETLeptonProducer(const edm::ParameterSet &iConfig, const cms::Ort::ONNXRuntime *cache) + : src_(consumes>(iConfig.getParameter("src"))), + leps_(consumes>(iConfig.getParameter("srcLeps"))), + flav_names_(iConfig.getParameter>("flav_names")), + debug_(iConfig.getUntrackedParameter("debugMode", false)) { + ParticleNetConstructor(iConfig, true, input_names_, prep_info_map_, input_shapes_, input_sizes_, &data_); + + if (debug_) { + for (unsigned i = 0; i < input_names_.size(); ++i) { + const auto &group_name = input_names_.at(i); + std::cout << group_name << std::endl; + if (!input_shapes_.empty()) { + std::cout << group_name << "\nshapes: "; + for (const auto &x : input_shapes_.at(i)) { + std::cout << x << ", "; + } + } + std::cout << "\nvariables: "; + for (const auto &x : prep_info_map_.at(group_name).var_names) { + std::cout << x << ", "; + } + std::cout << "\n"; + } + std::cout << "\n"; + } + for (const auto &flav_name : flav_names_) { + produces>("pnScore" + flav_name); + } +} + +template +void PNETLeptonProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + edm::Handle> src; + iEvent.getByToken(src_, src); + + edm::Handle> leps; + iEvent.getByToken(leps_, leps); + + std::vector> mvaScores; + for (unsigned int iflav = 0; iflav < flav_names_.size(); ++iflav) { + mvaScores.push_back(std::vector()); + } + + for (size_t ilep = 0; ilep < src->size(); ilep++) { + const pat::LeptonTagInfo taginfo = (*src)[ilep]; + make_inputs(taginfo); + std::vector outputs; + outputs = globalCache()->run(input_names_, data_, input_shapes_)[0]; + // std::cout<<"outputs.size(): "<> pnScore(new edm::ValueMap()); + edm::ValueMap::Filler filler(*pnScore); + filler.insert(leps, mvaScores[iflav].begin(), mvaScores[iflav].end()); + filler.fill(); + iEvent.put(std::move(pnScore), "pnScore" + flav_names_[iflav]); + } +} + +template +std::unique_ptr PNETLeptonProducer::initializeGlobalCache(const edm::ParameterSet &cfg) { + return std::make_unique(cfg.getParameter("model_path").fullPath()); +} + +template +void PNETLeptonProducer::globalEndJob(const cms::Ort::ONNXRuntime *cache) {} + +template +edm::ParameterSetDescription PNETLeptonProducer::getDescription() { + edm::ParameterSetDescription desc; + desc.add("src")->setComment("input variables"); + desc.add("srcLeps")->setComment("input physics object collection. src and srcLeps must be in synch"); + desc.add>("flav_names")->setComment("Names of the oputput classes"); + desc.add("preprocess_json", ""); + desc.add("name")->setComment("output score variable name"); + desc.add("model_path", edm::FileInPath("PhysicsTools/PatAlgos/data/model.onnx")); + desc.addOptionalUntracked("debugMode", false); + + return desc; +} + +template +void PNETLeptonProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + edm::ParameterSetDescription desc = getDescription(); + std::string modname; + if (typeid(T) == typeid(pat::Jet)) + modname += "Jet"; + else if (typeid(T) == typeid(pat::Muon)) + modname += "Muon"; + else if (typeid(T) == typeid(pat::Electron)) + modname += "Ele"; + modname += "PNETLeptonProducer"; + descriptions.add(modname, desc); +} + +template +void PNETLeptonProducer::make_inputs(const pat::LeptonTagInfo &taginfo) { + for (unsigned igroup = 0; igroup < input_names_.size(); ++igroup) { + const auto &group_name = input_names_[igroup]; + const auto &prep_params = prep_info_map_.at(group_name); + auto &group_values = data_[igroup]; + group_values.resize(input_sizes_[igroup]); + + // first reset group_values to 0 + std::fill(group_values.begin(), group_values.end(), 0); + unsigned curr_pos = 0; + + // transform/pad + for (unsigned i = 0; i < prep_params.var_names.size(); ++i) { + const auto &varname = prep_params.var_names[i]; + const auto &raw_value = taginfo.features().get(varname); + const auto &info = prep_params.info(varname); + int insize = btagbtvdeep::center_norm_pad(raw_value, + info.center, + info.norm_factor, + prep_params.min_length, + prep_params.max_length, + group_values, + curr_pos, + info.pad, + info.replace_inf_value, + info.lower_bound, + info.upper_bound); + curr_pos += insize; + if (i == 0 && (!input_shapes_.empty())) { + input_shapes_[igroup][2] = insize; + } + } + group_values.resize(curr_pos); + } +} + +typedef PNETLeptonProducer PNETMuonProducer; +typedef PNETLeptonProducer PNETElectronProducer; + +//define this as a plug-in +DEFINE_FWK_MODULE(PNETMuonProducer); +DEFINE_FWK_MODULE(PNETElectronProducer); diff --git a/PhysicsTools/PatAlgos/src/classes.h b/PhysicsTools/PatAlgos/src/classes.h new file mode 100644 index 0000000000000..3df3f3ead3218 --- /dev/null +++ b/PhysicsTools/PatAlgos/src/classes.h @@ -0,0 +1,3 @@ +#include "DataFormats/PatCandidates/interface/Muon.h" +#include "DataFormats/PatCandidates/interface/Electron.h" +#include "PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h" diff --git a/PhysicsTools/PatAlgos/src/classes_def.xml b/PhysicsTools/PatAlgos/src/classes_def.xml new file mode 100644 index 0000000000000..ab8f7f56a3c31 --- /dev/null +++ b/PhysicsTools/PatAlgos/src/classes_def.xml @@ -0,0 +1,8 @@ + + + + + + + + From 991eca5c098e5f656ca6381cade7d1229390feda Mon Sep 17 00:00:00 2001 From: Huilin Qu Date: Fri, 4 Oct 2024 17:55:59 +0200 Subject: [PATCH 4/6] Update ParticleNet lepton ID implementations. --- PhysicsTools/NanoAOD/python/muons_cff.py | 146 +++---- PhysicsTools/PatAlgos/BuildFile.xml | 3 - .../LeptonTagInfoCollectionProducer.h | 112 ----- .../PatAlgos/interface/PNETLeptonProducer.h | 89 ---- PhysicsTools/PatAlgos/plugins/BuildFile.xml | 1 + .../LeptonTagInfoCollectionProducer.cc | 413 +++++++++++------- .../PatAlgos/plugins/PNETLeptonProducer.cc | 142 +++--- PhysicsTools/PatAlgos/src/classes.h | 3 - PhysicsTools/PatAlgos/src/classes_def.xml | 8 - 9 files changed, 405 insertions(+), 512 deletions(-) delete mode 100644 PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h delete mode 100644 PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h delete mode 100644 PhysicsTools/PatAlgos/src/classes.h delete mode 100644 PhysicsTools/PatAlgos/src/classes_def.xml diff --git a/PhysicsTools/NanoAOD/python/muons_cff.py b/PhysicsTools/NanoAOD/python/muons_cff.py index fa3bb9c8b21e6..5295817f0e67b 100644 --- a/PhysicsTools/NanoAOD/python/muons_cff.py +++ b/PhysicsTools/NanoAOD/python/muons_cff.py @@ -145,64 +145,71 @@ variables = _legacy_muon_BDT_variable ) -pnetMuonVariables = cms.EDProducer("MuonInfoCollectionProducer", - src = cms.InputTag("linkedObjects","muons"), - secondary_vertices=cms.InputTag("slimmedSecondaryVertices"), - pvSrc = cms.InputTag("offlineSlimmedPrimaryVertices"), - pfCandidates=cms.InputTag("packedPFCandidates"), - leptonVars = cms.PSet( - MuonSelected_LepGood_pt = cms.string("pt"), - MuonSelected_LepGood_eta = cms.string("eta"), - MuonSelected_LepGood_jetNDauChargedMVASel = cms.string("?userCand('jetForLepJetVar').isNonnull()?userFloat('jetNDauChargedMVASel'):0"), - MuonSelected_LepGood_miniRelIsoCharged = cms.string("userFloat('miniIsoChg')/pt"), - MuonSelected_LepGood_miniRelIsoNeutral = cms.string("(userFloat('miniIsoAll')-userFloat('miniIsoChg'))/pt"), - MuonSelected_LepGood_jetPtRelv2 = cms.string("?userCand('jetForLepJetVar').isNonnull()?userFloat('ptRel'):0"), - MuonSelected_LepGood_jetDF = cms.string("?userCand('jetForLepJetVar').isNonnull()?max(userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:probbb')+userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:probb')+userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:problepb'),0.0):0.0"), - MuonSelected_LepGood_jetPtRatio = cms.string("?userCand('jetForLepJetVar').isNonnull()?min(userFloat('ptRatio'),1.5):1.0/(1.0+(pfIsolationR04().sumChargedHadronPt + max(pfIsolationR04().sumNeutralHadronEt + pfIsolationR04().sumPhotonEt - pfIsolationR04().sumPUPt/2,0.0))/pt)"), - MuonSelected_dxy = cms.string("log(abs(dB('PV2D')))"), - MuonSelected_sip3d = cms.string("abs(dB('PV3D')/edB('PV3D'))"), - MuonSelected_dz = cms.string("log(abs(dB('PVDZ')))"), - MuonSelected_LepGood_dz = cms.string("log(abs(dB('PVDZ')))"), - MuonSelected_segmentComp = cms.string("segmentCompatibility"), - MuonSelected_global_muon = cms.string("isGlobalMuon"), - MuonSelected_validFraction = cms.string("?innerTrack.isNonnull?innerTrack().validFraction:-99"), - MuonSelected_local_chi2 = cms.string("combinedQuality().chi2LocalPosition"), - MuonSelected_kink = cms.string("combinedQuality().trkKink"), - MuonSelected_n_MatchedStations = cms.string("numberOfMatchedStations()"), - MuonSelected_Valid_pixel = cms.string("?innerTrack.isNonnull()?innerTrack().hitPattern().numberOfValidPixelHits():-99"), - MuonSelected_tracker_layers = cms.string("?innerTrack.isNonnull()?innerTrack().hitPattern().trackerLayersWithMeasurement():-99"), - MuonSelected_mvaId=cms.string("userFloat('mvaIDMuon')"), - ), - leptonVarsExt = cms.PSet( - MuonSelected_mvaTTH=cms.InputTag("muonMVATTH"), - ), - pfVars = cms.PSet( - PF_pt=cms.string("pt"), - PF_charge=cms.string("charge"), - PF_isElectron=cms.string("?abs(pdgId)==11?1:0"), - PF_isMuon=cms.string("?abs(pdgId)==13?1:0"), - PF_isNeutralHadron=cms.string("?abs(pdgId)==130?1:0"), - PF_isPhoton=cms.string("?abs(pdgId)==22?1:0"), - PF_isChargedHadron=cms.string("?abs(pdgId)==211?1:0"), - PF_puppiWeightNoLep=cms.string("puppiWeightNoLep"), - PF_fromPV=cms.string("fromPV"), - PF_numberOfPixelHits=cms.string("numberOfPixelHits"), - PF_dzSig=cms.string("?hasTrackDetails?dz/max(dzError,1.e-6):0"), - PF_dxySig=cms.string("?hasTrackDetails?dxy/max(dxyError,1.e-6):0"), - PF_hcalFraction=cms.string("hcalFraction"), - PF_trackerLayersWithMeasurement=cms.string("?hasTrackDetails?bestTrack().hitPattern().trackerLayersWithMeasurement:0"), - pf_mask=cms.string("1"), - ), - svVars = cms.PSet( - SV_eta=cms.string("eta"), - SV_phi=cms.string("phi"), - SV_pt=cms.string("pt"), - SV_ndof=cms.string("vertexNdof"), - SV_chi2=cms.string("vertexChi2"), - SV_nTracks=cms.string("numberOfDaughters"), - SV_mass=cms.string("mass"), - SV_mask=cms.string("1"), - ), +from PhysicsTools.PatAlgos.muonTagInfos_cfi import muonTagInfos as _muonTagInfos +muonPNetVariables = _muonTagInfos.clone( + src = cms.InputTag("linkedObjects","muons"), + leptonVars = cms.PSet( + MuonSelected_LepGood_pt = cms.string("pt"), + MuonSelected_LepGood_eta = cms.string("eta"), + MuonSelected_LepGood_jetNDauChargedMVASel = cms.string("?userCand('jetForLepJetVar').isNonnull()?userFloat('jetNDauChargedMVASel'):0"), + MuonSelected_LepGood_miniRelIsoCharged = cms.string("userFloat('miniIsoChg')/pt"), + MuonSelected_LepGood_miniRelIsoNeutral = cms.string("(userFloat('miniIsoAll')-userFloat('miniIsoChg'))/pt"), + MuonSelected_LepGood_jetPtRelv2 = cms.string("?userCand('jetForLepJetVar').isNonnull()?userFloat('ptRel'):0"), + MuonSelected_LepGood_jetDF = cms.string("?userCand('jetForLepJetVar').isNonnull()?max(userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:probbb')+userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:probb')+userCand('jetForLepJetVar').bDiscriminator('pfDeepFlavourJetTags:problepb'),0.0):0.0"), + MuonSelected_LepGood_jetPtRatio = cms.string("?userCand('jetForLepJetVar').isNonnull()?min(userFloat('ptRatio'),1.5):1.0/(1.0+(pfIsolationR04().sumChargedHadronPt + max(pfIsolationR04().sumNeutralHadronEt + pfIsolationR04().sumPhotonEt - pfIsolationR04().sumPUPt/2,0.0))/pt)"), + MuonSelected_dxy = cms.string("log(abs(dB('PV2D')))"), + MuonSelected_sip3d = cms.string("abs(dB('PV3D')/edB('PV3D'))"), + MuonSelected_dz = cms.string("log(abs(dB('PVDZ')))"), + MuonSelected_LepGood_dz = cms.string("log(abs(dB('PVDZ')))"), + MuonSelected_segmentComp = cms.string("segmentCompatibility"), + MuonSelected_global_muon = cms.string("isGlobalMuon"), + MuonSelected_validFraction = cms.string("?innerTrack.isNonnull?innerTrack().validFraction:-99"), + MuonSelected_local_chi2 = cms.string("combinedQuality().chi2LocalPosition"), + MuonSelected_kink = cms.string("combinedQuality().trkKink"), + MuonSelected_n_MatchedStations = cms.string("numberOfMatchedStations()"), + MuonSelected_Valid_pixel = cms.string("?innerTrack.isNonnull()?innerTrack().hitPattern().numberOfValidPixelHits():-99"), + MuonSelected_tracker_layers = cms.string("?innerTrack.isNonnull()?innerTrack().hitPattern().trackerLayersWithMeasurement():-99"), + MuonSelected_mvaId=cms.string("userFloat('mvaIDMuon')"), + ), + leptonVarsExt = cms.PSet( + MuonSelected_mvaTTH=cms.InputTag("muonPROMPTMVA"), + ), + pfVars = cms.PSet( + PF_pt=cms.string("pt"), + PF_charge=cms.string("charge"), + PF_isElectron=cms.string("?abs(pdgId)==11?1:0"), + PF_isMuon=cms.string("?abs(pdgId)==13?1:0"), + PF_isNeutralHadron=cms.string("?abs(pdgId)==130?1:0"), + PF_isPhoton=cms.string("?abs(pdgId)==22?1:0"), + PF_isChargedHadron=cms.string("?abs(pdgId)==211?1:0"), + PF_puppiWeightNoLep=cms.string("puppiWeightNoLep"), + PF_fromPV=cms.string("fromPV"), + PF_numberOfPixelHits=cms.string("numberOfPixelHits"), + PF_dzSig=cms.string("?hasTrackDetails?dz/max(dzError,1.e-6):0"), + PF_dxySig=cms.string("?hasTrackDetails?dxy/max(dxyError,1.e-6):0"), + PF_hcalFraction=cms.string("hcalFraction"), + PF_trackerLayersWithMeasurement=cms.string("?hasTrackDetails?bestTrack().hitPattern().trackerLayersWithMeasurement:0"), + PF_mask=cms.string("1"), + ), + svVars = cms.PSet( + SV_eta=cms.string("eta"), + SV_phi=cms.string("phi"), + SV_pt=cms.string("pt"), + SV_ndof=cms.string("vertexNdof"), + SV_chi2=cms.string("vertexChi2"), + SV_nTracks=cms.string("numberOfDaughters"), + SV_mass=cms.string("mass"), + SV_mask=cms.string("1"), + ), +) + +from PhysicsTools.PatAlgos.muonPNetTags_cfi import muonPNetTags as _muonPNetTags +muonPNetScores = _muonPNetTags.clone( + src = cms.InputTag("muonPNetVariables"), + srcLeps = cms.InputTag("linkedObjects", "muons"), + model_path = 'PhysicsTools/NanoAOD/data/PNetMuonId/model.onnx', + preprocess_json = 'PhysicsTools/NanoAOD/data/PNetMuonId/preprocess.json', + flav_names = cms.vstring(["light", "prompt", "tau", "heavy"]), ) from TrackingTools.TransientTrack.TransientTrackBuilder_cfi import * @@ -273,10 +280,10 @@ externalVariables = cms.PSet( promptMVA = ExtVar(cms.InputTag("muonPROMPTMVA"),float, doc="Prompt MVA lepton ID score. Corresponds to the previous mvaTTH",precision=14), mvaLowPt = ExtVar(cms.InputTag("muonMVALowPt"),float, doc="Low pt muon ID score",precision=14), - pnScore_light = ExtVar(cms.InputTag("muonPNnorwwithtaus:pnScorelight"),float, doc="Score of PNet Muon id",precision=14), - pnScore_prompt = ExtVar(cms.InputTag("muonPNnorwwithtaus:pnScoreprompt"),float, doc="Score of PNet Muon id",precision=14), - pnScore_heavy = ExtVar(cms.InputTag("muonPNnorwwithtaus:pnScoreheavy"),float, doc="Score of PNet Muon id",precision=14), - pnScore_tau = ExtVar(cms.InputTag("muonPNnorwwithtaus:pnScoretau"),float, doc="Score of PNet Muon id",precision=14), + pnScore_prompt = ExtVar(cms.InputTag("muonPNetScores:prompt"),float, doc="PNet muon ID score for lepton from W/Z/H bosons", precision=14), + pnScore_heavy = ExtVar(cms.InputTag("muonPNetScores:heavy"),float, doc="PNet muon ID score for lepton from B or D hadrons", precision=14), + pnScore_light = ExtVar(cms.InputTag("muonPNetScores:light"),float, doc="PNet muon ID score for lepton from hadrons w/o b or c quarks OR w/o generator matching", precision=14), + pnScore_tau = ExtVar(cms.InputTag("muonPNetScores:tau"),float, doc="PNet muon ID score for decay of tau to light leptons (mu)", precision=14), fsrPhotonIdx = ExtVar(cms.InputTag("leptonFSRphotons:muFsrIndex"), "int16", doc="Index of the lowest-dR/ET2 among associated FSR photons"), bsConstrainedPt = ExtVar(cms.InputTag("muonBSConstrain:muonBSConstrainedPt"),float, doc="pT with beamspot constraint",precision=-1), bsConstrainedPtErr = ExtVar(cms.InputTag("muonBSConstrain:muonBSConstrainedPtErr"),float, doc="pT error with beamspot constraint ",precision=6), @@ -284,16 +291,6 @@ ), ) -muonPNnorwwithtaus = cms.EDProducer('PNETMuonProducer', - src = cms.InputTag("pnetMuonVariables"), - srcLeps = cms.InputTag("linkedObjects","muons"), - model_path=cms.FileInPath('PhysicsTools/NanoAOD/data/PNetMuonId/model.onnx'), - preprocess_json=cms.FileInPath('PhysicsTools/NanoAOD/data/PNetMuonId/preprocess.json'), - name=cms.string("PN_lepton"), - debugMode=cms.untracked.bool(True), - flav_names = cms.vstring(["light","prompt","tau","heavy"]), -) - # Increase precision of eta and phi muonTable.variables.eta.precision = 16 muonTable.variables.phi.precision = 16 @@ -326,7 +323,6 @@ docString = cms.string("MC matching to status==1 muons"), ) -muonTask = cms.Task(slimmedMuonsUpdated,isoForMu,ptRatioRelForMu,slimmedMuonsWithUserData,finalMuons,finalLooseMuons ) +muonTask = cms.Task(slimmedMuonsUpdated,isoForMu,ptRatioRelForMu,slimmedMuonsWithUserData,finalMuons,finalLooseMuons) muonMCTask = cms.Task(muonsMCMatchForTable,muonMCTable) -muonTablesTask = cms.Task(muonPROMPTMVA,muonMVALowPt,muonBSConstrain,muonTable,muonMVAID,pnetMuonVariables,muonPNnorwwithtaus) - +muonTablesTask = cms.Task(muonPROMPTMVA,muonMVALowPt,muonBSConstrain,muonTable,muonMVAID,muonPNetVariables,muonPNetScores) diff --git a/PhysicsTools/PatAlgos/BuildFile.xml b/PhysicsTools/PatAlgos/BuildFile.xml index fc97d28c9ed4d..b0a2ac5138524 100644 --- a/PhysicsTools/PatAlgos/BuildFile.xml +++ b/PhysicsTools/PatAlgos/BuildFile.xml @@ -14,13 +14,10 @@ - - - diff --git a/PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h b/PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h deleted file mode 100644 index 0b5a485556701..0000000000000 --- a/PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h +++ /dev/null @@ -1,112 +0,0 @@ -// -*- C++ -*- -// -// Package: PhysicsTools/PatAlgos -// Class: LeptonTagInfoCollectionProducer -// -/**\class LeptonTagInfoCollectionProducer LeptonTagInfoCollectionProducer.cc PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc - - -*/ -// -// Original Author: Sergio Sanchez Cruz -// Created: Mon, 15 May 2023 08:32:03 GMT -// -// - -#ifndef PhysicsTools_PatAlgos_LeptonTagInfoCollectionProducer_h -#define PhysicsTools_PatAlgos_LeptonTagInfoCollectionProducer_h - -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/StreamID.h" -#include "FWCore/Utilities/interface/ESGetToken.h" - -#include "DataFormats/Common/interface/CMS_CLASS_VERSION.h" -#include "DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h" -#include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h" -#include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h" -#include "DataFormats/PatCandidates/interface/PackedCandidate.h" -#include "DataFormats/BTauReco/interface/DeepBoostedJetTagInfo.h" // this is flexible enough for our purposes -#include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h" -#include "DataFormats/VertexReco/interface/Vertex.h" - -namespace pat { - template - - class FeaturesLepInfo { - public: - FeaturesLepInfo() {} - - FeaturesLepInfo(const Features& features, const edm::RefToBase& lep_ref) - : features_(features), lep_ref_(lep_ref) {} - - edm::RefToBase lep() const { return lep_ref_; } - - const Features& features() const { return features_; } - - ~FeaturesLepInfo() {} - FeaturesLepInfo* clone(void) const { return new FeaturesLepInfo(*this); } - - CMS_CLASS_VERSION(3); - - private: - Features features_; - edm::RefToBase lep_ref_; - }; - - template - using LeptonTagInfo = FeaturesLepInfo; - - template - using LeptonTagInfoCollection = std::vector>; - - template - using varWithName = std::pair>; - - template - using extVarWithName = std::pair>>; - - template - class LeptonTagInfoCollectionProducer : public edm::stream::EDProducer<> { - public: - explicit LeptonTagInfoCollectionProducer(const edm::ParameterSet& iConfig); - ~LeptonTagInfoCollectionProducer() override {}; - - private: - void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; - template - void parse_vars_into(const edm::ParameterSet&, std::vector>>&); - template - void parse_extvars_into(const edm::ParameterSet&, std::vector>>&); - void fill_lepton_features(const T&, btagbtvdeep::DeepBoostedJetFeatures&); - void fill_lepton_extfeatures(const edm::RefToBase&, btagbtvdeep::DeepBoostedJetFeatures&, edm::Event&); - void fill_pf_features(const T&, btagbtvdeep::DeepBoostedJetFeatures&); - void fill_sv_features(const T&, btagbtvdeep::DeepBoostedJetFeatures&); - - edm::EDGetTokenT> src_token_; - edm::EDGetTokenT pf_token_; - edm::EDGetTokenT sv_token_; - edm::EDGetTokenT> pv_token_; - - edm::ParameterSet lepton_varsPSet_; - edm::ParameterSet lepton_varsExtPSet_; - edm::ParameterSet pf_varsPSet_; - edm::ParameterSet sv_varsPSet_; - - std::vector>> lepton_vars_; - std::vector>> pf_vars_; - std::vector>> sv_vars_; - edm::Handle svs_; - edm::Handle pfs_; - edm::Handle> pvs_; - std::vector>> extLepton_vars_; - }; - -} // namespace pat - -#endif diff --git a/PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h b/PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h deleted file mode 100644 index 51ebeac9025c9..0000000000000 --- a/PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef PhysicsTools_PatAlgos_PNETLeptonProducer -#define PhysicsTools_PatAlgos_PNETLeptonProducer - -// -*- C++ -*- -// -// Package: PhysicsTools/PatAlgos -// Class: PNETLeptonProducer -// -/**\class PNETLeptonProducer PNETLeptonProducer.cc PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc - - -*/ -// -// Original Author: Sergio Sanchez Cruz -// Created: Mon, 15 May 2023 08:32:03 GMT -// -// - -#include - -#include "FWCore/Framework/interface/Frameworkfwd.h" -#include "FWCore/Framework/interface/stream/EDProducer.h" - -#include "FWCore/Framework/interface/Event.h" -#include "FWCore/Framework/interface/MakerMacros.h" - -#include "FWCore/ParameterSet/interface/ParameterSet.h" -#include "FWCore/Utilities/interface/StreamID.h" - -#include "CommonTools/Utils/interface/StringObjectFunction.h" -#include "DataFormats/Common/interface/ValueMap.h" - -#include "DataFormats/PatCandidates/interface/Jet.h" -#include "DataFormats/PatCandidates/interface/Muon.h" -#include "DataFormats/PatCandidates/interface/Electron.h" -#include "PhysicsTools/ONNXRuntime/interface/ONNXRuntime.h" -#include "RecoBTag/FeatureTools/interface/deep_helpers.h" -#include "DataFormats/BTauReco/interface/DeepBoostedJetTagInfo.h" // this is flexible enough for our purposes -//#include "DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h" // this will need to be moved to the dedicated producer -#include "PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h" - -#include -// -// class declaration -// - -template -class PNETLeptonProducer : public edm::stream::EDProducer> { -public: - PNETLeptonProducer(const edm::ParameterSet&, const cms::Ort::ONNXRuntime*); - ~PNETLeptonProducer() override {} - - /* void setValue(const std::string var, float val) { */ - /* if (positions_.find(var) != positions_.end()) */ - /* values_[positions_[var]] = val; */ - /* } */ - - static std::unique_ptr initializeGlobalCache(const edm::ParameterSet& cfg); - static void globalEndJob(const cms::Ort::ONNXRuntime* cache); - - static edm::ParameterSetDescription getDescription(); - static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - -private: - void beginStream(edm::StreamID) override{}; - void produce(edm::Event&, const edm::EventSetup&) override; - void endStream() override {}; - - ///to be implemented in derived classes, filling values for additional variables - virtual void readAdditionalCollections(edm::Event&, const edm::EventSetup&) {} - virtual void fillAdditionalVariables(const T&) {} - - edm::EDGetTokenT> src_; - edm::EDGetTokenT> leps_; - std::vector flav_names_; - std::string name_; - std::vector input_names_; // names of each input group - the ordering is important! - std::vector> input_shapes_; // shapes of each input group (-1 for dynamic axis) - std::vector input_sizes_; // total length of each input vector - std::unordered_map - prep_info_map_; // preprocessing info for each input group - - cms::Ort::FloatArrays data_; - bool debug_ = false; - - void make_inputs(const pat::LeptonTagInfo&); -}; - -#endif diff --git a/PhysicsTools/PatAlgos/plugins/BuildFile.xml b/PhysicsTools/PatAlgos/plugins/BuildFile.xml index 8abcb381084a6..1eb494d19fbd3 100644 --- a/PhysicsTools/PatAlgos/plugins/BuildFile.xml +++ b/PhysicsTools/PatAlgos/plugins/BuildFile.xml @@ -35,5 +35,6 @@ + diff --git a/PhysicsTools/PatAlgos/plugins/LeptonTagInfoCollectionProducer.cc b/PhysicsTools/PatAlgos/plugins/LeptonTagInfoCollectionProducer.cc index a1e74df3b1af3..dcf1c168e9f58 100644 --- a/PhysicsTools/PatAlgos/plugins/LeptonTagInfoCollectionProducer.cc +++ b/PhysicsTools/PatAlgos/plugins/LeptonTagInfoCollectionProducer.cc @@ -3,21 +3,27 @@ // Package: PhysicsTools/PatAlgos // Class: LeptonTagInfoCollectionProducer // -/**\class LeptonTagInfoCollectionProducer LeptonTagInfoCollectionProducer.cc PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc - - -*/ -// // Original Author: Sergio Sanchez Cruz // Created: Mon, 15 May 2023 08:32:03 GMT // -// +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" +#include "FWCore/Utilities/interface/ESGetToken.h" -#include "PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h" +#include "CommonTools/Utils/interface/StringObjectFunction.h" +#include "DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h" +#include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" #include "DataFormats/PatCandidates/interface/Electron.h" #include "DataFormats/PatCandidates/interface/Muon.h" #include "DataFormats/PatCandidates/interface/Jet.h" -#include "PhysicsTools/NanoAOD/interface/MatchingUtils.h" +#include "DataFormats/VertexReco/interface/Vertex.h" #include "DataFormats/Math/interface/deltaPhi.h" #include "DataFormats/Math/interface/deltaR.h" @@ -26,189 +32,262 @@ #include "RecoVertex/VertexPrimitives/interface/VertexState.h" #include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h" -namespace pat { - template - LeptonTagInfoCollectionProducer::LeptonTagInfoCollectionProducer(const edm::ParameterSet& iConfig) - : src_token_(consumes>(iConfig.getParameter("src"))), - pf_token_(consumes(iConfig.getParameter("pfCandidates"))), - sv_token_(consumes( - iConfig.getParameter("secondary_vertices"))), - pv_token_(consumes>(iConfig.getParameter("pvSrc"))), - lepton_varsPSet_(iConfig.getParameter("leptonVars")), - lepton_varsExtPSet_(iConfig.getParameter("leptonVarsExt")), - pf_varsPSet_(iConfig.getParameter("pfVars")), - sv_varsPSet_(iConfig.getParameter("svVars")) { - produces>(); - parse_vars_into(lepton_varsPSet_, lepton_vars_); - parse_vars_into(pf_varsPSet_, pf_vars_); - parse_vars_into(sv_varsPSet_, sv_vars_); - parse_extvars_into(lepton_varsExtPSet_, extLepton_vars_); - } +using namespace btagbtvdeep; - template - void LeptonTagInfoCollectionProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { - auto src = iEvent.getHandle(src_token_); - iEvent.getByToken(sv_token_, svs_); - iEvent.getByToken(pv_token_, pvs_); - iEvent.getByToken(pf_token_, pfs_); - - auto output_info = std::make_unique>(); - - for (size_t ilep = 0; ilep < src->size(); ilep++) { - const auto& lep = (*src)[ilep]; - edm::RefToBase lep_ref(src, ilep); - btagbtvdeep::DeepBoostedJetFeatures features; - fill_lepton_features(lep, features); - fill_lepton_extfeatures(lep_ref, features, iEvent); - fill_pf_features(lep, features); - fill_sv_features(lep, features); - - output_info->emplace_back(features, lep_ref); - } - iEvent.put(std::move(output_info)); - } +template +class LeptonTagInfoCollectionProducer : public edm::stream::EDProducer<> { +public: + explicit LeptonTagInfoCollectionProducer(const edm::ParameterSet& iConfig); + ~LeptonTagInfoCollectionProducer() override {}; + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + +private: + using LeptonTagInfoCollection = DeepBoostedJetFeaturesCollection; - template - template - void LeptonTagInfoCollectionProducer::parse_vars_into(const edm::ParameterSet& varsPSet, - std::vector>>& vars) { + void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override; + + void fill_lepton_features(const LeptonType&, DeepBoostedJetFeatures&); + void fill_lepton_extfeatures(const edm::RefToBase&, DeepBoostedJetFeatures&, edm::Event&); + void fill_pf_features(const LeptonType&, DeepBoostedJetFeatures&); + void fill_sv_features(const LeptonType&, DeepBoostedJetFeatures&); + + template + using VarWithName = std::pair>; + template + void parse_vars_into(const edm::ParameterSet& varsPSet, std::vector>>& vars) { for (const std::string& vname : varsPSet.getParameterNamesForType()) { const std::string& func = varsPSet.getParameter(vname); - vars.push_back(std::make_unique>(vname, StringObjectFunction(func))); + vars.push_back(std::make_unique>(vname, StringObjectFunction(func))); } } - template - template - void LeptonTagInfoCollectionProducer::parse_extvars_into(const edm::ParameterSet& varsPSet, - std::vector>>& vars) { + template + using ExtVarWithName = std::pair>>; + template + void parse_extvars_into(const edm::ParameterSet& varsPSet, + std::vector>>& vars) { for (const std::string& vname : varsPSet.getParameterNamesForType()) { - vars.push_back(std::make_unique>( - vname, consumes>(varsPSet.getParameter(vname)))); + vars.push_back(std::make_unique>( + vname, consumes>(varsPSet.getParameter(vname)))); } } - template - void LeptonTagInfoCollectionProducer::fill_lepton_features(const T& lep, - btagbtvdeep::DeepBoostedJetFeatures& features) { - for (auto& var : lepton_vars_) { - features.add(var->first); - features.reserve(var->first, 1); - features.fill(var->first, var->second(lep)); - } + edm::EDGetTokenT> src_token_; + edm::EDGetTokenT pf_token_; + edm::EDGetTokenT sv_token_; + edm::EDGetTokenT> pv_token_; + + edm::ParameterSet lepton_varsPSet_; + edm::ParameterSet lepton_varsExtPSet_; + edm::ParameterSet pf_varsPSet_; + edm::ParameterSet sv_varsPSet_; + + std::vector>> lepton_vars_; + std::vector>> pf_vars_; + std::vector>> sv_vars_; + edm::Handle svs_; + edm::Handle pfs_; + edm::Handle> pvs_; + std::vector>> extLepton_vars_; +}; + +template +LeptonTagInfoCollectionProducer::LeptonTagInfoCollectionProducer(const edm::ParameterSet& iConfig) + : src_token_(consumes>(iConfig.getParameter("src"))), + pf_token_(consumes(iConfig.getParameter("pfCandidates"))), + sv_token_(consumes( + iConfig.getParameter("secondary_vertices"))), + pv_token_(consumes>(iConfig.getParameter("pvSrc"))), + lepton_varsPSet_(iConfig.getParameter("leptonVars")), + lepton_varsExtPSet_(iConfig.getParameter("leptonVarsExt")), + pf_varsPSet_(iConfig.getParameter("pfVars")), + sv_varsPSet_(iConfig.getParameter("svVars")) { + parse_vars_into(lepton_varsPSet_, lepton_vars_); + parse_vars_into(pf_varsPSet_, pf_vars_); + parse_vars_into(sv_varsPSet_, sv_vars_); + parse_extvars_into(lepton_varsExtPSet_, extLepton_vars_); + + produces(); +} + +template +void LeptonTagInfoCollectionProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + + desc.add("src", edm::InputTag("slimmedMuons")); + desc.add("pfCandidates", edm::InputTag("packedPFCandidates")); + desc.add("secondary_vertices", edm::InputTag("slimmedSecondaryVertices")); + desc.add("pvSrc", edm::InputTag("offlineSlimmedPrimaryVertices")); + + for (auto&& what : {"leptonVars", "pfVars", "svVars"}) { + edm::ParameterSetDescription descNested; + descNested.addWildcard("*"); + desc.add(what, descNested); } - template - void LeptonTagInfoCollectionProducer::fill_lepton_extfeatures(const edm::RefToBase& lep, - btagbtvdeep::DeepBoostedJetFeatures& features, - edm::Event& iEvent) { - for (auto& var : extLepton_vars_) { - edm::Handle> vmap; - iEvent.getByToken(var->second, vmap); - - features.add(var->first); - features.reserve(var->first, 1); - features.fill(var->first, (*vmap)[lep]); - } + for (auto&& what : {"leptonVarsExt"}) { + edm::ParameterSetDescription descNested; + descNested.addWildcard("*"); + desc.add(what, descNested); } - template - void LeptonTagInfoCollectionProducer::fill_pf_features(const T& lep, - btagbtvdeep::DeepBoostedJetFeatures& features) { - pat::PackedCandidateCollection pfcands; - for (size_t ipf = 0; ipf < pfs_->size(); ++ipf) { - if (deltaR(pfs_->at(ipf), lep) < 0.4) - pfcands.push_back(pfs_->at(ipf)); - } + std::string modname; + if (typeid(LeptonType) == typeid(pat::Muon)) + modname += "muon"; + else if (typeid(LeptonType) == typeid(pat::Electron)) + modname += "electron"; + modname += "TagInfos"; + descriptions.add(modname, desc); +} - for (auto& var : pf_vars_) { - features.add(var->first); - features.reserve(var->first, pfcands.size()); - for (const auto& _d : pfcands) { - features.fill(var->first, var->second(_d)); - } - } +template +void LeptonTagInfoCollectionProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto src = iEvent.getHandle(src_token_); + iEvent.getByToken(sv_token_, svs_); + iEvent.getByToken(pv_token_, pvs_); + iEvent.getByToken(pf_token_, pfs_); - // afaik these need to be hardcoded because I cannot put userFloats to pat::packedCandidates - features.add("PF_phi_rel"); - features.reserve("PF_phi_rel", pfcands.size()); - features.add("PF_eta_rel"); - features.reserve("PF_eta_rel", pfcands.size()); - features.add("PF_dR_lep"); - features.reserve("PF_dR_lep", pfcands.size()); - features.add("PF_pt_rel_log"); - features.reserve("PF_pt_rel_log", pfcands.size()); - - for (const auto& _d : pfcands) { - features.fill("PF_phi_rel", deltaPhi(lep.phi(), _d.phi())); - features.fill("PF_eta_rel", lep.eta() - _d.eta()); - features.fill("PF_dR_lep", deltaR(lep, _d)); - features.fill("PF_pt_rel_log", log(_d.pt() / lep.pt())); - } + auto output_info = std::make_unique(); + + if (pvs_->empty()) { + // produce empty TagInfos in case no primary vertex + iEvent.put(std::move(output_info)); + return; } - template - void LeptonTagInfoCollectionProducer::fill_sv_features(const T& lep, - btagbtvdeep::DeepBoostedJetFeatures& features) { - reco::VertexCompositePtrCandidateCollection selectedSVs; - for (size_t isv = 0; isv < svs_->size(); ++isv) { - if (deltaR(lep, svs_->at(isv)) < 0.4) { - selectedSVs.push_back(svs_->at(isv)); - } - } + for (size_t ilep = 0; ilep < src->size(); ilep++) { + const auto& lep = (*src)[ilep]; + edm::RefToBase lep_ref(src, ilep); + DeepBoostedJetFeatures features; + fill_lepton_features(lep, features); + fill_lepton_extfeatures(lep_ref, features, iEvent); // fixme + fill_pf_features(lep, features); + fill_sv_features(lep, features); + + output_info->emplace_back(features); + } + iEvent.put(std::move(output_info)); +} + +template +void LeptonTagInfoCollectionProducer::fill_lepton_features(const LeptonType& lep, + DeepBoostedJetFeatures& features) { + for (auto& var : lepton_vars_) { + features.add(var->first); + features.reserve(var->first, 1); + features.fill(var->first, var->second(lep)); + } +} + +template +void LeptonTagInfoCollectionProducer::fill_lepton_extfeatures(const edm::RefToBase& lep, + DeepBoostedJetFeatures& features, + edm::Event& iEvent) { + for (auto& var : extLepton_vars_) { + edm::Handle> vmap; + iEvent.getByToken(var->second, vmap); + + features.add(var->first); + features.reserve(var->first, 1); + features.fill(var->first, (*vmap)[lep]); + } +} - for (auto& var : sv_vars_) { - features.add(var->first); - features.reserve(var->first, selectedSVs.size()); - for (auto& sv : selectedSVs) - features.fill(var->first, var->second(sv)); +template +void LeptonTagInfoCollectionProducer::fill_pf_features(const LeptonType& lep, + DeepBoostedJetFeatures& features) { + pat::PackedCandidateCollection pfcands; + for (size_t ipf = 0; ipf < pfs_->size(); ++ipf) { + if (reco::deltaR(pfs_->at(ipf), lep) < 0.4) + pfcands.push_back(pfs_->at(ipf)); + } + + for (auto& var : pf_vars_) { + features.add(var->first); + features.reserve(var->first, pfcands.size()); + for (const auto& cand : pfcands) { + features.fill(var->first, var->second(cand)); } + } + + // afaik these need to be hardcoded because I cannot put userFloats to pat::packedCandidates + features.add("PF_phi_rel"); + features.reserve("PF_phi_rel", pfcands.size()); + features.add("PF_eta_rel"); + features.reserve("PF_eta_rel", pfcands.size()); + features.add("PF_dR_lep"); + features.reserve("PF_dR_lep", pfcands.size()); + features.add("PF_pt_rel_log"); + features.reserve("PF_pt_rel_log", pfcands.size()); + + for (const auto& cand : pfcands) { + features.fill("PF_phi_rel", reco::deltaPhi(lep.phi(), cand.phi())); + features.fill("PF_eta_rel", lep.eta() - cand.eta()); + features.fill("PF_dR_lep", reco::deltaR(lep, cand)); + features.fill("PF_pt_rel_log", log(cand.pt() / lep.pt())); + } +} - // afaik these need to be hardcoded - const auto& PV0 = pvs_->front(); - VertexDistance3D vdist; - VertexDistanceXY vdistXY; - - features.add("SV_dlenSig"); - features.reserve("SV_dlenSig", selectedSVs.size()); - features.add("SV_dxy"); - features.reserve("SV_dxy", selectedSVs.size()); - features.add("SV_eta_rel"); - features.reserve("SV_eta_rel", selectedSVs.size()); - features.add("SV_phi_rel"); - features.reserve("SV_phi_rel", selectedSVs.size()); - features.add("SV_dR_lep"); - features.reserve("SV_dR_lep", selectedSVs.size()); - features.add("SV_pt_rel"); - features.reserve("SV_pt_rel", selectedSVs.size()); - features.add("SV_cospAngle"); - features.reserve("SV_cospAngle", selectedSVs.size()); - features.add("SV_d3d"); - features.reserve("SV_d3d", selectedSVs.size()); - - for (auto& sv : selectedSVs) { - Measurement1D dl = - vdist.distance(PV0, VertexState(RecoVertex::convertPos(sv.position()), RecoVertex::convertError(sv.error()))); - features.fill("SV_d3d", dl.value()); - features.fill("SV_dlenSig", dl.significance()); - Measurement1D d2d = vdistXY.distance( - PV0, VertexState(RecoVertex::convertPos(sv.position()), RecoVertex::convertError(sv.error()))); - features.fill("SV_dxy", d2d.value()); - features.fill("SV_phi_rel", deltaPhi(lep.phi(), sv.phi())); - features.fill("SV_eta_rel", lep.eta() - sv.eta()); - features.fill("SV_dR_lep", deltaR(sv, lep)); - features.fill("SV_pt_rel", sv.pt() / lep.pt()); - double dx = (PV0.x() - sv.vx()), dy = (PV0.y() - sv.vy()), dz = (PV0.z() - sv.vz()); - double pdotv = (dx * sv.px() + dy * sv.py() + dz * sv.pz()) / sv.p() / sqrt(dx * dx + dy * dy + dz * dz); - features.fill("SV_cospAngle", pdotv); +template +void LeptonTagInfoCollectionProducer::fill_sv_features(const LeptonType& lep, + DeepBoostedJetFeatures& features) { + reco::VertexCompositePtrCandidateCollection selectedSVs; + for (size_t isv = 0; isv < svs_->size(); ++isv) { + if (reco::deltaR(lep, svs_->at(isv)) < 0.4) { + selectedSVs.push_back(svs_->at(isv)); } } - typedef LeptonTagInfoCollectionProducer MuonInfoCollectionProducer; - typedef LeptonTagInfoCollectionProducer ElectronInfoCollectionProducer; + for (auto& var : sv_vars_) { + features.add(var->first); + features.reserve(var->first, selectedSVs.size()); + for (auto& sv : selectedSVs) + features.fill(var->first, var->second(sv)); + } -#include "FWCore/Framework/interface/MakerMacros.h" - DEFINE_FWK_MODULE(MuonInfoCollectionProducer); - DEFINE_FWK_MODULE(ElectronInfoCollectionProducer); + // afaik these need to be hardcoded + const auto& PV0 = pvs_->front(); + VertexDistance3D vdist; + VertexDistanceXY vdistXY; + + features.add("SV_dlenSig"); + features.reserve("SV_dlenSig", selectedSVs.size()); + features.add("SV_dxy"); + features.reserve("SV_dxy", selectedSVs.size()); + features.add("SV_eta_rel"); + features.reserve("SV_eta_rel", selectedSVs.size()); + features.add("SV_phi_rel"); + features.reserve("SV_phi_rel", selectedSVs.size()); + features.add("SV_dR_lep"); + features.reserve("SV_dR_lep", selectedSVs.size()); + features.add("SV_pt_rel"); + features.reserve("SV_pt_rel", selectedSVs.size()); + features.add("SV_cospAngle"); + features.reserve("SV_cospAngle", selectedSVs.size()); + features.add("SV_d3d"); + features.reserve("SV_d3d", selectedSVs.size()); + + for (auto& sv : selectedSVs) { + Measurement1D dl = + vdist.distance(PV0, VertexState(RecoVertex::convertPos(sv.position()), RecoVertex::convertError(sv.error()))); + features.fill("SV_d3d", dl.value()); + features.fill("SV_dlenSig", dl.significance()); + Measurement1D d2d = + vdistXY.distance(PV0, VertexState(RecoVertex::convertPos(sv.position()), RecoVertex::convertError(sv.error()))); + features.fill("SV_dxy", d2d.value()); + features.fill("SV_phi_rel", reco::deltaPhi(lep.phi(), sv.phi())); + features.fill("SV_eta_rel", lep.eta() - sv.eta()); + features.fill("SV_dR_lep", reco::deltaR(sv, lep)); + features.fill("SV_pt_rel", sv.pt() / lep.pt()); + double dx = (PV0.x() - sv.vx()), dy = (PV0.y() - sv.vy()), dz = (PV0.z() - sv.vz()); + double pdotv = (dx * sv.px() + dy * sv.py() + dz * sv.pz()) / sv.p() / sqrt(dx * dx + dy * dy + dz * dz); + features.fill("SV_cospAngle", pdotv); + } +} + +typedef LeptonTagInfoCollectionProducer MuonTagInfoCollectionProducer; +typedef LeptonTagInfoCollectionProducer ElectronTagInfoCollectionProducer; -} // namespace pat +DEFINE_FWK_MODULE(MuonTagInfoCollectionProducer); +DEFINE_FWK_MODULE(ElectronTagInfoCollectionProducer); diff --git a/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc b/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc index f3d1c9b891009..3e9fbd27b8a4f 100644 --- a/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc +++ b/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc @@ -3,23 +3,64 @@ // Package: PhysicsTools/PatAlgos // Class: PNETLeptonProducer // -/**\class PNETLeptonProducer PNETLeptonProducer.cc PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc - - -*/ -// // Original Author: Sergio Sanchez Cruz // Created: Mon, 15 May 2023 08:32:03 GMT // -// -#include "PhysicsTools/PatAlgos/interface/PNETLeptonProducer.h" -#include "PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h" +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/MakerMacros.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/Utilities/interface/StreamID.h" + +#include "DataFormats/BTauReco/interface/DeepBoostedJetFeatures.h" +#include "DataFormats/Common/interface/ValueMap.h" +#include "DataFormats/PatCandidates/interface/Electron.h" +#include "DataFormats/PatCandidates/interface/Muon.h" + +#include "PhysicsTools/ONNXRuntime/interface/ONNXRuntime.h" +#include "RecoBTag/FeatureTools/interface/deep_helpers.h" + +using namespace cms::Ort; +using namespace btagbtvdeep; + +template +class PNETLeptonProducer : public edm::stream::EDProducer> { +public: + explicit PNETLeptonProducer(const edm::ParameterSet &, const cms::Ort::ONNXRuntime *); + ~PNETLeptonProducer() override {} + + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); -template -PNETLeptonProducer::PNETLeptonProducer(const edm::ParameterSet &iConfig, const cms::Ort::ONNXRuntime *cache) - : src_(consumes>(iConfig.getParameter("src"))), - leps_(consumes>(iConfig.getParameter("srcLeps"))), + static std::unique_ptr initializeGlobalCache(const edm::ParameterSet &); + static void globalEndJob(const ONNXRuntime *); + +private: + using LeptonTagInfoCollection = DeepBoostedJetFeaturesCollection; + + void produce(edm::Event &, const edm::EventSetup &) override; + void make_inputs(const DeepBoostedJetFeatures &); + + edm::EDGetTokenT src_; + edm::EDGetTokenT> leps_; + std::vector flav_names_; + std::vector input_names_; // names of each input group - the ordering is important! + std::vector> input_shapes_; // shapes of each input group (-1 for dynamic axis) + std::vector input_sizes_; // total length of each input vector + std::unordered_map + prep_info_map_; // preprocessing info for each input group + + cms::Ort::FloatArrays data_; + bool debug_ = false; +}; + +template +PNETLeptonProducer::PNETLeptonProducer(const edm::ParameterSet &iConfig, const cms::Ort::ONNXRuntime *cache) + : src_(consumes(iConfig.getParameter("src"))), + leps_(consumes>(iConfig.getParameter("srcLeps"))), flav_names_(iConfig.getParameter>("flav_names")), debug_(iConfig.getUntrackedParameter("debugMode", false)) { ParticleNetConstructor(iConfig, true, input_names_, prep_info_map_, input_shapes_, input_sizes_, &data_); @@ -42,34 +83,33 @@ PNETLeptonProducer::PNETLeptonProducer(const edm::ParameterSet &iConfig, cons } std::cout << "\n"; } + for (const auto &flav_name : flav_names_) { - produces>("pnScore" + flav_name); + produces>(flav_name); } } -template -void PNETLeptonProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { - edm::Handle> src; +template +void PNETLeptonProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + edm::Handle src; iEvent.getByToken(src_, src); - edm::Handle> leps; + edm::Handle> leps; iEvent.getByToken(leps_, leps); - std::vector> mvaScores; - for (unsigned int iflav = 0; iflav < flav_names_.size(); ++iflav) { - mvaScores.push_back(std::vector()); - } + assert(src->size() == leps->size()); + + std::vector> mvaScores(flav_names_.size(), std::vector(src->size(), -1)); for (size_t ilep = 0; ilep < src->size(); ilep++) { - const pat::LeptonTagInfo taginfo = (*src)[ilep]; + const auto &taginfo = (*src)[ilep]; make_inputs(taginfo); - std::vector outputs; - outputs = globalCache()->run(input_names_, data_, input_shapes_)[0]; + auto outputs = globalCache()->run(input_names_, data_, input_shapes_)[0]; // std::cout<<"outputs.size(): "<::produce(edm::Event &iEvent, const edm::EventSetup &i edm::ValueMap::Filler filler(*pnScore); filler.insert(leps, mvaScores[iflav].begin(), mvaScores[iflav].end()); filler.fill(); - iEvent.put(std::move(pnScore), "pnScore" + flav_names_[iflav]); + iEvent.put(std::move(pnScore), flav_names_[iflav]); } } -template -std::unique_ptr PNETLeptonProducer::initializeGlobalCache(const edm::ParameterSet &cfg) { +template +std::unique_ptr PNETLeptonProducer::initializeGlobalCache( + const edm::ParameterSet &cfg) { return std::make_unique(cfg.getParameter("model_path").fullPath()); } -template -void PNETLeptonProducer::globalEndJob(const cms::Ort::ONNXRuntime *cache) {} +template +void PNETLeptonProducer::globalEndJob(const cms::Ort::ONNXRuntime *cache) {} -template -edm::ParameterSetDescription PNETLeptonProducer::getDescription() { +template +void PNETLeptonProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { edm::ParameterSetDescription desc; desc.add("src")->setComment("input variables"); desc.add("srcLeps")->setComment("input physics object collection. src and srcLeps must be in synch"); desc.add>("flav_names")->setComment("Names of the oputput classes"); - desc.add("preprocess_json", ""); - desc.add("name")->setComment("output score variable name"); - desc.add("model_path", edm::FileInPath("PhysicsTools/PatAlgos/data/model.onnx")); + desc.add("preprocess_json", "PhysicsTools/NanoAOD/data/PNetMuonId/preprocess.json"); + desc.add("model_path", edm::FileInPath("PhysicsTools/NanoAOD/data/PNetMuonId/model.onnx")); desc.addOptionalUntracked("debugMode", false); - return desc; -} - -template -void PNETLeptonProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { - edm::ParameterSetDescription desc = getDescription(); std::string modname; - if (typeid(T) == typeid(pat::Jet)) - modname += "Jet"; - else if (typeid(T) == typeid(pat::Muon)) - modname += "Muon"; - else if (typeid(T) == typeid(pat::Electron)) - modname += "Ele"; - modname += "PNETLeptonProducer"; + if (typeid(LeptonType) == typeid(pat::Muon)) + modname += "muon"; + else if (typeid(LeptonType) == typeid(pat::Electron)) + modname += "electron"; + modname += "PNetTags"; descriptions.add(modname, desc); } -template -void PNETLeptonProducer::make_inputs(const pat::LeptonTagInfo &taginfo) { +template +void PNETLeptonProducer::make_inputs(const DeepBoostedJetFeatures &taginfo) { for (unsigned igroup = 0; igroup < input_names_.size(); ++igroup) { const auto &group_name = input_names_[igroup]; const auto &prep_params = prep_info_map_.at(group_name); @@ -133,7 +165,7 @@ void PNETLeptonProducer::make_inputs(const pat::LeptonTagInfo &taginfo) { // transform/pad for (unsigned i = 0; i < prep_params.var_names.size(); ++i) { const auto &varname = prep_params.var_names[i]; - const auto &raw_value = taginfo.features().get(varname); + const auto &raw_value = taginfo.get(varname); const auto &info = prep_params.info(varname); int insize = btagbtvdeep::center_norm_pad(raw_value, info.center, @@ -155,9 +187,9 @@ void PNETLeptonProducer::make_inputs(const pat::LeptonTagInfo &taginfo) { } } -typedef PNETLeptonProducer PNETMuonProducer; -typedef PNETLeptonProducer PNETElectronProducer; +typedef PNETLeptonProducer MuonPNETProducer; +typedef PNETLeptonProducer ElectronPNETProducer; //define this as a plug-in -DEFINE_FWK_MODULE(PNETMuonProducer); -DEFINE_FWK_MODULE(PNETElectronProducer); +DEFINE_FWK_MODULE(MuonPNETProducer); +DEFINE_FWK_MODULE(ElectronPNETProducer); diff --git a/PhysicsTools/PatAlgos/src/classes.h b/PhysicsTools/PatAlgos/src/classes.h deleted file mode 100644 index 3df3f3ead3218..0000000000000 --- a/PhysicsTools/PatAlgos/src/classes.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "DataFormats/PatCandidates/interface/Muon.h" -#include "DataFormats/PatCandidates/interface/Electron.h" -#include "PhysicsTools/PatAlgos/interface/LeptonTagInfoCollectionProducer.h" diff --git a/PhysicsTools/PatAlgos/src/classes_def.xml b/PhysicsTools/PatAlgos/src/classes_def.xml deleted file mode 100644 index ab8f7f56a3c31..0000000000000 --- a/PhysicsTools/PatAlgos/src/classes_def.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - From c75d8583366fb9941cb6dbeeeb928ec3b6dfacbf Mon Sep 17 00:00:00 2001 From: Huilin Qu Date: Sat, 5 Oct 2024 00:02:56 +0200 Subject: [PATCH 5/6] Add pnScores to nanoDQM. --- PhysicsTools/NanoAOD/python/nanoDQM_cfi.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py index 19c4d371b22ea..b15fb41f11c4d 100644 --- a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py +++ b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py @@ -593,6 +593,10 @@ Plot1D('pfRelIso03_chg', 'pfRelIso03_chg', 20, 0, 2, 'PF relative isolation dR=0.3, charged component'), Plot1D('pfRelIso04_all', 'pfRelIso04_all', 20, 0, 2, 'PF relative isolation dR=0.4, total (deltaBeta corrections)'), Plot1D('phi', 'phi', 20, -3.14159, 3.14159, 'phi'), + Plot1D('pnScore_heavy', 'pnScore_heavy', 40, -1, 1, 'PNet muon ID score for lepton from B or D hadrons'), + Plot1D('pnScore_light', 'pnScore_light', 40, -1, 1, 'PNet muon ID score for lepton from hadrons w/o b or c quarks OR w/o generator matching'), + Plot1D('pnScore_prompt', 'pnScore_prompt', 40, -1, 1, 'PNet muon ID score for lepton from W/Z/H bosons'), + Plot1D('pnScore_tau', 'pnScore_tau', 40, -1, 1, 'PNet muon ID score for decay of tau to light leptons (mu)'), Plot1D('pt', 'pt', 20, 0, 200, 'pt'), Plot1D('ptErr', 'ptErr', 20, 0, 20, 'ptError of the muon track'), Plot1D('segmentComp', 'segmentComp', 20, 0, 1, 'muon segment compatibility'), @@ -607,6 +611,7 @@ Plot1D('tkRelIso', 'tkRelIso', 100, 0, 1, 'Tracker-based relative isolation dR=0.3 for highPt, trkIso/tunePpt'), Plot1D('triggerIdLoose', 'triggerIdLoose', 2, -0.5, 1.5, 'TriggerIdLoose ID'), Plot1D('tunepRelPt', 'tunepRelPt', 200, 0, 200, 'TuneP relative pt, tunePpt/pt'), + Plot1D('tuneP_pterr', 'tuneP_pterr', 200, 0, 20, 'pTerr from tunePMuonBestTrack'), Plot1D('VXBS_Cov00', 'VXBS_Cov00', 200, -10, 10, '0, 0 element of the VXBS Covariance matrix'), Plot1D('VXBS_Cov03', 'VXBS_Cov03', 200, -10, 10, '0, 3 element of the VXBS Covariance matrix'), Plot1D('VXBS_Cov33', 'VXBS_Cov33', 200, -10, 10, '3, 3 element of the VXBS Covariance matrix'), From 8a13edd5327bd910ecd4ab80853afcb976d4e596 Mon Sep 17 00:00:00 2001 From: Huilin Qu Date: Mon, 28 Oct 2024 14:51:44 +0100 Subject: [PATCH 6/6] Add a protection for empty tagInfo. --- .../PatAlgos/plugins/PNETLeptonProducer.cc | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc b/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc index 3e9fbd27b8a4f..de9a466f2e2c0 100644 --- a/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc +++ b/PhysicsTools/PatAlgos/plugins/PNETLeptonProducer.cc @@ -97,19 +97,21 @@ void PNETLeptonProducer::produce(edm::Event &iEvent, const edm::Even edm::Handle> leps; iEvent.getByToken(leps_, leps); - assert(src->size() == leps->size()); - - std::vector> mvaScores(flav_names_.size(), std::vector(src->size(), -1)); - - for (size_t ilep = 0; ilep < src->size(); ilep++) { - const auto &taginfo = (*src)[ilep]; - make_inputs(taginfo); - auto outputs = globalCache()->run(input_names_, data_, input_shapes_)[0]; - // std::cout<<"outputs.size(): "<> mvaScores(flav_names_.size(), std::vector(leps->size(), -1)); + + // tagInfo src could be empty if the event has no PV + if (!src->empty()) { + assert(src->size() == leps->size()); + for (size_t ilep = 0; ilep < src->size(); ilep++) { + const auto &taginfo = (*src)[ilep]; + make_inputs(taginfo); + auto outputs = globalCache()->run(input_names_, data_, input_shapes_)[0]; + // std::cout<<"outputs.size(): "<