From fc26dd8fef202b31dc254f3f1a9e4029bc09bd04 Mon Sep 17 00:00:00 2001 From: Ming-Yan Lee Date: Thu, 9 Nov 2023 18:57:21 +0100 Subject: [PATCH 1/9] feat: move PFNano to customize modules in NANOAOD --- .gitignore | 4 +- PhysicsTools/NanoAOD/BuildFile.xml | 8 + PhysicsTools/NanoAOD/interface/BTV_flavor.h | 7 + PhysicsTools/NanoAOD/plugins/BuildFile.xml | 8 + .../NanoAOD/plugins/DeepJetTableProducer.cc | 669 ++++++++++++++ .../plugins/JetConstituentTableProducer.cc | 311 +++++++ PhysicsTools/NanoAOD/python/custom_btv_cff.py | 826 ++++++++++++++++++ PhysicsTools/NanoAOD/python/nano_cff.py | 2 + 8 files changed, 1834 insertions(+), 1 deletion(-) create mode 100644 PhysicsTools/NanoAOD/interface/BTV_flavor.h create mode 100644 PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/python/custom_btv_cff.py diff --git a/.gitignore b/.gitignore index 18f4f414b9425..c417ee75f908c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,12 +5,14 @@ __init__.py #*# *~ *.pb - +RecoBTag # ignore partially applied patches and their backup *.rej *.orig + + # ignore files under the top level $CMSSW_BASE/src directory, but not its subdirectories /* !/*/ diff --git a/PhysicsTools/NanoAOD/BuildFile.xml b/PhysicsTools/NanoAOD/BuildFile.xml index 20ecb336c0866..e4cfb0e7e70a9 100644 --- a/PhysicsTools/NanoAOD/BuildFile.xml +++ b/PhysicsTools/NanoAOD/BuildFile.xml @@ -2,6 +2,14 @@ + + + + + + + + diff --git a/PhysicsTools/NanoAOD/interface/BTV_flavor.h b/PhysicsTools/NanoAOD/interface/BTV_flavor.h new file mode 100644 index 0000000000000..ac766bb251c34 --- /dev/null +++ b/PhysicsTools/NanoAOD/interface/BTV_flavor.h @@ -0,0 +1,7 @@ +int jet_flavour(const pat::Jet& jet, + const std::vector& gToBB, + const std::vector& gToCC, + const std::vector& neutrinosLepB, + const std::vector& neutrinosLepB_C, + const std::vector& alltaus, + bool usePhysForLightAndUndefined); diff --git a/PhysicsTools/NanoAOD/plugins/BuildFile.xml b/PhysicsTools/NanoAOD/plugins/BuildFile.xml index e833cd0cd4c04..e08787f2c59c3 100644 --- a/PhysicsTools/NanoAOD/plugins/BuildFile.xml +++ b/PhysicsTools/NanoAOD/plugins/BuildFile.xml @@ -26,6 +26,14 @@ + + + + + + + + diff --git a/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc b/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc new file mode 100644 index 0000000000000..ecc62e73c0451 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc @@ -0,0 +1,669 @@ +#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 "RecoBTag/FeatureTools/interface/TrackInfoBuilder.h" + +using namespace btagbtvdeep; + +#include "DataFormats/Math/interface/deltaR.h" + +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" +#include + +// add tag info and a way to go back to the jet reference +#include "FWCore/Framework/interface/makeRefToBaseProdFrom.h" +#include "DataFormats/BTauReco/interface/JetTag.h" +#include "DataFormats/BTauReco/interface/DeepFlavourTagInfo.h" + +// To store the gen info to get the truth flavour of the jet +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" + +#include "PhysicsTools/NanoAOD/interface/BTV_flavor.h" + +template +class DeepJetTableProducer : public edm::stream::EDProducer<> { +public: + explicit DeepJetTableProducer(const edm::ParameterSet &); + ~DeepJetTableProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); + + int jet_flavour(const pat::Jet& jet, + const std::vector& gToBB, + const std::vector& gToCC, + const std::vector& neutrinosLepB, + const std::vector& neutrinosLepB_C, + const std::vector& alltaus, + bool usePhysForLightAndUndefined) { + + int hflav = abs(jet.hadronFlavour()); + int pflav = abs(jet.partonFlavour()); + int physflav = 0; + if ( !( jet.genJet() ) ){ + if (pflav == 0) return 999; + else return 1000; + } + if(jet.genParton()) physflav=abs(jet.genParton()->pdgId()); + std::size_t nbs = jet.jetFlavourInfo().getbHadrons().size(); + std::size_t ncs = jet.jetFlavourInfo().getcHadrons().size(); + + unsigned int nbFromGSP(0); + for (reco::GenParticle p : gToBB) { + double dr2(reco::deltaR2(jet, p)); + if (dr2 < jetR_ * jetR_) ++nbFromGSP; + } + + unsigned int ncFromGSP(0); + for (reco::GenParticle p : gToCC) { + double dr2(reco::deltaR2(jet, p)); + if (dr2 < jetR_ * jetR_) ++ncFromGSP; + } + + //std::cout << " jet pt = " << jet.pt() << " hfl = " << hflav << " pfl = " << pflav << " genpart = " << physflav + // << " nbFromGSP = " << nbFromGSP << " ncFromGSP = " << ncFromGSP + // << " nBhadrons " << nbs << " nCHadrons " << ncs << std::endl; + if(hflav == 5) { //B jet + if(nbs > 1) { + if (nbFromGSP > 0) return 511; + else return 510; + } + else if(nbs == 1) { + for (std::vector::const_iterator it = neutrinosLepB.begin(); it != neutrinosLepB.end(); ++it){ + if(reco::deltaR2(it->eta(),it->phi(),jet.eta(),jet.phi()) < 0.4*0.4) { + return 520; + } + } + for (std::vector::const_iterator it = neutrinosLepB_C.begin(); it != neutrinosLepB_C.end(); ++it){ + if(reco::deltaR2(it->eta(),it->phi(),jet.eta(),jet.phi()) < 0.4*0.4) { + return 521; + } + } + return 500; + } + else { + if(usePhysForLightAndUndefined){ + if(physflav == 21) return 0; + else if(physflav == 3) return 2; + else if(physflav == 2 || physflav ==1) return 1; + else return 1000; + } + else return 1000; + } + } + else if(hflav == 4) { //C jet + if (ncs > 1) { + if (ncFromGSP > 0) return 411; + else return 410; + } + else return 400; + } + else { //not a heavy jet + if(alltaus.size()>0){ //check for tau in a simplistic way + bool ishadrtaucontained=true; + for(const auto& p:alltaus){ + size_t ndau=p.numberOfDaughters(); + for(size_t i=0;ipdgId()); + if(daupid == 13 || daupid == 11){ + ishadrtaucontained=false; + break; + } + if(daupid != 12 && daupid!=14 && daupid!=16 && + reco::deltaR2(*dau,jet) > jetR_*jetR_){ + ishadrtaucontained=false; + break; + } + } + } + if(ishadrtaucontained) return 600; + } + if(std::abs(pflav) == 4 || std::abs(pflav) == 5 || nbs || ncs) { + if(usePhysForLightAndUndefined){ + if(physflav == 21) return 0; + else if(physflav == 3) return 2; + else if(physflav == 2 || physflav ==1) return 1; + else return 1000; + } + else return 1000; + } + else if(usePhysForLightAndUndefined){ + if(physflav == 21) return 0; + else if(physflav == 3) return 2; + else if(physflav == 2 || physflav ==1) return 1; + else return 1000; + } + else { + if(pflav == 21) return 0; + else if(pflav == 3) return 2; + else if(pflav == 2 || pflav ==1) return 1; + else return 1000; + } + } + + } + +private: + void produce(edm::Event &, const edm::EventSetup &) override; + + const std::string nameDeepJet_; + const std::string idx_nameDeepJet_; + const bool storeAK4Truth_; + + + const edm::EDGetTokenT genParticlesToken_; + + edm::EDGetTokenT> jet_token_; + + typedef std::vector TagInfoCollection; + const edm::EDGetTokenT tag_info_src_; + + constexpr static unsigned n_cpf_ = 3; + constexpr static unsigned n_npf_ = 3; + constexpr static unsigned n_sv_ = 4; // 5 + + constexpr static double jetR_ = 0.4; + + constexpr static bool usePhysForLightAndUndefined = false; + + +}; + +// +// constructors and destructor +// +template< typename T> +DeepJetTableProducer::DeepJetTableProducer(const edm::ParameterSet &iConfig) + : nameDeepJet_(iConfig.getParameter("nameDeepJet")), + idx_nameDeepJet_(iConfig.getParameter("idx_nameDeepJet")), + storeAK4Truth_(iConfig.getParameter("storeAK4Truth")), + genParticlesToken_(consumes(iConfig.getParameter("genparticles"))), + jet_token_(consumes>(iConfig.getParameter("jets"))), + tag_info_src_(consumes(iConfig.getParameter("tagInfo_src"))){ + produces(nameDeepJet_); +} + +template< typename T> +DeepJetTableProducer::~DeepJetTableProducer() {} + +template< typename T> +void DeepJetTableProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + // elements in all these collections must have the same order! + + // only necessary to explicitly check correct matching of jets + // std::vector jetIdx_dj; + + edm::Handle genParticlesHandle; + iEvent.getByToken(genParticlesToken_, genParticlesHandle); + + auto jets = iEvent.getHandle(jet_token_); + + edm::Handle tag_infos; + iEvent.getByToken(tag_info_src_, tag_infos); + + + std::vector neutrinosLepB; + std::vector neutrinosLepB_C; + + std::vector gToBB; + std::vector gToCC; + std::vector alltaus; + + + unsigned nJets = jets->size(); + + std::vector jet_N_CPFCands(nJets); + std::vector jet_N_NPFCands(nJets); + std::vector jet_N_PVs(nJets); + std::vector jet_N_SVs(nJets); + + + std::vector jet_FlavSplit(nJets); + + // should default to 0 if less than nCpf cpf with information + std::vector> Cpfcan_BtagPf_trackEtaRel_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackPtRel_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackPPar_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackDeltaR_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackPParRatio_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackSip2dVal_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackSip2dSig_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackSip3dVal_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackSip3dSig_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackJetDistVal_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_ptrel_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_drminsv_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_VTX_ass_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_puppiw_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_chi2_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_quality_nCpf(n_cpf_, std::vector(nJets)); + + + // should default to 0 if less than nNpf npf with information + std::vector> Npfcan_ptrel_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_deltaR_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_isGamma_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_HadFrac_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_drminsv_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_puppiw_nNpf(n_npf_, std::vector(nJets)); + /* + // only after dataformat updated as well + std::vector> Npfcan_etarel_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_phirel_nNpf(n_npf_, std::vector(nJets)); + */ + + + // should default to 0 if less than nSv SVs with information + std::vector> sv_mass_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_pt_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_ntracks_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_chi2_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_normchi2_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_dxy_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_dxysig_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_d3d_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_d3dsig_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_costhetasvpv_nSV(n_sv_, std::vector(nJets)); + /* + // only after dataformat updated as well + std::vector> sv_etarel_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_phirel_nSV(n_sv_, std::vector(nJets)); + */ + std::vector> sv_deltaR_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_enratio_nSV(n_sv_, std::vector(nJets)); + + if (storeAK4Truth_) { + + neutrinosLepB.clear(); + neutrinosLepB_C.clear(); + gToBB.clear(); + gToCC.clear(); + alltaus.clear(); + + for (const reco::Candidate &genC : *genParticlesHandle) { + const reco::GenParticle &gen = static_cast< const reco::GenParticle &>(genC); + if(abs(gen.pdgId())==12||abs(gen.pdgId())==14||abs(gen.pdgId())==16) { + const reco::GenParticle* mother = static_cast< const reco::GenParticle*> (gen.mother()); + if(mother!=NULL) { + if((abs(mother->pdgId())>500&&abs(mother->pdgId())<600)||(abs(mother->pdgId())>5000&&abs(mother->pdgId())<6000)) { + neutrinosLepB.emplace_back(gen); + } + if((abs(mother->pdgId())>400&&abs(mother->pdgId())<500)||(abs(mother->pdgId())>4000&&abs(mother->pdgId())<5000)) { + neutrinosLepB_C.emplace_back(gen); + } + } + else { + std::cout << "No mother" << std::endl; + } + } + + int id(std::abs(gen.pdgId())); + int status(gen.status()); + + if (id == 21 && status >= 21 && status <= 59) { //// Pythia8 hard scatter, ISR, or FSR + if ( gen.numberOfDaughters() == 2 ) { + const reco::Candidate* d0 = gen.daughter(0); + const reco::Candidate* d1 = gen.daughter(1); + if ( std::abs(d0->pdgId()) == 5 && std::abs(d1->pdgId()) == 5 + && d0->pdgId()*d1->pdgId() < 0 && reco::deltaR2(*d0, *d1) < jetR_ * jetR_) gToBB.push_back(gen) ; + if ( std::abs(d0->pdgId()) == 4 && std::abs(d1->pdgId()) == 4 + && d0->pdgId()*d1->pdgId() < 0 && reco::deltaR2(*d0, *d1) < jetR_ * jetR_) gToCC.push_back(gen) ; + } + } + + if(id == 15 && false){ + alltaus.push_back(gen); + } + + } + + } + + if (!tag_infos->empty()) { + + for (unsigned i_jet = 0; i_jet < nJets; ++i_jet) { + + + if (storeAK4Truth_) { + + // from DeepNTuples + const auto &jet = jets->at(i_jet); + + + jet_FlavSplit[i_jet] = jet_flavour(jet, gToBB, gToCC, neutrinosLepB, neutrinosLepB_C, alltaus, usePhysForLightAndUndefined); + + } + + // jet loop reads tag info instead of constituent info + + const auto& taginfo = (*tag_infos)[i_jet]; + const auto& features = taginfo.features(); + + + // jet.pt and jet.eta as well as other jet variables (ShallowTagInfo) already included (via DeepCSV) + + // number of elements in different collections + jet_N_CPFCands[i_jet] = features.c_pf_features.size(); + jet_N_NPFCands[i_jet] = features.n_pf_features.size(); + jet_N_SVs[i_jet] = features.sv_features.size(); + jet_N_PVs[i_jet] = features.npv; + + // c_pf candidates + auto max_c_pf_n = std::min(features.c_pf_features.size(), (std::size_t)n_cpf_); + for (std::size_t c_pf_n = 0; c_pf_n < max_c_pf_n; c_pf_n++) { + const auto& c_pf_features = features.c_pf_features.at(c_pf_n); + Cpfcan_BtagPf_trackEtaRel_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackEtaRel; + Cpfcan_BtagPf_trackPtRel_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPtRel; + Cpfcan_BtagPf_trackPPar_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPPar; + Cpfcan_BtagPf_trackDeltaR_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackDeltaR; + Cpfcan_BtagPf_trackPParRatio_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPParRatio; + Cpfcan_BtagPf_trackSip2dVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip2dVal; + Cpfcan_BtagPf_trackSip2dSig_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip2dSig; + Cpfcan_BtagPf_trackSip3dVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip3dVal; + Cpfcan_BtagPf_trackSip3dSig_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip3dSig; + Cpfcan_BtagPf_trackJetDistVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackJetDistVal; + Cpfcan_ptrel_nCpf[c_pf_n][i_jet] = c_pf_features.ptrel; + Cpfcan_drminsv_nCpf[c_pf_n][i_jet] = c_pf_features.drminsv; + Cpfcan_VTX_ass_nCpf[c_pf_n][i_jet] = c_pf_features.vtx_ass; + Cpfcan_puppiw_nCpf[c_pf_n][i_jet] = c_pf_features.puppiw; + Cpfcan_chi2_nCpf[c_pf_n][i_jet] = c_pf_features.chi2; + Cpfcan_quality_nCpf[c_pf_n][i_jet] = c_pf_features.quality; + } + + // n_pf candidates + auto max_n_pf_n = std::min(features.n_pf_features.size(), (std::size_t)n_npf_); + for (std::size_t n_pf_n = 0; n_pf_n < max_n_pf_n; n_pf_n++) { + const auto& n_pf_features = features.n_pf_features.at(n_pf_n); + Npfcan_ptrel_nNpf[n_pf_n][i_jet] = n_pf_features.ptrel; + Npfcan_deltaR_nNpf[n_pf_n][i_jet] = n_pf_features.deltaR; + Npfcan_isGamma_nNpf[n_pf_n][i_jet] = n_pf_features.isGamma; + Npfcan_HadFrac_nNpf[n_pf_n][i_jet] = n_pf_features.hadFrac; + Npfcan_drminsv_nNpf[n_pf_n][i_jet] = n_pf_features.drminsv; + Npfcan_puppiw_nNpf[n_pf_n][i_jet] = n_pf_features.puppiw; + /* + // only after dataformat updated as well + Npfcan_etarel_nNpf[n_pf_n][i_jet] = n_pf_features.etarel; + Npfcan_phirel_nNpf[n_pf_n][i_jet] = n_pf_features.phirel; + */ + } + + // sv candidates + auto max_sv_n = std::min(features.sv_features.size(), (std::size_t)n_sv_); + for (std::size_t sv_n = 0; sv_n < max_sv_n; sv_n++) { + const auto& sv_features = features.sv_features.at(sv_n); + sv_pt_nSV[sv_n][i_jet] = sv_features.pt; + sv_deltaR_nSV[sv_n][i_jet] = sv_features.deltaR; + sv_mass_nSV[sv_n][i_jet] = sv_features.mass; + sv_ntracks_nSV[sv_n][i_jet] = sv_features.ntracks; + sv_chi2_nSV[sv_n][i_jet] = sv_features.chi2; + sv_normchi2_nSV[sv_n][i_jet] = sv_features.normchi2; + sv_dxy_nSV[sv_n][i_jet] = sv_features.dxy; + sv_dxysig_nSV[sv_n][i_jet] = sv_features.dxysig; + sv_d3d_nSV[sv_n][i_jet] = sv_features.d3d; + sv_d3dsig_nSV[sv_n][i_jet] = sv_features.d3dsig; + sv_costhetasvpv_nSV[sv_n][i_jet] = sv_features.costhetasvpv; + sv_enratio_nSV[sv_n][i_jet] = sv_features.enratio; + /* + // only after dataformat updated as well + sv_etarel_nSV[sv_n][i_jet] = sv_features.etarel; + sv_phirel_nSV[sv_n][i_jet] = sv_features.phirel; + */ + } + } + } + + // DeepJetInputs table + auto djTable = std::make_unique(jet_N_CPFCands.size(), nameDeepJet_, false, true); + //djTable->addColumn("DeepJet_jetIdx", jetIdx_dj, "Index of the parent jet", ); + + + djTable->addColumn("DeepJet_nCpfcand", + jet_N_CPFCands, + "Number of charged PF candidates in the jet" + ); + djTable->addColumn("DeepJet_nNpfcand", + jet_N_NPFCands, + "Number of neutral PF candidates in the jet" + ); + djTable->addColumn("DeepJet_nsv", + jet_N_SVs, + "Number of secondary vertices in the jet" + ); + djTable->addColumn("DeepJet_npv", + jet_N_PVs, + "Number of primary vertices" + ); + + //if (true) { + if (storeAK4Truth_) { + //std::cout << "Start filling table with truth info" << std::endl; + djTable->addColumn("FlavSplit", + jet_FlavSplit, + "Flavour of the jet, numerical codes: " + "isG: 0, " + "isUD: 1, " + "isS: 2, " + "isC: 400, " + "isCC: 410, " + "isGCC: 411, " + "isB: 500, " + "isBB: 510, " + "isGBB: 511, " + "isLeptonicB: 520, " + "isLeptonicB_C: 521, " + "isTAU: 600, " + "isPU: 999," + "isUndefined: 1000. " + "May be combined to form coarse labels for tagger training and flavour dependent attacks using the loss surface." + ); + } + + // ============================================================== Cpfs =================================================================== + for (unsigned int p = 0; p < n_cpf_; p++) { + auto s = std::to_string(p); + + djTable->addColumn("DeepJet_Cpfcan_puppiw_" + s, + Cpfcan_puppiw_nCpf[p], + "charged candidate PUPPI weight of the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_VTX_ass_" + s, + Cpfcan_VTX_ass_nCpf[p], + "integer flag that indicates whether the track was used in the primary vertex fit for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_drminsv_" + s, + Cpfcan_drminsv_nCpf[p], + "track pseudoangular distance from the closest secondary vertex of the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_ptrel_" + s, + Cpfcan_ptrel_nCpf[p], + "fraction of the jet momentum carried by the track for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_quality_" + s, + Cpfcan_quality_nCpf[p], + "integer flag which indicates the quality of the fitted track, based on number of detector hits used for the reconstruction as well as the overall chi2 of the charged track fit for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_chi2_" + s, + Cpfcan_chi2_nCpf[p], + "chi2 of the charged track fit for the " + s + ". cpf", + 10); + + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackDeltaR_" + s, + Cpfcan_BtagPf_trackDeltaR_nCpf[p], + "track pseudoangular distance from the jet axis for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackEtaRel_" + s, + Cpfcan_BtagPf_trackEtaRel_nCpf[p], + "track pseudorapidity, relative to the jet axis for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackJetDistVal_" + s, + Cpfcan_BtagPf_trackJetDistVal_nCpf[p], + "minimum track approach distance to jet axis for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackPPar_" + s, + Cpfcan_BtagPf_trackPPar_nCpf[p], + "dot product of the jet and track momentum for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackPParRatio_" + s, + Cpfcan_BtagPf_trackPParRatio_nCpf[p], + "dot product of the jet and track momentum divided by the magnitude of the jet momentum for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackPtRel_" + s, + Cpfcan_BtagPf_trackPtRel_nCpf[p], + "track transverse momentum, relative to the jet axis for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip2dSig_" + s, + Cpfcan_BtagPf_trackSip2dSig_nCpf[p], + "track 2D signed impact parameter significance for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip3dSig_" + s, + Cpfcan_BtagPf_trackSip3dSig_nCpf[p], + "track 3D signed impact parameter significance for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip2dVal_" + s, + Cpfcan_BtagPf_trackSip2dVal_nCpf[p], + "track 2D signed impact parameter for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip3dVal_" + s, + Cpfcan_BtagPf_trackSip3dVal_nCpf[p], + "track 3D signed impact parameter for the " + s + ". cpf", + 10); + + } + + // ============================================================== Npfs =================================================================== + for (unsigned int p = 0; p < n_npf_; p++) { + auto s = std::to_string(p); + + djTable->addColumn("DeepJet_Npfcan_puppiw_" + s, + Npfcan_puppiw_nNpf[p], + "neutral candidate PUPPI weight for the " + s + ". npf", + 10); + djTable->addColumn("DeepJet_Npfcan_deltaR_" + s, + Npfcan_deltaR_nNpf[p], + "pseudoangular distance between the neutral candidate and the jet axis for the " + s + ". npf", + 10); + djTable->addColumn("DeepJet_Npfcan_drminsv_" + s, + Npfcan_drminsv_nNpf[p], + "pseudoangular distance between the neutral candidate and the closest secondary vertex for the " + s + ". npf", + 10); + djTable->addColumn("DeepJet_Npfcan_HadFrac_" + s, + Npfcan_HadFrac_nNpf[p], + "fraction of the neutral candidate energy deposited in the hadronic calorimeter for the " + s + ". npf", + 10); + djTable->addColumn("DeepJet_Npfcan_ptrel_" + s, + Npfcan_ptrel_nNpf[p], + "fraction of the jet momentum carried by the neutral candidate for the " + s + ". npf", + 10); + djTable->addColumn("DeepJet_Npfcan_isGamma_" + s, + Npfcan_isGamma_nNpf[p], + "integer flag indicating whether the neutral candidate is a photon for the " + s + ". npf", + 10); + /* + // only after dataformat updated as well + djTable->addColumn("DeepJetExtra_Npfcan_etarel_" + s, + Npfcan_etarel_nNpf[p], + "pseudorapidity relative to parent jet for the " + s + ". npf", + 10); + djTable->addColumn("DeepJetExtra_Npfcan_phirel_" + s, + Npfcan_phirel_nNpf[p], + "DeltaPhi(npf, jet) for the " + s + ". npf", + 10); + */ + } + + // ============================================================== SVs =================================================================== + for (unsigned int p = 0; p < n_sv_; p++) { + auto s = std::to_string(p); + + djTable->addColumn("DeepJet_sv_mass_" + s, + sv_mass_nSV[p], + "SV mass of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_pt_" + s, + sv_pt_nSV[p], + "SV pt of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_ntracks_" + s, + sv_ntracks_nSV[p], + "Number of tracks asociated to the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_chi2_" + s, + sv_chi2_nSV[p], + "chi2 of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_normchi2_" + s, + sv_normchi2_nSV[p], + "chi2/dof of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_dxy_" + s, + sv_dxy_nSV[p], + "2D impact parameter (flight distance) value of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_dxysig_" + s, + sv_dxysig_nSV[p], + "2D impact parameter (flight distance) significance of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_d3d_" + s, + sv_d3d_nSV[p], + "3D impact parameter (flight distance) value of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_d3dsig_" + s, + sv_d3dsig_nSV[p], + "3D impact parameter (flight distance) significance of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_costhetasvpv_" + s, + sv_costhetasvpv_nSV[p], + "cosine of the angle between the " + s + ". SV flight direction and the direction of the " + s + ". SV momentum", + 10); + /* + // only after dataformat updated as well + djTable->addColumn("DeepJetExtra_sv_etarel_" + s, + sv_etarel_nSV[p], + "pseudorapidity relative to parent jet for the " + s + ". SV", + 10); + djTable->addColumn("DeepJetExtra_sv_phirel_" + s, + sv_phirel_nSV[p], + "DeltaPhi(sv, jet) for the " + s + ". SV", + 10); + */ + djTable->addColumn("DeepJet_sv_deltaR_" + s, + sv_deltaR_nSV[p], + "pseudoangular distance between jet axis and the " + s + ". SV direction", + 10); + djTable->addColumn("DeepJet_sv_enratio_" + s, + sv_enratio_nSV[p], + "ratio of the " + s + ". SV energy ratio to the jet energy", + 10); + + } + + + iEvent.put(std::move(djTable), nameDeepJet_); + +} + +template< typename T> +void DeepJetTableProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + edm::ParameterSetDescription desc; + desc.add("nameDeepJet", "Jet"); + desc.add("idx_nameDeepJet", "djIdx"); + desc.add("storeAK4Truth", false); + desc.add("genparticles", edm::InputTag("prunedGenParticles")); + desc.add("jets", edm::InputTag("slimmedJetsPuppi")); + desc.add("tagInfo_src", edm::InputTag("pfDeepFlavourTagInfosWithDeepInfo")); + descriptions.addWithDefaultLabel(desc); +} + +typedef DeepJetTableProducer PatJetDeepJetTableProducer; +//typedef DeepJetTableProducer GenJetDeepJetTableProducer; + +DEFINE_FWK_MODULE(PatJetDeepJetTableProducer); +//DEFINE_FWK_MODULE(GenJetDeepJetTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc b/PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc new file mode 100644 index 0000000000000..9874556078a67 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc @@ -0,0 +1,311 @@ +#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/VertexReco/interface/VertexFwd.h" +#include "RecoVertex/VertexTools/interface/VertexDistance3D.h" +#include "RecoVertex/VertexTools/interface/VertexDistanceXY.h" +#include "RecoVertex/VertexPrimitives/interface/ConvertToFromReco.h" +#include "RecoVertex/VertexPrimitives/interface/VertexState.h" + +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/PatCandidates/interface/PackedCandidate.h" + +#include "DataFormats/Candidate/interface/CandidateFwd.h" + +#include "RecoBTag/FeatureTools/interface/TrackInfoBuilder.h" +#include "TrackingTools/Records/interface/TransientTrackRecord.h" + +#include "DataFormats/BTauReco/interface/TrackIPTagInfo.h" +#include "DataFormats/BTauReco/interface/SecondaryVertexTagInfo.h" +#include "RecoBTag/FeatureTools/interface/deep_helpers.h" +#include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h" +using namespace btagbtvdeep; + +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" +#include "DataFormats/NanoAOD/interface/FlatTable.h" + +template +class JetConstituentTableProducer : public edm::stream::EDProducer<> { +public: + explicit JetConstituentTableProducer(const edm::ParameterSet &); + ~JetConstituentTableProducer() override; + + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); + +private: + void produce(edm::Event &, const edm::EventSetup &) override; + + typedef reco::VertexCollection VertexCollection; + //===== + typedef reco::VertexCompositePtrCandidateCollection SVCollection; + + //const std::string name_; + const std::string name_; + const std::string nameSV_; + const std::string idx_name_; + const std::string idx_nameSV_; + const bool readBtag_; + const double jet_radius_; + + edm::EDGetTokenT> jet_token_; + edm::EDGetTokenT vtx_token_; + edm::EDGetTokenT cand_token_; + edm::EDGetTokenT sv_token_; + + edm::Handle vtxs_; + edm::Handle cands_; + edm::Handle svs_; + edm::ESHandle track_builder_; + edm::ESGetToken track_builder_token_; + + const reco::Vertex *pv_ = nullptr; + +}; + +// +// constructors and destructor +// +template< typename T> +JetConstituentTableProducer::JetConstituentTableProducer(const edm::ParameterSet &iConfig) + : name_(iConfig.getParameter("name")), + nameSV_(iConfig.getParameter("nameSV")), + idx_name_(iConfig.getParameter("idx_name")), + idx_nameSV_(iConfig.getParameter("idx_nameSV")), + readBtag_(iConfig.getParameter("readBtag")), + jet_radius_(iConfig.getParameter("jet_radius")), + jet_token_(consumes>(iConfig.getParameter("jets"))), + vtx_token_(consumes(iConfig.getParameter("vertices"))), + cand_token_(consumes(iConfig.getParameter("candidates"))), + sv_token_(consumes(iConfig.getParameter("secondary_vertices"))), + track_builder_token_( + esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))){ + produces(name_); + produces(nameSV_); + produces>(); +} + +template< typename T> +JetConstituentTableProducer::~JetConstituentTableProducer() {} + +template< typename T> +void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { + // elements in all these collections must have the same order! + auto outCands = std::make_unique>(); + auto outSVs = std::make_unique> (); + std::vector jetIdx_pf, jetIdx_sv, pfcandIdx, svIdx; + // PF Cands + std::vector btagEtaRel, btagPtRatio, btagPParRatio, btagSip3dVal, btagSip3dSig, btagJetDistVal, btagDecayLenVal, cand_pt, cand_dzFromPV, cand_dxyFromPV, cand_dzErrFromPV, cand_dxyErrFromPV; + // Secondary vertices + std::vector sv_mass, sv_pt, sv_ntracks, sv_chi2, sv_normchi2, sv_dxy, sv_dxysig, sv_d3d, sv_d3dsig, sv_costhetasvpv; + std::vector sv_ptrel, sv_phirel, sv_deltaR, sv_enratio; + + auto jets = iEvent.getHandle(jet_token_); + iEvent.getByToken(vtx_token_, vtxs_); + iEvent.getByToken(cand_token_, cands_); + iEvent.getByToken(sv_token_, svs_); + + if(readBtag_){ + track_builder_ = iSetup.getHandle(track_builder_token_); + } + + for (unsigned i_jet = 0; i_jet < jets->size(); ++i_jet) { + const auto &jet = jets->at(i_jet); + math::XYZVector jet_dir = jet.momentum().Unit(); + GlobalVector jet_ref_track_dir(jet.px(), jet.py(), jet.pz()); + VertexDistance3D vdist; + + pv_ = &vtxs_->at(0); + + ////////////////////// + // Secondary Vertices + std::vector jetSVs; + std::vector allSVs; + for (const auto &sv : *svs_) { + // Factor in cuts in NanoAOD for indexing + Measurement1D dl= vdist.distance(vtxs_->front(), VertexState(RecoVertex::convertPos(sv.position()),RecoVertex::convertError(sv.error()))); + if(dl.significance() > 3){ + allSVs.push_back(&sv); + } + if (reco::deltaR2(sv, jet) < jet_radius_ * jet_radius_) { + jetSVs.push_back(&sv); + } + } + // sort by dxy significance + std::sort(jetSVs.begin(), + jetSVs.end(), + [&](const reco::VertexCompositePtrCandidate *sva, const reco::VertexCompositePtrCandidate *svb) { + return sv_vertex_comparator(*sva, *svb, *pv_); + }); + + for (const auto &sv : jetSVs) { + // auto svPtrs = svs_->ptrs(); + auto svInNewList = std::find(allSVs.begin(), allSVs.end(), sv ); + if (svInNewList == allSVs.end()) { + // continue; + svIdx.push_back(-1); + } else{ + svIdx.push_back(svInNewList - allSVs.begin()); + } + outSVs->push_back(sv); + jetIdx_sv.push_back(i_jet); + if (readBtag_ && !vtxs_->empty()) { + // Jet independent + sv_mass.push_back(sv->mass()); + sv_pt.push_back(sv->pt()); + + sv_ntracks.push_back(sv->numberOfDaughters()); + sv_chi2.push_back(sv->vertexChi2()); + sv_normchi2.push_back(catch_infs_and_bound(sv->vertexChi2() / sv->vertexNdof(), 1000, -1000, 1000)); + const auto& dxy_meas = vertexDxy(*sv, *pv_); + sv_dxy.push_back(dxy_meas.value()); + sv_dxysig.push_back(catch_infs_and_bound(dxy_meas.value() / dxy_meas.error(), 0, -1, 800)); + const auto& d3d_meas = vertexD3d(*sv, *pv_); + sv_d3d.push_back(d3d_meas.value()); + sv_d3dsig.push_back(catch_infs_and_bound(d3d_meas.value() / d3d_meas.error(), 0, -1, 800)); + sv_costhetasvpv.push_back(vertexDdotP(*sv, *pv_)); + // Jet related + sv_ptrel.push_back(sv->pt() / jet.pt()); + sv_phirel.push_back(reco::deltaPhi(*sv, jet)); + sv_deltaR.push_back(catch_infs_and_bound(std::fabs(reco::deltaR(*sv, jet_dir)) - 0.5, 0, -2, 0)); + sv_enratio.push_back(sv->energy() / jet.energy()); + } + } + + // PF Cands + std::vector const & daughters = jet.daughterPtrVector(); + + for (const auto &cand : daughters) { + auto candPtrs = cands_->ptrs(); + auto candInNewList = std::find( candPtrs.begin(), candPtrs.end(), cand ); + if ( candInNewList == candPtrs.end() ) { + //std::cout << "Cannot find candidate : " << cand.id() << ", " << cand.key() << ", pt = " << cand->pt() << std::endl; + continue; + } + outCands->push_back(cand); + jetIdx_pf.push_back(i_jet); + pfcandIdx.push_back(candInNewList - candPtrs.begin()); + cand_pt.push_back(cand->pt()); + auto const *packedCand = dynamic_cast (cand.get()); + if (packedCand && packedCand->hasTrackDetails()) { + const reco::Track* track_ptr = &(packedCand->pseudoTrack()); + cand_dzFromPV.push_back(track_ptr->dz(pv_->position())); + cand_dxyFromPV.push_back(track_ptr->dxy(pv_->position())); + cand_dzErrFromPV.push_back(std::hypot(track_ptr->dzError(), pv_->zError())); + cand_dxyErrFromPV.push_back(track_ptr->dxyError(pv_->position(), pv_->covariance())); + } else { + cand_dzFromPV.push_back(-1); + cand_dxyFromPV.push_back(-1); + cand_dzErrFromPV.push_back(-1); + cand_dxyErrFromPV.push_back(-1); + } + + if (readBtag_ && !vtxs_->empty()) { + if ( cand.isNull() ) continue; + auto const *packedCand = dynamic_cast (cand.get()); + if ( packedCand == nullptr ) continue; + if ( packedCand && packedCand->hasTrackDetails()){ + btagbtvdeep::TrackInfoBuilder trkinfo(track_builder_); + trkinfo.buildTrackInfo(&(*packedCand), jet_dir, jet_ref_track_dir, vtxs_->at(0)); + btagEtaRel.push_back(trkinfo.getTrackEtaRel()); + btagPtRatio.push_back(trkinfo.getTrackPtRatio()); + btagPParRatio.push_back(trkinfo.getTrackPParRatio()); + btagSip3dVal.push_back(trkinfo.getTrackSip3dVal()); + btagSip3dSig.push_back(trkinfo.getTrackSip3dSig()); + btagJetDistVal.push_back(trkinfo.getTrackJetDistVal()); + // decay length + const reco::Track* track_ptr = packedCand->bestTrack(); + reco::TransientTrack transient_track = track_builder_->build(track_ptr); + double decayLength = -1; + TrajectoryStateOnSurface closest = IPTools::closestApproachToJet(transient_track.impactPointState(), *pv_, jet_ref_track_dir, transient_track.field()); + if (closest.isValid()) + decayLength = (closest.globalPosition() - RecoVertex::convertPos(pv_->position())).mag(); + else + decayLength = -1; + btagDecayLenVal.push_back(decayLength); + } else { + btagEtaRel.push_back(0); + btagPtRatio.push_back(0); + btagPParRatio.push_back(0); + btagSip3dVal.push_back(0); + btagSip3dSig.push_back(0); + btagJetDistVal.push_back(0); + btagDecayLenVal.push_back(0); + } + } + } // end jet loop + } + + auto candTable = std::make_unique(outCands->size(), name_, false); + // We fill from here only stuff that cannot be created with the SimpleFlatTableProducer + candTable->addColumn(idx_name_, pfcandIdx, "Index in the candidate list"); + candTable->addColumn("jetIdx", jetIdx_pf, "Index of the parent jet"); + if (readBtag_) { + candTable->addColumn("pt", cand_pt, "pt", 10); // to check matchind down the line + candTable->addColumn("dzFromPV", cand_dzFromPV, "dzFromPV", 10); + candTable->addColumn("dxyFromPV", cand_dxyFromPV, "dxyFromPV", 10); + candTable->addColumn("dzErrFromPV", cand_dzErrFromPV, "dzErrFromPV", 10); + candTable->addColumn("dxyErrFromPV", cand_dxyErrFromPV, "dxyErrFromPV", 10); + candTable->addColumn("btagEtaRel", btagEtaRel, "btagEtaRel", 10); + candTable->addColumn("btagPtRatio", btagPtRatio, "btagPtRatio", 10); + candTable->addColumn("btagPParRatio", btagPParRatio, "btagPParRatio", 10); + candTable->addColumn("btagSip3dVal", btagSip3dVal, "btagSip3dVal", 10); + candTable->addColumn("btagSip3dSig", btagSip3dSig, "btagSip3dSig", 10); + candTable->addColumn("btagJetDistVal", btagJetDistVal, "btagJetDistVal", 10); + candTable->addColumn("btagDecayLenVal", btagDecayLenVal, "btagDecayLenVal", 10); + } + iEvent.put(std::move(candTable), name_); + + // SV table + auto svTable = std::make_unique(outSVs->size(), nameSV_, false); + // We fill from here only stuff that cannot be created with the SimpleFlatTnameableProducer + svTable->addColumn("jetIdx", jetIdx_sv, "Index of the parent jet"); + svTable->addColumn(idx_nameSV_, svIdx, "Index in the SV list"); + if (readBtag_) { + svTable->addColumn("mass", sv_mass, "SV mass", 10); + svTable->addColumn("pt", sv_pt, "SV pt", 10); + svTable->addColumn("ntracks", sv_ntracks, "Number of tracks associated to SV", 10); + svTable->addColumn("chi2", sv_chi2, "chi2", 10); + svTable->addColumn("normchi2", sv_normchi2, "chi2/ndof", 10); + svTable->addColumn("dxy", sv_dxy, "", 10); + svTable->addColumn("dxysig", sv_dxysig, "", 10); + svTable->addColumn("d3d", sv_d3d, "", 10); + svTable->addColumn("d3dsig", sv_d3dsig, "", 10); + svTable->addColumn("costhetasvpv", sv_costhetasvpv, "", 10); + // Jet related + svTable->addColumn("phirel", sv_phirel, "DeltaPhi(sv, jet)", 10); + svTable->addColumn("ptrel", sv_ptrel, "pT relative to parent jet", 10); + svTable->addColumn("deltaR", sv_deltaR, "dR from parent jet", 10); + svTable->addColumn("enration", sv_enratio, "energy relative to parent jet", 10); + } + iEvent.put(std::move(svTable), nameSV_); + + iEvent.put(std::move(outCands)); +} + +template< typename T> +void JetConstituentTableProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + edm::ParameterSetDescription desc; + desc.add("name", "JetPFCands"); + desc.add("nameSV", "JetSV"); + desc.add("idx_name", "candIdx"); + desc.add("idx_nameSV", "svIdx"); + desc.add("jet_radius", true); + desc.add("readBtag", true); + desc.add("jets", edm::InputTag("slimmedJetsAK8")); + desc.add("vertices", edm::InputTag("offlineSlimmedPrimaryVertices")); + desc.add("candidates", edm::InputTag("packedPFCandidates")); + desc.add("secondary_vertices", edm::InputTag("slimmedSecondaryVertices")); + descriptions.addWithDefaultLabel(desc); +} + +typedef JetConstituentTableProducer PatJetConstituentTableProducer; +typedef JetConstituentTableProducer GenJetConstituentTableProducer; + +DEFINE_FWK_MODULE(PatJetConstituentTableProducer); +DEFINE_FWK_MODULE(GenJetConstituentTableProducer); diff --git a/PhysicsTools/NanoAOD/python/custom_btv_cff.py b/PhysicsTools/NanoAOD/python/custom_btv_cff.py new file mode 100644 index 0000000000000..e35aa80f52a45 --- /dev/null +++ b/PhysicsTools/NanoAOD/python/custom_btv_cff.py @@ -0,0 +1,826 @@ +import FWCore.ParameterSet.Config as cms +from PhysicsTools.NanoAOD.common_cff import Var +#from PhysicsTools.NanoAOD.jetsAK4_CHS_cff import jetTable, jetCorrFactorsNano, updatedJets, finalJets, qgtagger, hfJetShowerShapeforNanoAOD +from PhysicsTools.NanoAOD.jetsAK4_Puppi_cff import jetPuppiTable, jetPuppiCorrFactorsNano, updatedJetsPuppi, updatedJetsPuppiWithUserData +from PhysicsTools.NanoAOD.jetsAK8_cff import fatJetTable, subJetTable +from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection +from PhysicsTools.PatAlgos.tools.helpers import addToProcessAndTask, getPatAlgosToolsTask +from PhysicsTools.NanoAOD.common_cff import Var, CandVars + + + +def update_jets_AK4(process): + # Based on ``nanoAOD_addDeepInfo`` + # in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/nano_cff.py + # DeepJet flav_names as found in + # https://github.com/cms-sw/cmssw/blob/master/RecoBTag/ONNXRuntime/plugins/DeepFlavourONNXJetTagsProducer.cc#L86 + # and https://twiki.cern.ch/twiki/bin/view/CMS/DeepJet + from RecoBTag.ONNXRuntime.pfParticleTransformerAK4_cff import _pfParticleTransformerAK4JetTagsAll as pfParticleTransformerAK4JetTagsAll + from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import _pfParticleNetFromMiniAODAK4PuppiCentralJetTagsAll as pfParticleNetFromMiniAODAK4PuppiCentralJetTagsAll + from RecoBTag.ONNXRuntime.pfParticleTransformerAK4_cff import _pfNegativeParticleTransformerAK4JetTagsProbs as pfNegativeParticleTransformerAK4JetTagsProbs + from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import _pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs as pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs + + _btagDiscriminators = [ + 'pfJetProbabilityBJetTags', + 'pfJetBProbabilityBJetTags', + 'pfNegativeOnlyJetProbabilityBJetTags', + 'pfNegativeOnlyJetBProbabilityBJetTags', + 'pfDeepCSVJetTags:probb', + 'pfDeepCSVJetTags:probc', + 'pfDeepCSVJetTags:probbb', + 'pfDeepCSVJetTags:probudsg', + 'pfDeepFlavourJetTags:probb', + 'pfDeepFlavourJetTags:probbb', + 'pfDeepFlavourJetTags:problepb', + 'pfDeepFlavourJetTags:probc', + 'pfDeepFlavourJetTags:probuds', + 'pfDeepFlavourJetTags:probg', + 'pfNegativeDeepFlavourJetTags:probb', + 'pfNegativeDeepFlavourJetTags:probbb', + 'pfNegativeDeepFlavourJetTags:problepb', + 'pfNegativeDeepFlavourJetTags:probc', + 'pfNegativeDeepFlavourJetTags:probuds', + 'pfNegativeDeepFlavourJetTags:probg', + ] + pfParticleTransformerAK4JetTagsAll + pfNegativeParticleTransformerAK4JetTagsProbs \ + + pfParticleNetFromMiniAODAK4PuppiCentralJetTagsAll + pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs + + updateJetCollection( + process, + jetSource=cms.InputTag('slimmedJetsPuppi'), + jetCorrections=('AK4PFPuppi', + cms.vstring( + ['L1FastJet', 'L2Relative', 'L3Absolute', + 'L2L3Residual']), 'None'), + btagDiscriminators=_btagDiscriminators, + postfix='WithDeepInfo', + ) + process.load("Configuration.StandardSequences.MagneticField_cff") + process.jetPuppiCorrFactorsNano.src = "selectedUpdatedPatJetsWithDeepInfo" + process.updatedJetsPuppi.jetSource = "selectedUpdatedPatJetsWithDeepInfo" + + process.updatedPatJetsTransientCorrectedWithDeepInfo.tagInfoSources.append(cms.InputTag("pfDeepCSVTagInfosWithDeepInfo")) + process.updatedPatJetsTransientCorrectedWithDeepInfo.tagInfoSources.append(cms.InputTag("pfDeepFlavourTagInfosWithDeepInfo")) + + + process.updatedPatJetsTransientCorrectedWithDeepInfo.addTagInfos = cms.bool(True) + + + return process + + +def update_jets_AK8(process): + # Based on ``nanoAOD_addDeepInfoAK8`` + # in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/nano_cff.py + # Care needs to be taken to make sure no discriminators from stock Nano are excluded -> would results in unfilled vars + _btagDiscriminators = [ + 'pfJetProbabilityBJetTags', + 'pfDeepCSVJetTags:probb', + 'pfDeepCSVJetTags:probc', + 'pfDeepCSVJetTags:probbb', + 'pfDeepCSVJetTags:probudsg', + 'pfMassIndependentDeepDoubleBvLJetTags:probHbb', + 'pfMassIndependentDeepDoubleCvLJetTags:probHcc', + 'pfMassIndependentDeepDoubleCvBJetTags:probHcc', + 'pfMassIndependentDeepDoubleBvLV2JetTags:probHbb', + 'pfMassIndependentDeepDoubleCvLV2JetTags:probHcc', + 'pfMassIndependentDeepDoubleCvBV2JetTags:probHcc', + ] + from RecoBTag.ONNXRuntime.pfParticleNet_cff import _pfParticleNetJetTagsAll as pfParticleNetJetTagsAll + _btagDiscriminators += pfParticleNetJetTagsAll + updateJetCollection( + process, + jetSource=cms.InputTag('slimmedJetsAK8'), + pvSource=cms.InputTag('offlineSlimmedPrimaryVertices'), + svSource=cms.InputTag('slimmedSecondaryVertices'), + rParam=0.8, + jetCorrections=('AK8PFPuppi', + cms.vstring([ + 'L1FastJet', 'L2Relative', 'L3Absolute', + 'L2L3Residual' + ]), 'None'), + btagDiscriminators=_btagDiscriminators, + postfix='AK8WithDeepInfo', + # this should work but doesn't seem to enable the tag info with addTagInfos + # btagInfos=['pfDeepDoubleXTagInfos'], + printWarning=False) + process.jetCorrFactorsAK8.src = "selectedUpdatedPatJetsAK8WithDeepInfo" + process.updatedJetsAK8.jetSource = "selectedUpdatedPatJetsAK8WithDeepInfo" + # add DeepDoubleX taginfos + process.updatedPatJetsTransientCorrectedAK8WithDeepInfo.tagInfoSources.append(cms.InputTag("pfDeepDoubleXTagInfosAK8WithDeepInfo")) + process.updatedPatJetsTransientCorrectedAK8WithDeepInfo.addTagInfos = cms.bool(True) + return process + + +def update_jets_AK8_subjet(process): + # Based on ``nanoAOD_addDeepInfoAK8`` + # in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/nano_cff.py + # and https://github.com/alefisico/RecoBTag-PerformanceMeasurements/blob/10_2_X_boostedCommissioning/test/runBTagAnalyzer_cfg.py + _btagDiscriminators = [ + 'pfJetProbabilityBJetTags', + 'pfDeepCSVJetTags:probb', + 'pfDeepCSVJetTags:probc', + 'pfDeepCSVJetTags:probbb', + 'pfDeepCSVJetTags:probudsg', + ] + updateJetCollection( + process, + labelName='SoftDropSubjetsPF', + jetSource=cms.InputTag("slimmedJetsAK8PFPuppiSoftDropPacked", "SubJets"), + jetCorrections=('AK4PFPuppi', + ['L2Relative', 'L3Absolute'], 'None'), + btagDiscriminators=list(_btagDiscriminators), + explicitJTA=True, # needed for subjet b tagging + svClustering=False, # needed for subjet b tagging (IMPORTANT: Needs to be set to False to disable ghost-association which does not work with slimmed jets) + fatJets=cms.InputTag('slimmedJetsAK8'), # needed for subjet b tagging + rParam=0.8, # needed for subjet b tagging + sortByPt=False, # Don't change order (would mess with subJetIdx for FatJets) + postfix='AK8SubjetsWithDeepInfo') + + process.subJetTable.src = 'selectedUpdatedPatJetsSoftDropSubjetsPFAK8SubjetsWithDeepInfo' + + + return process + +def get_DDX_vars(): + # retreive 27 jet-level features used in double-b and deep double-x taggers + # defined in arXiv:1712.07158 + DDXVars = cms.PSet( + DDX_jetNTracks = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.jetNTracks", int, doc="number of tracks associated with the jet"), + DDX_jetNSecondaryVertices = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.jetNSecondaryVertices", int, doc="number of SVs associated with the jet"), + DDX_tau1_trackEtaRel_0 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_trackEtaRel_0", float, doc="1st smallest track pseudorapidity, relative to the jet axis, associated to the 1st N-subjettiness axis", precision=10), + DDX_tau1_trackEtaRel_1 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_trackEtaRel_1", float, doc="2nd smallest track pseudorapidity, relative to the jet axis, associated to the 1st N-subjettiness axis", precision=10), + DDX_tau1_trackEtaRel_2 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_trackEtaRel_2", float, doc="3rd smallest track pseudorapidity, relative to the jet axis, associated to the 1st N-subjettiness axis", precision=10), + DDX_tau2_trackEtaRel_0 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau2_trackEtaRel_0", float, doc="1st smallest track pseudorapidity, relative to the jet axis, associated to the 2nd N-subjettiness axis", precision=10), + DDX_tau2_trackEtaRel_1 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau2_trackEtaRel_1", float, doc="2nd smallest track pseudorapidity, relative to the jet axis, associated to the 2nd N-subjettiness axis", precision=10), + DDX_tau2_trackEtaRel_3 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau2_trackEtaRel_2", float, doc="3rd smallest track pseudorapidity, relative to the jet axis, associated to the 2nd N-subjettiness axis", precision=10), + DDX_tau1_flightDistance2dSig = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_flightDistance2dSig", float, doc="transverse distance significance between primary and secondary vertex associated to the 1st N-subjettiness axis", precision=10), + DDX_tau2_flightDistance2dSig = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau2_flightDistance2dSig", float, doc="transverse distance significance between primary and secondary vertex associated to the 2nd N-subjettiness axis", precision=10), + DDX_tau1_vertexDeltaR = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_vertexDeltaR", float, doc="deltaR between the 1st N-subjettiness axis and secondary vertex direction", precision=10), + DDX_tau1_vertexEnergyRatio = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_vertexEnergyRatio", float, doc="ratio of energy at secondary vertex over total energy associated to the 1st N-subjettiness axis", precision=10), + DDX_tau2_vertexEnergyRatio = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau2_vertexEnergyRatio", float, doc="ratio of energy at secondary vertex over total energy associated to the 2nd N-subjettiness axis", precision=10), + DDX_tau1_vertexMass = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_vertexMass", float, doc="mass of track sum at secondary vertex associated to the 1st N-subjettiness axis", precision=10), + DDX_tau2_vertexMass = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau2_vertexMass", float, doc="mass of track sum at secondary vertex associated to the 2nd N-subjettiness axis", precision=10), + DDX_trackSip2dSigAboveBottom_0 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.trackSip2dSigAboveBottom_0", float, doc="track 2D signed impact parameter significance of 1st track lifting mass above bottom", precision=10), + DDX_trackSip2dSigAboveBottom_1 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.trackSip2dSigAboveBottom_1", float, doc="track 2D signed impact parameter significance of 2nd track lifting mass above bottom", precision=10), + DDX_trackSip2dSigAboveCharm = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.trackSip2dSigAboveCharm", float, doc="track 2D signed impact parameter significance of 1st track lifting mass above charm", precision=10), + DDX_trackSip3dSig_0 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.trackSip3dSig_0", float, doc="1st largest track 3D signed impact parameter significance", precision=10), + DDX_tau1_trackSip3dSig_0 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_trackSip3dSig_0", float, doc="1st largest track 3D signed impact parameter significance associated to the 1st N-subjettiness axis", precision=10), + DDX_tau1_trackSip3dSig_1 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau1_trackSip3dSig_1", float, doc="2nd largest track 3D signed impact parameter significance associated to the 1st N-subjettiness axis", precision=10), + DDX_trackSip3dSig_1 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.trackSip3dSig_1", float, doc="2nd largest track 3D signed impact parameter significance", precision=10), + DDX_tau2_trackSip3dSig_0 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau2_trackSip3dSig_0", float, doc="1st largest track 3D signed impact parameter significance associated to the 2nd N-subjettiness axis", precision=10), + DDX_tau2_trackSip3dSig_1 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.tau2_trackSip3dSig_1", float, doc="2nd largest track 3D signed impact parameter significance associated to the 2nd N-subjettiness axis", precision=10), + DDX_trackSip3dSig_2 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.trackSip3dSig_2", float, doc="3rd largest track 3D signed impact parameter significance", precision=10), + DDX_trackSip3dSig_3 = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.trackSip3dSig_3", float, doc="4th largest track 3D signed impact parameter significance", precision=10), + DDX_z_ratio = Var("tagInfo(\'pfDeepDoubleX\').features().tag_info_features.z_ratio", float, doc="z = deltaR(SV0,SV1)*pT(SV1)/m(SV0,SV1), defined in Eq. 7 of arXiv:1712.07158", precision=10) + ) + return DDXVars + +def get_DeepCSV_vars(): + DeepCSVVars = cms.PSet( + # Tagger inputs also include jet pt and eta + # Track based (keep only jet-based features for DeepCSV from Run 3 commissioning) + # DeepCSV_trackPtRel_0 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRel\')[0]:-999", float, doc="track transverse momentum, relative to the jet axis", precision=10), + # DeepCSV_trackPtRel_1 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRel\')[1]:-999", float, doc="track transverse momentum, relative to the jet axis", precision=10), + # DeepCSV_trackPtRel_2 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRel\')[2]:-999", float, doc="track transverse momentum, relative to the jet axis", precision=10), + # DeepCSV_trackPtRel_3 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRel\')[3]:-999", float, doc="track transverse momentum, relative to the jet axis", precision=10), + # DeepCSV_trackPtRel_4 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRel\')[4]:-999", float, doc="track transverse momentum, relative to the jet axis", precision=10), + # DeepCSV_trackPtRel_5 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRel\')[5]:-999", float, doc="track transverse momentum, relative to the jet axis", precision=10), + # DeepCSV_trackJetDistVal_0 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackJetDistVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackJetDistVal\')[0]:-999", float, doc="minimum track approach distance to jet axis", precision=10), + # DeepCSV_trackJetDistVal_1 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackJetDistVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackJetDistVal\')[1]:-999", float, doc="minimum track approach distance to jet axis", precision=10), + # DeepCSV_trackJetDistVal_2 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackJetDistVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackJetDistVal\')[2]:-999", float, doc="minimum track approach distance to jet axis", precision=10), + # DeepCSV_trackJetDistVal_3 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackJetDistVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackJetDistVal\')[3]:-999", float, doc="minimum track approach distance to jet axis", precision=10), + # DeepCSV_trackJetDistVal_4 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackJetDistVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackJetDistVal\')[4]:-999", float, doc="minimum track approach distance to jet axis", precision=10), + # DeepCSV_trackJetDistVal_5 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackJetDistVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackJetDistVal\')[5]:-999", float, doc="minimum track approach distance to jet axis", precision=10), + # DeepCSV_trackDeltaR_0 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDeltaR\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDeltaR\')[0]:-999", float, doc="track pseudoangular distance from the jet axis", precision=10), + # DeepCSV_trackDeltaR_1 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDeltaR\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDeltaR\')[1]:-999", float, doc="track pseudoangular distance from the jet axis", precision=10), + # DeepCSV_trackDeltaR_2 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDeltaR\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDeltaR\')[2]:-999", float, doc="track pseudoangular distance from the jet axis", precision=10), + # DeepCSV_trackDeltaR_3 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDeltaR\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDeltaR\')[3]:-999", float, doc="track pseudoangular distance from the jet axis", precision=10), + # DeepCSV_trackDeltaR_4 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDeltaR\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDeltaR\')[4]:-999", float, doc="track pseudoangular distance from the jet axis", precision=10), + # DeepCSV_trackDeltaR_5 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDeltaR\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDeltaR\')[5]:-999", float, doc="track pseudoangular distance from the jet axis", precision=10), + # DeepCSV_trackPtRatio_0 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRatio\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRatio\')[0]:-999", float, doc="track transverse momentum, relative to the jet axis, normalized to its energy", precision=10), + # DeepCSV_trackPtRatio_1 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRatio\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRatio\')[1]:-999", float, doc="track transverse momentum, relative to the jet axis, normalized to its energy", precision=10), + # DeepCSV_trackPtRatio_2 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRatio\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRatio\')[2]:-999", float, doc="track transverse momentum, relative to the jet axis, normalized to its energy", precision=10), + # DeepCSV_trackPtRatio_3 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRatio\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRatio\')[3]:-999", float, doc="track transverse momentum, relative to the jet axis, normalized to its energy", precision=10), + # DeepCSV_trackPtRatio_4 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRatio\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRatio\')[4]:-999", float, doc="track transverse momentum, relative to the jet axis, normalized to its energy", precision=10), + # DeepCSV_trackPtRatio_5 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackPtRatio\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackPtRatio\')[5]:-999", float, doc="track transverse momentum, relative to the jet axis, normalized to its energy", precision=10), + # DeepCSV_trackSip3dSig_0 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip3dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip3dSig\')[0]:-999", float, doc="track 3D signed impact parameter significance", precision=10), + # DeepCSV_trackSip3dSig_1 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip3dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip3dSig\')[1]:-999", float, doc="track 3D signed impact parameter significance", precision=10), + # DeepCSV_trackSip3dSig_2 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip3dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip3dSig\')[2]:-999", float, doc="track 3D signed impact parameter significance", precision=10), + # DeepCSV_trackSip3dSig_3 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip3dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip3dSig\')[3]:-999", float, doc="track 3D signed impact parameter significance", precision=10), + # DeepCSV_trackSip3dSig_4 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip3dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip3dSig\')[4]:-999", float, doc="track 3D signed impact parameter significance", precision=10), + # DeepCSV_trackSip3dSig_5 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip3dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip3dSig\')[5]:-999", float, doc="track 3D signed impact parameter significance", precision=10), + # DeepCSV_trackSip2dSig_0 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip2dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip2dSig\')[0]:-999", float, doc="track 2D signed impact parameter significance", precision=10), + # DeepCSV_trackSip2dSig_1 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip2dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip2dSig\')[1]:-999", float, doc="track 2D signed impact parameter significance", precision=10), + # DeepCSV_trackSip2dSig_2 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip2dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip2dSig\')[2]:-999", float, doc="track 2D signed impact parameter significance", precision=10), + # DeepCSV_trackSip2dSig_3 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip2dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip2dSig\')[3]:-999", float, doc="track 2D signed impact parameter significance", precision=10), + # DeepCSV_trackSip2dSig_4 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip2dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip2dSig\')[4]:-999", float, doc="track 2D signed impact parameter significance", precision=10), + # DeepCSV_trackSip2dSig_5 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackSip2dSig\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackSip2dSig\')[5]:-999", float, doc="track 2D signed impact parameter significance", precision=10), + # DeepCSV_trackDecayLenVal_0 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDecayLenVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDecayLenVal\')[0]:-999", float, doc="track decay length", precision=10), + # DeepCSV_trackDecayLenVal_1 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDecayLenVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDecayLenVal\')[1]:-999", float, doc="track decay length", precision=10), + # DeepCSV_trackDecayLenVal_2 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDecayLenVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDecayLenVal\')[2]:-999", float, doc="track decay length", precision=10), + # DeepCSV_trackDecayLenVal_3 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDecayLenVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDecayLenVal\')[3]:-999", float, doc="track decay length", precision=10), + # DeepCSV_trackDecayLenVal_4 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDecayLenVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDecayLenVal\')[4]:-999", float, doc="track decay length", precision=10), + # DeepCSV_trackDecayLenVal_5 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackDecayLenVal\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackDecayLenVal\')[5]:-999", float, doc="track decay length", precision=10), + # DeepCSV_trackEtaRel_0 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackEtaRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackEtaRel\')[0]:-999", float, doc="track pseudorapidity, relative to the jet axis", precision=10), + # DeepCSV_trackEtaRel_1 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackEtaRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackEtaRel\')[1]:-999", float, doc="track pseudorapidity, relative to the jet axis", precision=10), + # DeepCSV_trackEtaRel_2 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackEtaRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackEtaRel\')[2]:-999", float, doc="track pseudorapidity, relative to the jet axis", precision=10), + # DeepCSV_trackEtaRel_3 = Var("?tagInfo(\'pfDeepCSV\').taggingVariables.checkTag(\'trackEtaRel\')?tagInfo(\'pfDeepCSV\').taggingVariables.getList(\'trackEtaRel\')[3]:-999", float, doc="track pseudorapidity, relative to the jet axis", precision=10), + # Jet based + DeepCSV_trackJetPt = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'trackJetPt\', -999)", float, doc="track-based jet transverse momentum", precision=10), + DeepCSV_vertexCategory = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'vertexCategory\', -999)", float, doc="category of secondary vertex (Reco, Pseudo, No)", precision=10), + DeepCSV_jetNSecondaryVertices = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'jetNSecondaryVertices\', -999)", int, doc="number of reconstructed possible secondary vertices in jet"), + DeepCSV_jetNSelectedTracks = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'jetNSelectedTracks\', -999)", int, doc="selected tracks in the jet"), + DeepCSV_jetNTracksEtaRel = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'jetNTracksEtaRel\', -999)", int, doc="number of tracks for which etaRel is computed"), + DeepCSV_trackSumJetEtRatio = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'trackSumJetEtRatio\', -999)", float, doc="ratio of track sum transverse energy over jet energy", precision=10), + DeepCSV_trackSumJetDeltaR = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'trackSumJetDeltaR\', -999)", float, doc="pseudoangular distance between jet axis and track fourvector sum", precision=10), + DeepCSV_trackSip2dValAboveCharm = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'trackSip2dValAboveCharm\', -999)", float, doc="track 2D signed impact parameter of first track lifting mass above charm", precision=10), + DeepCSV_trackSip2dSigAboveCharm = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'trackSip2dSigAboveCharm\', -999)", float, doc="track 2D signed impact parameter significance of first track lifting mass above charm", precision=10), + DeepCSV_trackSip3dValAboveCharm = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'trackSip3dValAboveCharm\', -999)", float, doc="track 3D signed impact parameter of first track lifting mass above charm", precision=10), + DeepCSV_trackSip3dSigAboveCharm = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'trackSip3dSigAboveCharm\', -999)", float, doc="track 3D signed impact parameter significance of first track lifting mass above charm", precision=10), + DeepCSV_vertexMass = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'vertexMass\', -999)", float, doc="mass of track sum at secondary vertex", precision=10), + DeepCSV_vertexNTracks = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'vertexNTracks\', -999)", int, doc="number of tracks at secondary vertex"), + DeepCSV_vertexEnergyRatio = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'vertexEnergyRatio\', -999)", float, doc="ratio of energy at secondary vertex over total energy", precision=10), + DeepCSV_vertexJetDeltaR = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'vertexJetDeltaR\', -999)", float, doc="pseudoangular distance between jet axis and secondary vertex direction", precision=10), + DeepCSV_flightDistance2dVal = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'flightDistance2dVal\', -999)", float, doc="transverse distance between primary and secondary vertex", precision=10), + DeepCSV_flightDistance2dSig = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'flightDistance2dSig\', -999)", float, doc="transverse distance significance between primary and secondary vertex", precision=10), + DeepCSV_flightDistance3dVal = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'flightDistance3dVal\', -999)", float, doc="distance between primary and secondary vertex", precision=10), + DeepCSV_flightDistance3dSig = Var("tagInfo(\'pfDeepCSV\').taggingVariables.get(\'flightDistance3dSig\', -999)", float, doc="distance significance between primary and secondary vertex", precision=10), + ) + return DeepCSVVars + + +def get_DeepJet_outputs(): + DeepJetOutputVars = cms.PSet( + btagDeepFlavB_b=Var("bDiscriminator('pfDeepFlavourJetTags:probb')", + float, + doc="DeepJet b tag probability", + precision=10), + btagDeepFlavB_bb=Var("bDiscriminator('pfDeepFlavourJetTags:probbb')", + float, + doc="DeepJet bb tag probability", + precision=10), + btagDeepFlavB_lepb=Var("bDiscriminator('pfDeepFlavourJetTags:problepb')", + float, + doc="DeepJet lepb tag probability", + precision=10), + btagDeepFlavC=Var("bDiscriminator('pfDeepFlavourJetTags:probc')", + float, + doc="DeepJet c tag probability", + precision=10), + btagDeepFlavUDS=Var("bDiscriminator('pfDeepFlavourJetTags:probuds')", + float, + doc="DeepJet uds tag probability", + precision=10), + btagDeepFlavG=Var("bDiscriminator('pfDeepFlavourJetTags:probg')", + float, + doc="DeepJet gluon tag probability", + precision=10), + # discriminators are already part of jets_cff.py from NanoAOD and therefore not added here + + # negative taggers + btagNegDeepFlavB = Var("bDiscriminator('pfNegativeDeepFlavourJetTags:probb')+bDiscriminator('pfNegativeDeepFlavourJetTags:probbb')+bDiscriminator('pfNegativeDeepFlavourJetTags:problepb')", + float, + doc="Negative DeepJet b+bb+lepb tag discriminator", + precision=10), + btagNegDeepFlavCvL = Var("?(bDiscriminator('pfNegativeDeepFlavourJetTags:probc')+bDiscriminator('pfNegativeDeepFlavourJetTags:probuds')+bDiscriminator('pfNegativeDeepFlavourJetTags:probg'))>0?bDiscriminator('pfNegativeDeepFlavourJetTags:probc')/(bDiscriminator('pfNegativeDeepFlavourJetTags:probc')+bDiscriminator('pfNegativeDeepFlavourJetTags:probuds')+bDiscriminator('pfNegativeDeepFlavourJetTags:probg')):-1", + float, + doc="Negative DeepJet c vs uds+g discriminator", + precision=10), + btagNegDeepFlavCvB = Var("?(bDiscriminator('pfNegativeDeepFlavourJetTags:probc')+bDiscriminator('pfNegativeDeepFlavourJetTags:probb')+bDiscriminator('pfNegativeDeepFlavourJetTags:probbb')+bDiscriminator('pfNegativeDeepFlavourJetTags:problepb'))>0?bDiscriminator('pfNegativeDeepFlavourJetTags:probc')/(bDiscriminator('pfNegativeDeepFlavourJetTags:probc')+bDiscriminator('pfNegativeDeepFlavourJetTags:probb')+bDiscriminator('pfNegativeDeepFlavourJetTags:probbb')+bDiscriminator('pfNegativeDeepFlavourJetTags:problepb')):-1", + float, + doc="Negative DeepJet c vs b+bb+lepb discriminator", + precision=10), + btagNegDeepFlavQG = Var("?(bDiscriminator('pfNegativeDeepFlavourJetTags:probg')+bDiscriminator('pfNegativeDeepFlavourJetTags:probuds'))>0?bDiscriminator('pfNegativeDeepFlavourJetTags:probg')/(bDiscriminator('pfNegativeDeepFlavourJetTags:probg')+bDiscriminator('pfNegativeDeepFlavourJetTags:probuds')):-1", + float, + doc="Negative DeepJet g vs uds discriminator", + precision=10), + btagNegDeepFlavB_b = Var("bDiscriminator('pfNegativeDeepFlavourJetTags:probb')", + float, + doc="Negative DeepJet b tag probability", + precision=10), + btagNegDeepFlavB_bb = Var("bDiscriminator('pfNegativeDeepFlavourJetTags:probbb')", + float, + doc="Negative DeepJet bb tag probability", + precision=10), + btagNegDeepFlavB_lepb = Var("bDiscriminator('pfNegativeDeepFlavourJetTags:problepb')", + float, + doc="Negative DeepJet lepb tag probability", + precision=10), + btagNegDeepFlavC = Var("bDiscriminator('pfNegativeDeepFlavourJetTags:probc')", + float, + doc="Negative DeepJet c tag probability", + precision=10), + btagNegDeepFlavUDS = Var("bDiscriminator('pfNegativeDeepFlavourJetTags:probuds')", + float, + doc="Negative DeepJet uds tag probability", + precision=10), + btagNegDeepFlavG = Var("bDiscriminator('pfNegativeDeepFlavourJetTags:probg')", + float, + doc="Negative DeepJet gluon tag probability", + precision=10), + ) + return DeepJetOutputVars + + +def get_ParticleNetAK4_outputs(): + ## default scores in jetAK4_Puppi_cff.py collections + ParticleNetAK4OutputVars = cms.PSet( + # raw scores + btagPNetProbB = Var("?bDiscriminator('pfParticleNetFromMiniAODAK4PuppiCentralJetTags:probb')>0?bDiscriminator('pfParticleNetFromMiniAODAK4PuppiCentralJetTags:probb'):-1", + float, + doc="ParticleNet b tag probability", + precision=10), + btagPNetProbC = Var("?bDiscriminator('pfParticleNetFromMiniAODAK4PuppiCentralJetTags:probc')>0?bDiscriminator('pfParticleNetFromMiniAODAK4PuppiCentralJetTags:probc'):-1", + float, + doc="ParticleNet c tag probability", + precision=10), + btagPNetProbUDS = Var("?bDiscriminator('pfParticleNetFromMiniAODAK4PuppiCentralJetTags:probuds')>0?bDiscriminator('pfParticleNetFromMiniAODAK4PuppiCentralJetTags:probuds'):-1", + float, + doc="ParticleNet uds tag probability", + precision=10), + btagPNetProbG = Var("?bDiscriminator('pfParticleNetFromMiniAODAK4PuppiCentralJetTags:probg')>0?bDiscriminator('pfParticleNetFromMiniAODAK4PuppiCentralJetTags:probg'):-1", + float, + doc="ParticleNet gluon tag probability", + precision=10), + + # negative taggers + btagNegPNetB = Var("?(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probb')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probuds')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probg'))>0?(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probb'))/(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probb')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probuds')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probg')):-1", + float, + doc="Negative ParticleNet b vs. udscg", + precision=10), + btagNegPNetCvL = Var("?(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probuds')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probg'))>0?(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc'))/(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probuds')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probg')):-1", + float, + doc="Negative ParticleNet c vs. udsg", + precision=10), + btagNegPNetCvB = Var("?(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probb'))>0?(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc'))/(bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc')+bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probb')):-1", + float, + doc="Negative ParticleNet c vs. b", + precision=10), + btagNegPNetProbB = Var("?bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probb')>0?bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probb'):-1", + float, + doc="Negative ParticleNet b tag probability", + precision=10), + btagNegPNetProbC = Var("?bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc')>0?bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probc'):-1", + float, + doc="Negative ParticleNet c tag probability", + precision=10), + btagNegPNetProbUDS = Var("?bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probuds')>0?bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probuds'):-1", + float, + doc="Negative ParticleNet uds tag probability", + precision=10), + btagNegPNetProbG = Var("?bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probg')>0?bDiscriminator('pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:probg'):-1", + float, + doc="Negative ParticleNet gluon tag probability", + precision=10), + ) + + return ParticleNetAK4OutputVars + + +def get_ParticleTransformerAK4_outputs(): + ParticleTransformerAK4OutputVars = cms.PSet( + btagRobustParTAK4B_b=Var("bDiscriminator('pfParticleTransformerAK4JetTags:probb')", + float, + doc="RobustParTAK4 b tag probability", + precision=10), + btagRobustParTAK4B_bb=Var("bDiscriminator('pfParticleTransformerAK4JetTags:probbb')", + float, + doc="RobustParTAK4 bb tag probability", + precision=10), + btagRobustParTAK4B_lepb=Var("bDiscriminator('pfParticleTransformerAK4JetTags:problepb')", + float, + doc="RobustParTAK4 lepb tag probability", + precision=10), + btagRobustParTAK4C=Var("bDiscriminator('pfParticleTransformerAK4JetTags:probc')", + float, + doc="RobustParTAK4 c tag probability", + precision=10), + btagRobustParTAK4UDS=Var("bDiscriminator('pfParticleTransformerAK4JetTags:probuds')", + float, + doc="RobustParTAK4 uds tag probability", + precision=10), + btagRobustParTAK4G=Var("bDiscriminator('pfParticleTransformerAK4JetTags:probg')", + float, + doc="RobustParTAK4 gluon tag probability", + precision=10), + + # negative taggers + btagNegRobustParTAK4B = Var("bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probb')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probbb')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:problepb')", + float, + doc="Negative RobustParTAK4 b+bb+lepb tag discriminator", + precision=10), + btagNegRobustParTAK4CvL = Var("?(bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probc')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probuds')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probg'))>0?bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probc')/(bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probc')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probuds')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probg')):-1", + float, + doc="Negative RobustParTAK4 c vs uds+g discriminator", + precision=10), + btagNegRobustParTAK4CvB = Var("?(bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probc')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probb')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probbb')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:problepb'))>0?bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probc')/(bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probc')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probb')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probbb')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:problepb')):-1", + float, + doc="Negative RobustParTAK4 c vs b+bb+lepb discriminator", + precision=10), + btagNegRobustParTAK4QG = Var("?(bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probg')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probuds'))>0?bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probg')/(bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probg')+bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probuds')):-1", + float, + doc="Negative RobustParTAK4 g vs uds discriminator", + precision=10), + btagNegRobustParTAK4B_b = Var("bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probb')", + float, + doc="Negative RobustParTAK4 b tag probability", + precision=10), + btagNegRobustParTAK4B_bb = Var("bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probbb')", + float, + doc="Negative RobustParTAK4 bb tag probability", + precision=10), + btagNegRobustParTAK4B_lepb = Var("bDiscriminator('pfNegativeParticleTransformerAK4JetTags:problepb')", + float, + doc="Negative RobustParTAK4 lepb tag probability", + precision=10), + btagNegRobustParTAK4C = Var("bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probc')", + float, + doc="Negative RobustParTAK4 c tag probability", + precision=10), + btagNegRobustParTAK4UDS = Var("bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probuds')", + float, + doc="Negative RobustParTAK4 uds tag probability", + precision=10), + btagNegRobustParTAK4G = Var("bDiscriminator('pfNegativeParticleTransformerAK4JetTags:probg')", + float, + doc="Negative RobustParTAK4 gluon tag probability", + precision=10), + ) + + return ParticleTransformerAK4OutputVars + + +def customize_BTV_GenTable(process): + process.finalGenParticles.select += [ + "keep (4 <= abs(pdgId) <= 5) && statusFlags().isLastCopy()", # BTV: keep b/c quarks in their last copy + "keep (abs(pdgId) == 310 || abs(pdgId) == 3122) && statusFlags().isLastCopy()", # BTV: keep K0s and Lambdas in their last copy + ] + process.genParticleTable.variables = cms.PSet( + process.genParticleTable.variables, + vx = Var("vx", "float", doc="x coordinate of vertex position"), + vy = Var("vy", "float", doc="y coordinate of vertex position"), + vz = Var("vz", "float", doc="z coordinate of vertex position"), + genPartIdxMother2 = Var("?numberOfMothers>1?motherRef(1).key():-1", "int", doc="index of the second mother particle, if valid"), + ) + +def addPFCands(process, runOnMC=False, allPF = False, onlyAK4=False, onlyAK8=False): + process.customizedPFCandsTask = cms.Task( ) + process.schedule.associate(process.customizedPFCandsTask) + + process.finalJetsAK8Constituents = cms.EDProducer("PatJetConstituentPtrSelector", + src = cms.InputTag("finalJetsAK8"), + cut = cms.string("") + ) + process.finalJetsAK4Constituents = cms.EDProducer("PatJetConstituentPtrSelector", + src = cms.InputTag("finalJetsPuppi"), + cut = cms.string("") + ) + if allPF: + candInput = cms.InputTag("packedPFCandidates") + elif onlyAK4: + candList = cms.VInputTag(cms.InputTag("finalJetsAK4Constituents", "constituents")) + process.customizedPFCandsTask.add(process.finalJetsAK4Constituents) + process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituents") + elif onlyAK8: + candList = cms.VInputTag(cms.InputTag("finalJetsAK8Constituents", "constituents")) + process.customizedPFCandsTask.add(process.finalJetsAK8Constituents) + process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituents") + else: + candList = cms.VInputTag(cms.InputTag("finalJetsAK4Constituents", "constituents"), cms.InputTag("finalJetsAK8Constituents", "constituents")) + process.customizedPFCandsTask.add(process.finalJetsAK4Constituents) + process.customizedPFCandsTask.add(process.finalJetsAK8Constituents) + process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituents") + process.customConstituentsExtTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = candInput, + cut = cms.string(""), #we should not filter after pruning + name = cms.string("PFCands"), + doc = cms.string("interesting particles from AK4 and AK8 jets"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the extension table for the AK8 constituents + variables = cms.PSet(CandVars, + puppiWeight = Var("puppiWeight()", float, doc="Puppi weight",precision=10), + puppiWeightNoLep = Var("puppiWeightNoLep()", float, doc="Puppi weight removing leptons",precision=10), + vtxChi2 = Var("?hasTrackDetails()?vertexChi2():-1", float, doc="vertex chi2",precision=10), + trkChi2 = Var("?hasTrackDetails()?pseudoTrack().normalizedChi2():-1", float, doc="normalized trk chi2", precision=10), + dz = Var("?hasTrackDetails()?dz():-1", float, doc="pf dz", precision=10), + dzErr = Var("?hasTrackDetails()?dzError():-1", float, doc="pf dz err", precision=10), + d0 = Var("?hasTrackDetails()?dxy():-1", float, doc="pf d0", precision=10), + d0Err = Var("?hasTrackDetails()?dxyError():-1", float, doc="pf d0 err", precision=10), + pvAssocQuality = Var("pvAssociationQuality()", int, doc="primary vertex association quality. 0: NotReconstructedPrimary, 1: OtherDeltaZ, 4: CompatibilityBTag, 5: CompatibilityDz, 6: UsedInFitLoose, 7: UsedInFitTight"), + lostInnerHits = Var("lostInnerHits()", int, doc="lost inner hits. -1: validHitInFirstPixelBarrelLayer, 0: noLostInnerHits, 1: oneLostInnerHit, 2: moreLostInnerHits"), + lostOuterHits = Var("?hasTrackDetails()?pseudoTrack().hitPattern().numberOfLostHits('MISSING_OUTER_HITS'):0", int, doc="lost outer hits"), + numberOfHits = Var("numberOfHits()", int, doc="number of hits"), + numberOfPixelHits = Var("numberOfPixelHits()", int, doc="number of pixel hits"), + trkQuality = Var("?hasTrackDetails()?pseudoTrack().qualityMask():0", int, doc="track quality mask"), + trkHighPurity = Var("?hasTrackDetails()?pseudoTrack().quality('highPurity'):0", bool, doc="track is high purity"), + trkAlgo = Var("?hasTrackDetails()?pseudoTrack().algo():-1", int, doc="track algorithm"), + trkP = Var("?hasTrackDetails()?pseudoTrack().p():-1", float, doc="track momemtum", precision=-1), + trkPt = Var("?hasTrackDetails()?pseudoTrack().pt():-1", float, doc="track pt", precision=-1), + trkEta = Var("?hasTrackDetails()?pseudoTrack().eta():-1", float, doc="track pt", precision=12), + trkPhi = Var("?hasTrackDetails()?pseudoTrack().phi():-1", float, doc="track phi", precision=12), + ) + ) + process.customAK8ConstituentsTable = cms.EDProducer("PatJetConstituentTableProducer", + candidates = candInput, + jets = cms.InputTag("finalJetsAK8"), + jet_radius = cms.double(0.8), + name = cms.string("FatJetPFCands"), + idx_name = cms.string("pFCandsIdx"), + nameSV = cms.string("FatJetSVs"), + idx_nameSV = cms.string("sVIdx"), + ) + process.customAK4ConstituentsTable = cms.EDProducer("PatJetConstituentTableProducer", + candidates = candInput, + jets = cms.InputTag("finalJetsPuppi"), # was finalJets before + jet_radius = cms.double(0.4), + name = cms.string("JetPFCands"), + idx_name = cms.string("pFCandsIdx"), + nameSV = cms.string("JetSVs"), + idx_nameSV = cms.string("sVIdx"), + ) + if not allPF: + process.customizedPFCandsTask.add(process.finalJetsConstituents) + process.customizedPFCandsTask.add(process.customConstituentsExtTable) + # linkedObjects are WIP for Run3 + process.customizedPFCandsTask.add(process.customAK8ConstituentsTable) + process.customizedPFCandsTask.add(process.customAK4ConstituentsTable) + + if runOnMC: + + process.genJetsAK8Constituents = cms.EDProducer("GenJetPackedConstituentPtrSelector", + src = cms.InputTag("slimmedGenJetsAK8"), + cut = cms.string("pt > 100.") + ) + + + process.genJetsAK4Constituents = process.genJetsAK8Constituents.clone( + src = cms.InputTag("slimmedGenJets"), + cut = cms.string("pt > 20") + ) + if allPF: + genCandInput = cms.InputTag("packedGenParticles") + elif onlyAK4: + genCandList = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents")) + genCandInput = cms.InputTag("genJetsConstituents") + process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + elif onlyAK8: + genCandList = cms.VInputTag(cms.InputTag("genJetsAK8Constituents", "constituents")) + genCandInput = cms.InputTag("genJetsConstituents") + process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + else: + genCandList = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents"), cms.InputTag("genJetsAK8Constituents", "constituents")) + genCandInput = cms.InputTag("genJetsConstituents") + process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + process.genJetsParticleTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = genCandInput, + cut = cms.string(""), #we should not filter after pruning + name= cms.string("GenCands"), + doc = cms.string("interesting gen particles from AK4 and AK8 jets"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the AK8 constituents + variables = cms.PSet(CandVars + ) + ) + process.genAK8ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", + candidates = genCandInput, + jets = cms.InputTag("genJetsAK8Constituents"), # Note: The name has "Constituents" in it, but these are the jets + name = cms.string("GenFatJetCands"), + nameSV = cms.string("GenFatJetSVs"), + idx_name = cms.string("pFCandsIdx"), + idx_nameSV = cms.string("sVIdx"), + readBtag = cms.bool(False)) + process.genAK4ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", + candidates = genCandInput, + jets = cms.InputTag("genJetsAK4Constituents"), # Note: The name has "Constituents" in it, but these are the jets + name = cms.string("GenJetCands"), + nameSV = cms.string("GenJetSVs"), + idx_name = cms.string("pFCandsIdx"), + idx_nameSV = cms.string("sVIdx"), + readBtag = cms.bool(False)) + process.customizedPFCandsTask.add(process.genJetsAK4Constituents) #Note: For gen need to add jets to the process to keep pt cuts. + process.customizedPFCandsTask.add(process.genJetsAK8Constituents) + if not allPF: + process.customizedPFCandsTask.add(process.genJetsConstituents) + process.customizedPFCandsTask.add(process.genJetsParticleTable) + process.customizedPFCandsTask.add(process.genAK8ConstituentsTable) + process.customizedPFCandsTask.add(process.genAK4ConstituentsTable) + + return process + + +def add_BTV(process, runOnMC=False, onlyAK4=False, onlyAK8=False, keepInputs=['DeepCSV','DeepJet','DDX']): + addAK4 = not onlyAK8 + addAK8 = not onlyAK4 + + if addAK4: + process = update_jets_AK4(process) + if addAK8: + process = update_jets_AK8(process) + process = update_jets_AK8_subjet(process) + + process.customizeJetTask = cms.Task() + process.schedule.associate(process.customizeJetTask) + + CommonVars = cms.PSet( + Proba=Var("bDiscriminator('pfJetProbabilityBJetTags')", + float, + doc="Jet Probability (Usage:BTV)", + precision=10), + ProbaN=Var("bDiscriminator('pfNegativeOnlyJetProbabilityBJetTags')", + float, + doc="Negative-only Jet Probability (Usage:BTV)", + precision=10), + Bprob=Var("bDiscriminator('pfJetBProbabilityBJetTags')", + float, + doc="Jet B Probability (Usage:BTV)", + precision=10), + BprobN=Var("bDiscriminator('pfNegativeOnlyJetBProbabilityBJetTags')", + float, + doc="Negative-only Jet B Probability (Usage:BTV)", + precision=10), + btagDeepB_b=Var("bDiscriminator('pfDeepCSVJetTags:probb')", + float, + doc="DeepCSV b tag discriminator", + precision=10), + btagDeepB_bb=Var("bDiscriminator('pfDeepCSVJetTags:probbb')", + float, + doc="DeepCSV bb tag discriminator", + precision=10), + btagDeepC=Var("bDiscriminator('pfDeepCSVJetTags:probc')", + float, + doc="DeepCSV c btag discriminator", + precision=10), + btagDeepL=Var("bDiscriminator('pfDeepCSVJetTags:probudsg')", + float, + doc="DeepCSV light btag discriminator", + precision=10), + ) + + # decouple these from CommonVars, not relevant for data + HadronCountingVars = cms.PSet( + nBHadrons=Var("jetFlavourInfo().getbHadrons().size()", + int, + doc="number of b-hadrons"), + nCHadrons=Var("jetFlavourInfo().getcHadrons().size()", + int, + doc="number of c-hadrons") + ) + + # AK4 + process.customJetExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src=jetPuppiTable.src, + cut=jetPuppiTable.cut, + name=jetPuppiTable.name, + doc=jetPuppiTable.doc, + singleton=cms.bool(False), # the number of entries is variable + extension=cms.bool(True), # this is the extension table for Jets + variables=cms.PSet( + CommonVars, + HadronCountingVars if runOnMC else cms.PSet(), # hadrons from Generator only relevant for MC + get_DeepCSV_vars() if ('DeepCSV' in keepInputs) else cms.PSet(), + get_DeepJet_outputs(), # outputs are added in any case, inputs only if requested + get_ParticleNetAK4_outputs(), + get_ParticleTransformerAK4_outputs(), + )) + + # disable the ParT branches in default jetPuppi table + from PhysicsTools.NanoAOD.nano_eras_cff import run3_nanoAOD_122, run3_nanoAOD_124 + (run3_nanoAOD_122 | run3_nanoAOD_124).toModify( + process.jetPuppiTable.variables, + btagRobustParTAK4B = None, + btagRobustParTAK4CvL = None, + btagRobustParTAK4CvB = None, + btagRobustParTAK4QG = None, + ) + + if ('DeepJet' in keepInputs): + # from Run3 onwards, always set storeAK4Truth to True for MC + process.customAK4ConstituentsForDeepJetTable = cms.EDProducer("PatJetDeepJetTableProducer", + jets = cms.InputTag("linkedObjects","jets"), + storeAK4Truth = cms.bool(runOnMC), + ) + + # AK8 + process.customFatJetExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src=fatJetTable.src, + cut=fatJetTable.cut, + name=fatJetTable.name, + doc=fatJetTable.doc, + singleton=cms.bool(False), # the number of entries is variable + extension=cms.bool(True), # this is the extension table for FatJets + variables=cms.PSet( + CommonVars, + #HadronCountingVars if runOnMC else cms.PSet(), # only necessary before 106x + get_DDX_vars() if ('DDX' in keepInputs) else cms.PSet(), + )) + + # Subjets + process.customSubJetExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src=subJetTable.src, + cut=subJetTable.cut, + name=subJetTable.name, + doc=subJetTable.doc, + singleton=cms.bool(False), # the number of entries is variable + extension=cms.bool(True), # this is the extension table for FatJets + variables=cms.PSet( + CommonVars, + #HadronCountingVars if runOnMC else cms.PSet(), # only necessary before 106x + )) + + process.customSubJetMCExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src = subJetTable.src, + cut = subJetTable.cut, + name = subJetTable.name, + doc=subJetTable.doc, + singleton = cms.bool(False), + extension = cms.bool(True), + variables = cms.PSet( + subGenJetAK8Idx = Var("?genJetFwdRef().backRef().isNonnull()?genJetFwdRef().backRef().key():-1", + int, + doc="index of matched gen Sub jet"), + ) + ) + + if addAK4: + process.customizeJetTask.add(process.customJetExtTable) + if ('DeepJet' in keepInputs): + process.customizeJetTask.add(process.customAK4ConstituentsForDeepJetTable) + + if addAK8: + process.customizeJetTask.add(process.customFatJetExtTable) + process.customizeJetTask.add(process.customSubJetExtTable) + if runOnMC: + process.customizeJetTask.add(process.customSubJetMCExtTable) + + ## customize BTV GenTable + if runOnMC: + customize_BTV_GenTable(process) + + return process + + + +def PFnano_customizeMC(process): + addPFCands(process, True) + add_BTV(process, True, keepInputs=['DeepCSV','DeepJet','DDX']) + return process + +def PFnano_customizeMC_allPF(process): + addPFCands(process, True, True) + add_BTV(process, True, keepInputs=['DeepCSV','DeepJet','DDX']) + return process + +def PFnano_customizeMC_AK4JetsOnly(process): + addPFCands(process, True, False, True) + add_BTV(process, True, True, keepInputs=['DeepCSV','DeepJet']) + return process + +def PFnano_customizeMC_AK8JetsOnly(process): + addPFCands(process, True, False, False, True) + add_BTV(process, True, False, True, keepInputs=['DDX']) + return process + +def PFnano_customizeMC_noPF(process): + add_BTV(process, True, keepInputs=['DeepCSV','DeepJet','DDX']) + return process + +def PFnano_customizeMC_noInputs(process): + add_BTV(process, True, keepInputs=[]) + return process + + +#### DATA customization +def PFnano_customizeData(process): + addPFCands(process, False) + add_BTV(process, False, keepInputs=['DeepCSV','DeepJet','DDX']) + return process + +def PFnano_customizeData_allPF(process): + addPFCands(process, False, True) + add_BTV(process, False, keepInputs=['DeepCSV','DeepJet','DDX']) + return process + +def PFnano_customizeData_AK4JetsOnly(process): + addPFCands(process, False, False, True) + add_BTV(process, False, True, keepInputs=['DeepCSV','DeepJet']) + return process + +def PFnano_customizeData_AK8JetsOnly(process): + addPFCands(process, False, False, False, True) + add_BTV(process, False, False, True, keepInputs=['DDX']) + return process + +def PFnano_customizeData_noPF(process): + add_BTV(process, False, keepInputs=['DeepCSV','DeepJet','DDX']) + return process + +def PFnano_customizeData_noInputs(process): + add_BTV(process, False, keepInputs=[]) + return process diff --git a/PhysicsTools/NanoAOD/python/nano_cff.py b/PhysicsTools/NanoAOD/python/nano_cff.py index 515c0c75d066a..7be976259950e 100644 --- a/PhysicsTools/NanoAOD/python/nano_cff.py +++ b/PhysicsTools/NanoAOD/python/nano_cff.py @@ -28,6 +28,7 @@ from PhysicsTools.NanoAOD.fsrPhotons_cff import * from PhysicsTools.NanoAOD.softActivity_cff import * from PhysicsTools.NanoAOD.l1trig_cff import * +from PhysicsTools.NanoAOD.custom_btv_cff import * nanoMetadata = cms.EDProducer("UniqueStringProducer", strings = cms.PSet( @@ -234,6 +235,7 @@ def nanoAOD_customizeCommon(process): addParticleNet=nanoAOD_addDeepInfoAK8_switch.nanoAOD_addParticleNet_switch, jecPayload=nanoAOD_addDeepInfoAK8_switch.jecPayload ) + process = PFnano_customizeMC(process) nanoAOD_tau_switch = cms.PSet( idsToAdd = cms.vstring(), From 37b89787e7c68ab9ac88ca7cb0cd188840067938 Mon Sep 17 00:00:00 2001 From: Congqiao Li Date: Thu, 29 Jun 2023 05:48:26 +0200 Subject: [PATCH 2/9] Add Negative tag for ParticleNet and ParT AK4 --- .../python/recoLayer0/bTagging_cff.py | 18 ++++++ .../PatAlgos/python/tools/jetTools.py | 46 +++++++++++++-- .../plugins/ParticleNetFeatureEvaluator.cc | 58 ++++++++++++++----- .../python/pfParticleNetFromMiniAODAK4_cff.py | 26 +++++++++ .../python/pfParticleTransformerAK4_cff.py | 13 +++++ 5 files changed, 144 insertions(+), 17 deletions(-) diff --git a/PhysicsTools/PatAlgos/python/recoLayer0/bTagging_cff.py b/PhysicsTools/PatAlgos/python/recoLayer0/bTagging_cff.py index 361c2fd2814ae..69a0c51b550e7 100644 --- a/PhysicsTools/PatAlgos/python/recoLayer0/bTagging_cff.py +++ b/PhysicsTools/PatAlgos/python/recoLayer0/bTagging_cff.py @@ -60,6 +60,8 @@ , 'pfParticleNetFromMiniAODAK4PuppiForwardTagInfos' , 'pfParticleNetFromMiniAODAK4CHSCentralTagInfos' , 'pfParticleNetFromMiniAODAK4CHSForwardTagInfos' + , 'pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos' + , 'pfNegativeParticleNetFromMiniAODAK4CHSCentralTagInfos' , 'pfParticleNetFromMiniAODAK8TagInfos' ] @@ -293,6 +295,7 @@ for disc in _pfNegativeParticleNetAK4JetTagsProbs: supportedBtagDiscr[disc] = [["pfNegativeParticleNetAK4TagInfos"]] # ----------------------------------- +# setup Run3 ParticleNet AK4 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import _pfParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs,_pfParticleNetFromMiniAODAK4PuppiCentralJetTagsMetaDiscr for disc in _pfParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs: supportedBtagDiscr[disc] = [["pfParticleNetFromMiniAODAK4PuppiCentralTagInfos"]] @@ -313,6 +316,16 @@ supportedBtagDiscr[disc] = [["pfParticleNetFromMiniAODAK4CHSForwardTagInfos"]] for disc in _pfParticleNetFromMiniAODAK4CHSForwardJetTagsMetaDiscr: supportedMetaDiscr[disc] = _pfParticleNetFromMiniAODAK4CHSForwardJetTagsProbs +# ----------------------------------- +# setup Negative Run3 ParticleNet AK4 (central only) +from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import _pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs +for disc in _pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs: + supportedBtagDiscr[disc] = [["pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos"]] +from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import _pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTagsProbs +for disc in _pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTagsProbs: + supportedBtagDiscr[disc] = [["pfNegativeParticleNetFromMiniAODAK4CHSCentralTagInfos"]] +# ----------------------------------- +# setup Run3 ParticleNet AK8 from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK8_cff import _pfParticleNetFromMiniAODAK8JetTagsProbs,_pfParticleNetFromMiniAODAK8JetTagsMetaDiscr for disc in _pfParticleNetFromMiniAODAK8JetTagsProbs: supportedBtagDiscr[disc] = [["pfParticleNetFromMiniAODAK8TagInfos"]] @@ -338,3 +351,8 @@ for disc in _pfParticleTransformerAK4JetTagsMetaDiscrs: supportedMetaDiscr[disc] = _pfParticleTransformerAK4JetTagsProbs # ----------------------------------- +# setup Negative ParticleTransformer AK4 +from RecoBTag.ONNXRuntime.pfParticleTransformerAK4_cff import _pfNegativeParticleTransformerAK4JetTagsProbs +# update supportedBtagDiscr +for disc in _pfNegativeParticleTransformerAK4JetTagsProbs: + supportedBtagDiscr[disc] = [["pfNegativeParticleTransformerAK4TagInfos"]] diff --git a/PhysicsTools/PatAlgos/python/tools/jetTools.py b/PhysicsTools/PatAlgos/python/tools/jetTools.py index 5854c1481c874..f1ed59547d7cb 100644 --- a/PhysicsTools/PatAlgos/python/tools/jetTools.py +++ b/PhysicsTools/PatAlgos/python/tools/jetTools.py @@ -11,6 +11,8 @@ from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4PuppiForwardTagInfos,pfParticleNetFromMiniAODAK4PuppiForwardJetTags,pfParticleNetFromMiniAODAK4PuppiForwardDiscriminatorsJetTags from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4CHSCentralTagInfos,pfParticleNetFromMiniAODAK4CHSCentralJetTags,pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4CHSForwardTagInfos,pfParticleNetFromMiniAODAK4CHSForwardJetTags,pfParticleNetFromMiniAODAK4CHSForwardDiscriminatorsJetTags +from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos,pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags +from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfNegativeParticleNetFromMiniAODAK4CHSCentralTagInfos,pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK8_cff import pfParticleNetFromMiniAODAK8TagInfos,pfParticleNetFromMiniAODAK8JetTags,pfParticleNetFromMiniAODAK8DiscriminatorsJetTags ## dictionary with supported jet clustering algorithms @@ -831,16 +833,22 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou acceptedTagInfos.append(btagInfo) elif hasattr(toptag, btagInfo) : acceptedTagInfos.append(btagInfo) - elif btagInfo == 'pfParticleNetFromMiniAODAK4PuppiCentralTagInfos': + elif btagInfo == 'pfParticleNetFromMiniAODAK4PuppiCentralTagInfos' or btagInfo == 'pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos': # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround + if btagInfo == 'pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos': + svUsed, flip_ip_sign, max_sip3dsig_for_flip = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix), True, 10. + else: + svUsed, flip_ip_sign, max_sip3dsig_for_flip = svSource, False, -1. if pfCandidates.value() != 'packedPFCandidates': raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value()) addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix, pfParticleNetFromMiniAODAK4PuppiCentralTagInfos.clone( jets = jetSource, vertices = pvSource, - secondary_vertices = svSource, + secondary_vertices = svUsed, pf_candidates = pfCandidates, + flip_ip_sign = flip_ip_sign, + max_sip3dsig_for_flip = max_sip3dsig_for_flip, ), process, task) acceptedTagInfos.append(btagInfo) @@ -857,16 +865,22 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou ), process, task) acceptedTagInfos.append(btagInfo) - elif btagInfo == 'pfParticleNetFromMiniAODAK4CHSCentralTagInfos': + elif btagInfo == 'pfParticleNetFromMiniAODAK4CHSCentralTagInfos' or btagInfo == 'pfNegativeParticleNetFromMiniAODAK4PuppiForwardTagInfos': # ParticleNetFromMiniAOD cannot be run on RECO inputs, so need a workaround + if btagInfo == 'pfNegativeParticleNetFromMiniAODAK4PuppiForwardTagInfos': + svUsed, flip_ip_sign, max_sip3dsig_for_flip = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix), True, 10. + else: + svUsed, flip_ip_sign, max_sip3dsig_for_flip = svSource, False, -1. if pfCandidates.value() != 'packedPFCandidates': raise ValueError("Invalid pfCandidates collection: %s." % pfCandidates.value()) addToProcessAndTask(btagPrefix+btagInfo+labelName+postfix, pfParticleNetFromMiniAODAK4CHSCentralTagInfos.clone( jets = jetSource, vertices = pvSource, - secondary_vertices = svSource, + secondary_vertices = svUsed, pf_candidates = pfCandidates, + flip_ip_sign = flip_ip_sign, + max_sip3dsig_for_flip = max_sip3dsig_for_flip, ), process, task) acceptedTagInfos.append(btagInfo) @@ -943,6 +957,18 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou task ) acceptedBtagDiscriminators.append(discriminator_name) + elif btagDiscr=='pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags': + if hasattr(process, newDiscr): + pass + addToProcessAndTask( + newDiscr, + pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags.clone( + src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix) + ), + process, + task + ) + acceptedBtagDiscriminators.append(discriminator_name) elif btagDiscr=='pfParticleNetFromMiniAODAK4PuppiForwardJetTags': if hasattr(process, newDiscr): pass @@ -967,6 +993,18 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou task ) acceptedBtagDiscriminators.append(discriminator_name) + elif btagDiscr=='pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags': + if hasattr(process, newDiscr): + pass + addToProcessAndTask( + newDiscr, + pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags.clone( + src = cms.InputTag(btagPrefix+supportedBtagDiscr[discriminator_name][0][0]+labelName+postfix) + ), + process, + task + ) + acceptedBtagDiscriminators.append(discriminator_name) elif btagDiscr=='pfParticleNetFromMiniAODAK4CHSForwardJetTags': if hasattr(process, newDiscr): pass diff --git a/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc b/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc index 7f820b6fe4fcf..2867d4ed34139 100644 --- a/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc +++ b/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc @@ -63,6 +63,8 @@ class ParticleNetFeatureEvaluator : public edm::stream::EDProducer<> { const double min_pt_for_taus_; const double max_eta_for_taus_; const bool include_neutrals_; + const bool flip_ip_sign_; + const double max_sip3dsig_for_flip_ip_sign_; edm::EDGetTokenT muon_token_; edm::EDGetTokenT electron_token_; @@ -261,6 +263,8 @@ ParticleNetFeatureEvaluator::ParticleNetFeatureEvaluator(const edm::ParameterSet min_pt_for_taus_(iConfig.getParameter("min_pt_for_taus")), max_eta_for_taus_(iConfig.getParameter("max_eta_for_taus")), include_neutrals_(iConfig.getParameter("include_neutrals")), + flip_ip_sign_(iConfig.getParameter("flip_ip_sign")), + max_sip3dsig_for_flip_ip_sign_(iConfig.getParameter("max_sip3dsig_for_flip")), muon_token_(consumes(iConfig.getParameter("muons"))), electron_token_(consumes(iConfig.getParameter("electrons"))), photon_token_(consumes(iConfig.getParameter("photons"))), @@ -292,6 +296,8 @@ void ParticleNetFeatureEvaluator::fillDescriptions(edm::ConfigurationDescription desc.add("min_pt_for_taus", 20.); desc.add("max_eta_for_taus", 2.5); desc.add("include_neutrals", true); + desc.add("flip_ip_sign", false); + desc.add("max_sip3dsig_for_flip", -1); desc.add("vertices", edm::InputTag("offlineSlimmedPrimaryVertices")); desc.add("secondary_vertices", edm::InputTag("slimmedSecondaryVertices")); desc.add("pf_candidates", edm::InputTag("packedPFCandidates")); @@ -451,6 +457,19 @@ void ParticleNetFeatureEvaluator::fillParticleFeatures(DeepBoostedJetFeatures &f TVector3 cand_direction(candP3.x(), candP3.y(), candP3.z()); + // only when computing the nagative tagger: remove charged candidates with high sip3d + if (flip_ip_sign_ && max_sip3dsig_for_flip_ip_sign_ > 0. && track) { + reco::TransientTrack transientTrack = track_builder_->build(*track); + Measurement1D meas_ip3d = IPTools::signedImpactParameter3D(transientTrack, jet_ref_track_dir, *pv_).second; + float d3dsig = std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance()); + if (d3dsig > max_sip3dsig_for_flip_ip_sign_) { + continue; + std::cout << "// removed!!!" << d3dsig << std::endl; + } + } + float ip_sign = flip_ip_sign_ ? -1.f : 1.f; + + fts.fill("jet_pfcand_pt_log", std::isnan(std::log(candP4.pt())) ? 0 : std::log(candP4.pt())); fts.fill("jet_pfcand_energy_log", std::isnan(std::log(candP4.energy())) ? 0 : std::log(candP4.energy())); fts.fill("jet_pfcand_eta", candP4.eta()); @@ -468,8 +487,8 @@ void ParticleNetFeatureEvaluator::fillParticleFeatures(DeepBoostedJetFeatures &f ? 0 : jet_direction.Dot(cand_direction) / cand_direction.Mag()); fts.fill("jet_pfcand_frompv", cand->fromPV()); - fts.fill("jet_pfcand_dz", std::isnan(cand->dz(pv_ass_pos)) ? 0 : cand->dz(pv_ass_pos)); - fts.fill("jet_pfcand_dxy", std::isnan(cand->dxy(pv_ass_pos)) ? 0 : cand->dxy(pv_ass_pos)); + fts.fill("jet_pfcand_dz", ip_sign * (std::isnan(cand->dz(pv_ass_pos)) ? 0 : cand->dz(pv_ass_pos))); + fts.fill("jet_pfcand_dxy", ip_sign * (std::isnan(cand->dxy(pv_ass_pos)) ? 0 : cand->dxy(pv_ass_pos))); fts.fill("jet_pfcand_puppiw", cand->puppiWeight()); fts.fill("jet_pfcand_nlostinnerhits", cand->lostInnerHits()); fts.fill("jet_pfcand_nhits", cand->numberOfHits()); @@ -515,11 +534,11 @@ void ParticleNetFeatureEvaluator::fillParticleFeatures(DeepBoostedJetFeatures &f Measurement1D meas_jetdist = IPTools::jetTrackDistance(transientTrack, jet_ref_track_dir, *pv_).second; Measurement1D meas_decayl = IPTools::signedDecayLength3D(transientTrack, jet_ref_track_dir, *pv_).second; - fts.fill("jet_pfcand_trackjet_d3d", std::isnan(meas_ip3d.value()) ? 0 : meas_ip3d.value()); + fts.fill("jet_pfcand_trackjet_d3d", ip_sign * (std::isnan(meas_ip3d.value()) ? 0 : meas_ip3d.value())); fts.fill("jet_pfcand_trackjet_d3dsig", std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance())); - fts.fill("jet_pfcand_trackjet_dist", std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value()); - fts.fill("jet_pfcand_trackjet_decayL", std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value()); + fts.fill("jet_pfcand_trackjet_dist", ip_sign * (std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value())); + fts.fill("jet_pfcand_trackjet_decayL", ip_sign * (std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value())); } else { fts.fill("jet_pfcand_dzsig", 0); fts.fill("jet_pfcand_dxysig", 0); @@ -683,6 +702,8 @@ void ParticleNetFeatureEvaluator::fillSVFeatures(DeepBoostedJetFeatures &fts, co fts.reserve(name, jetSVs.size()); GlobalVector jet_global_vec(jet.px(), jet.py(), jet.pz()); + + float ip_sign = flip_ip_sign_ ? -1.f : 1.f; for (const auto *sv : jetSVs) { fts.fill("sv_mask", 1); @@ -700,12 +721,12 @@ void ParticleNetFeatureEvaluator::fillSVFeatures(DeepBoostedJetFeatures &fts, co VertexDistanceXY dxy; auto valxy = dxy.signedDistance(svtx, *pv_, jet_global_vec); - fts.fill("jet_sv_dxy", std::isnan(valxy.value()) ? 0 : valxy.value()); + fts.fill("jet_sv_dxy", ip_sign * (std::isnan(valxy.value()) ? 0 : valxy.value())); fts.fill("jet_sv_dxysig", std::isnan(fabs(valxy.significance())) ? 0 : fabs(valxy.significance())); VertexDistance3D d3d; auto val3d = d3d.signedDistance(svtx, *pv_, jet_global_vec); - fts.fill("jet_sv_d3d", std::isnan(val3d.value()) ? 0 : val3d.value()); + fts.fill("jet_sv_d3d", ip_sign * (std::isnan(val3d.value()) ? 0 : val3d.value())); fts.fill("jet_sv_d3dsig", std::isnan(fabs(val3d.significance())) ? 0 : fabs(val3d.significance())); } } @@ -734,12 +755,24 @@ void ParticleNetFeatureEvaluator::fillLostTrackFeatures(DeepBoostedJetFeatures & math::XYZPoint pv_ass_pos = pv_ass->position(); for (auto const <rack : jet_lost_tracks) { + const reco::Track *track = ltrack.bestTrack(); + + // only when computing the nagative tagger: remove charged candidates with high sip3d + if (flip_ip_sign_ && max_sip3dsig_for_flip_ip_sign_ > 0.) { + reco::TransientTrack transientTrack = track_builder_->build(*track); + Measurement1D meas_ip3d = IPTools::signedImpactParameter3D(transientTrack, jet_ref_track_dir, *pv_).second; + float d3dsig = std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance()); + if (d3dsig > max_sip3dsig_for_flip_ip_sign_) + continue; + } + float ip_sign = flip_ip_sign_ ? -1.f : 1.f; + fts.fill("jet_losttrack_pt_log", std::isnan(std::log(ltrack.pt())) ? 0 : std::log(ltrack.pt())); fts.fill("jet_losttrack_eta", ltrack.eta()); fts.fill("jet_losttrack_charge", ltrack.charge()); fts.fill("jet_losttrack_frompv", ltrack.fromPV()); - fts.fill("jet_losttrack_dz", std::isnan(ltrack.dz(pv_ass_pos)) ? 0 : ltrack.dz(pv_ass_pos)); - fts.fill("jet_losttrack_dxy", std::isnan(ltrack.dxy(pv_ass_pos)) ? 0 : ltrack.dxy(pv_ass_pos)); + fts.fill("jet_losttrack_dz", ip_sign * (std::isnan(ltrack.dz(pv_ass_pos)) ? 0 : ltrack.dz(pv_ass_pos))); + fts.fill("jet_losttrack_dxy", ip_sign * (std::isnan(ltrack.dxy(pv_ass_pos)) ? 0 : ltrack.dxy(pv_ass_pos))); fts.fill("jet_losttrack_npixhits", ltrack.numberOfPixelHits()); fts.fill("jet_losttrack_nstriphits", ltrack.stripLayersWithMeasurement()); @@ -751,7 +784,6 @@ void ParticleNetFeatureEvaluator::fillLostTrackFeatures(DeepBoostedJetFeatures & ? 0 : reco::btau::etaRel(jet_dir, ltrack.momentum())); - const reco::Track *track = ltrack.bestTrack(); if (track) { fts.fill("jet_losttrack_track_chi2", track->normalizedChi2()); fts.fill("jet_losttrack_track_qual", track->qualityMask()); @@ -769,11 +801,11 @@ void ParticleNetFeatureEvaluator::fillLostTrackFeatures(DeepBoostedJetFeatures & Measurement1D meas_jetdist = IPTools::jetTrackDistance(transientTrack, jet_ref_track_dir, *pv_).second; Measurement1D meas_decayl = IPTools::signedDecayLength3D(transientTrack, jet_ref_track_dir, *pv_).second; - fts.fill("jet_losttrack_trackjet_d3d", std::isnan(meas_ip3d.value()) ? 0 : meas_ip3d.value()); + fts.fill("jet_losttrack_trackjet_d3d", ip_sign * (std::isnan(meas_ip3d.value()) ? 0 : meas_ip3d.value())); fts.fill("jet_losttrack_trackjet_d3dsig", std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance())); - fts.fill("jet_losttrack_trackjet_dist", std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value()); - fts.fill("jet_losttrack_trackjet_decayL", std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value()); + fts.fill("jet_losttrack_trackjet_dist", ip_sign * (std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value())); + fts.fill("jet_losttrack_trackjet_decayL", ip_sign * (std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value())); } else { fts.fill("jet_losttrack_track_chi2", 0); fts.fill("jet_losttrack_track_qual", 0); diff --git a/RecoBTag/ONNXRuntime/python/pfParticleNetFromMiniAODAK4_cff.py b/RecoBTag/ONNXRuntime/python/pfParticleNetFromMiniAODAK4_cff.py index dc3a8f746dfc1..e1ce1914c2d8d 100644 --- a/RecoBTag/ONNXRuntime/python/pfParticleNetFromMiniAODAK4_cff.py +++ b/RecoBTag/ONNXRuntime/python/pfParticleNetFromMiniAODAK4_cff.py @@ -163,3 +163,29 @@ _pfParticleNetFromMiniAODAK4CHSForwardJetTagsAll = _pfParticleNetFromMiniAODAK4CHSForwardJetTagsProbs + _pfParticleNetFromMiniAODAK4CHSForwardJetTagsMetaDiscr _pfParticleNetFromMiniAODAK4PuppiCentralJetTagsAll = _pfParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs + _pfParticleNetFromMiniAODAK4PuppiCentralJetTagsMetaDiscr _pfParticleNetFromMiniAODAK4PuppiForwardJetTagsAll = _pfParticleNetFromMiniAODAK4PuppiForwardJetTagsProbs + _pfParticleNetFromMiniAODAK4PuppiForwardJetTagsMetaDiscr + + +# === Negative tags === +pfNegativeParticleNetFromMiniAODAK4CHSCentralTagInfos = pfParticleNetFromMiniAODAK4CHSCentralTagInfos.clone( + flip_ip_sign = True, + max_sip3dsig_for_flip = 10, + secondary_vertices = 'inclusiveCandidateNegativeSecondaryVertices', +) +pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos = pfParticleNetFromMiniAODAK4PuppiCentralTagInfos.clone( + flip_ip_sign = True, + max_sip3dsig_for_flip = 10, + secondary_vertices = 'inclusiveCandidateNegativeSecondaryVertices', +) + +pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags = pfParticleNetFromMiniAODAK4CHSCentralJetTags.clone( + src = 'pfNegativeParticleNetFromMiniAODAK4CHSCentralTagInfos', +) +pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags = pfParticleNetFromMiniAODAK4PuppiCentralJetTags.clone( + src = 'pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos', +) + +# probs +_pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTagsProbs = ['pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags:' + flav_name + for flav_name in pfParticleNetFromMiniAODAK4CHSCentralJetTags.flav_names] +_pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTagsProbs = ['pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags:' + flav_name + for flav_name in pfParticleNetFromMiniAODAK4PuppiCentralJetTags.flav_names] diff --git a/RecoBTag/ONNXRuntime/python/pfParticleTransformerAK4_cff.py b/RecoBTag/ONNXRuntime/python/pfParticleTransformerAK4_cff.py index 0fb1c8ceac050..9df64c14f3406 100644 --- a/RecoBTag/ONNXRuntime/python/pfParticleTransformerAK4_cff.py +++ b/RecoBTag/ONNXRuntime/python/pfParticleTransformerAK4_cff.py @@ -27,3 +27,16 @@ pfParticleTransformerAK4FromMiniAODTask = cms.Task(pfParticleTransformerAK4TagInfos, pfParticleTransformerAK4JetTags, pfParticleTransformerAK4DiscriminatorsJetTags) + +# === Negative tags === +pfNegativeParticleTransformerAK4TagInfos = pfParticleTransformerAK4TagInfos.clone( + flip = True, + secondary_vertices = 'inclusiveCandidateNegativeSecondaryVertices', +) +pfNegativeParticleTransformerAK4JetTags = pfParticleTransformerAK4JetTags.clone( + src = 'pfNegativeParticleTransformerAK4TagInfos', +) + +# probs +_pfNegativeParticleTransformerAK4JetTagsProbs = ['pfNegativeParticleTransformerAK4JetTags:' + flav_name + for flav_name in pfParticleTransformerAK4JetTags.flav_names] From e8e440414f5a1a62eec620ab9afde1d24c41c36a Mon Sep 17 00:00:00 2001 From: Congqiao Li Date: Thu, 29 Jun 2023 18:02:14 +0200 Subject: [PATCH 3/9] Adding max_sip3dsig_for_flip for ParTAK4 feature producer, clearn up --- .gitignore | 4 +- PhysicsTools/NanoAOD/python/custom_btv_cff.py | 446 +++++++++--------- PhysicsTools/NanoAOD/python/nano_cff.py | 2 - .../PatAlgos/python/tools/jetTools.py | 14 +- .../plugins/ParticleNetFeatureEvaluator.cc | 26 +- .../ParticleTransformerAK4TagInfoProducer.cc | 7 +- 6 files changed, 245 insertions(+), 254 deletions(-) diff --git a/.gitignore b/.gitignore index c417ee75f908c..8925c98ef58da 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ __init__.py #*# *~ *.pb -RecoBTag + # ignore partially applied patches and their backup *.rej *.orig @@ -13,6 +13,8 @@ RecoBTag + + # ignore files under the top level $CMSSW_BASE/src directory, but not its subdirectories /* !/*/ diff --git a/PhysicsTools/NanoAOD/python/custom_btv_cff.py b/PhysicsTools/NanoAOD/python/custom_btv_cff.py index e35aa80f52a45..0b8f89cc97c76 100644 --- a/PhysicsTools/NanoAOD/python/custom_btv_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_btv_cff.py @@ -6,9 +6,26 @@ from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection from PhysicsTools.PatAlgos.tools.helpers import addToProcessAndTask, getPatAlgosToolsTask from PhysicsTools.NanoAOD.common_cff import Var, CandVars +from PhysicsTools.NanoAOD.simpleCandidateFlatTableProducer_cfi import simpleCandidateFlatTableProducer +## Move PFNano (https://github.com/cms-jet/PFNano/) to NanoAOD +## From: https://github.com/cms-jet/PFNano/blob/13_0_7_from124MiniAOD/python/addBTV.py +## Define customized GenParticles +def customize_BTV_GenTable(process): + process.finalGenParticles.select += [ + "keep (4 <= abs(pdgId) <= 5) && statusFlags().isLastCopy()", # BTV: keep b/c quarks in their last copy + "keep (abs(pdgId) == 310 || abs(pdgId) == 3122) && statusFlags().isLastCopy()", # BTV: keep K0s and Lambdas in their last copy + ] + process.genParticleTable.variables = cms.PSet( + process.genParticleTable.variables, + vx = Var("vx", "float", doc="x coordinate of vertex position"), + vy = Var("vy", "float", doc="y coordinate of vertex position"), + vz = Var("vz", "float", doc="z coordinate of vertex position"), + genPartIdxMother2 = Var("?numberOfMothers>1?motherRef(1).key():-1", "int", doc="index of the second mother particle, if valid"), + ) + def update_jets_AK4(process): # Based on ``nanoAOD_addDeepInfo`` # in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/nano_cff.py @@ -67,7 +84,6 @@ def update_jets_AK4(process): return process - def update_jets_AK8(process): # Based on ``nanoAOD_addDeepInfoAK8`` # in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/nano_cff.py @@ -110,7 +126,6 @@ def update_jets_AK8(process): process.updatedPatJetsTransientCorrectedAK8WithDeepInfo.addTagInfos = cms.bool(True) return process - def update_jets_AK8_subjet(process): # Based on ``nanoAOD_addDeepInfoAK8`` # in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/nano_cff.py @@ -248,7 +263,7 @@ def get_DeepCSV_vars(): ) return DeepCSVVars - +## Store all output nodes, negative tagger for SF def get_DeepJet_outputs(): DeepJetOutputVars = cms.PSet( btagDeepFlavB_b=Var("bDiscriminator('pfDeepFlavourJetTags:probb')", @@ -321,7 +336,6 @@ def get_DeepJet_outputs(): ) return DeepJetOutputVars - def get_ParticleNetAK4_outputs(): ## default scores in jetAK4_Puppi_cff.py collections ParticleNetAK4OutputVars = cms.PSet( @@ -376,7 +390,6 @@ def get_ParticleNetAK4_outputs(): return ParticleNetAK4OutputVars - def get_ParticleTransformerAK4_outputs(): ParticleTransformerAK4OutputVars = cms.PSet( btagRobustParTAK4B_b=Var("bDiscriminator('pfParticleTransformerAK4JetTags:probb')", @@ -449,172 +462,45 @@ def get_ParticleTransformerAK4_outputs(): return ParticleTransformerAK4OutputVars - -def customize_BTV_GenTable(process): - process.finalGenParticles.select += [ - "keep (4 <= abs(pdgId) <= 5) && statusFlags().isLastCopy()", # BTV: keep b/c quarks in their last copy - "keep (abs(pdgId) == 310 || abs(pdgId) == 3122) && statusFlags().isLastCopy()", # BTV: keep K0s and Lambdas in their last copy - ] - process.genParticleTable.variables = cms.PSet( - process.genParticleTable.variables, - vx = Var("vx", "float", doc="x coordinate of vertex position"), - vy = Var("vy", "float", doc="y coordinate of vertex position"), - vz = Var("vz", "float", doc="z coordinate of vertex position"), - genPartIdxMother2 = Var("?numberOfMothers>1?motherRef(1).key():-1", "int", doc="index of the second mother particle, if valid"), +def get_CommVars(): + # store all nodes and negative tagger for BTV SFs + CommonVars = cms.PSet( + Proba=Var("bDiscriminator('pfJetProbabilityBJetTags')", + float, + doc="Jet Probability (Usage:BTV)", + precision=10), + ProbaN=Var("bDiscriminator('pfNegativeOnlyJetProbabilityBJetTags')", + float, + doc="Negative-only Jet Probability (Usage:BTV)", + precision=10), + Bprob=Var("bDiscriminator('pfJetBProbabilityBJetTags')", + float, + doc="Jet B Probability (Usage:BTV)", + precision=10), + BprobN=Var("bDiscriminator('pfNegativeOnlyJetBProbabilityBJetTags')", + float, + doc="Negative-only Jet B Probability (Usage:BTV)", + precision=10), + btagDeepB_b=Var("bDiscriminator('pfDeepCSVJetTags:probb')", + float, + doc="DeepCSV b tag discriminator", + precision=10), + btagDeepB_bb=Var("bDiscriminator('pfDeepCSVJetTags:probbb')", + float, + doc="DeepCSV bb tag discriminator", + precision=10), + btagDeepC=Var("bDiscriminator('pfDeepCSVJetTags:probc')", + float, + doc="DeepCSV c btag discriminator", + precision=10), + btagDeepL=Var("bDiscriminator('pfDeepCSVJetTags:probudsg')", + float, + doc="DeepCSV light btag discriminator", + precision=10), ) + return CommonVars -def addPFCands(process, runOnMC=False, allPF = False, onlyAK4=False, onlyAK8=False): - process.customizedPFCandsTask = cms.Task( ) - process.schedule.associate(process.customizedPFCandsTask) - - process.finalJetsAK8Constituents = cms.EDProducer("PatJetConstituentPtrSelector", - src = cms.InputTag("finalJetsAK8"), - cut = cms.string("") - ) - process.finalJetsAK4Constituents = cms.EDProducer("PatJetConstituentPtrSelector", - src = cms.InputTag("finalJetsPuppi"), - cut = cms.string("") - ) - if allPF: - candInput = cms.InputTag("packedPFCandidates") - elif onlyAK4: - candList = cms.VInputTag(cms.InputTag("finalJetsAK4Constituents", "constituents")) - process.customizedPFCandsTask.add(process.finalJetsAK4Constituents) - process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - candInput = cms.InputTag("finalJetsConstituents") - elif onlyAK8: - candList = cms.VInputTag(cms.InputTag("finalJetsAK8Constituents", "constituents")) - process.customizedPFCandsTask.add(process.finalJetsAK8Constituents) - process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - candInput = cms.InputTag("finalJetsConstituents") - else: - candList = cms.VInputTag(cms.InputTag("finalJetsAK4Constituents", "constituents"), cms.InputTag("finalJetsAK8Constituents", "constituents")) - process.customizedPFCandsTask.add(process.finalJetsAK4Constituents) - process.customizedPFCandsTask.add(process.finalJetsAK8Constituents) - process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - candInput = cms.InputTag("finalJetsConstituents") - process.customConstituentsExtTable = cms.EDProducer("SimpleCandidateFlatTableProducer", - src = candInput, - cut = cms.string(""), #we should not filter after pruning - name = cms.string("PFCands"), - doc = cms.string("interesting particles from AK4 and AK8 jets"), - singleton = cms.bool(False), # the number of entries is variable - extension = cms.bool(False), # this is the extension table for the AK8 constituents - variables = cms.PSet(CandVars, - puppiWeight = Var("puppiWeight()", float, doc="Puppi weight",precision=10), - puppiWeightNoLep = Var("puppiWeightNoLep()", float, doc="Puppi weight removing leptons",precision=10), - vtxChi2 = Var("?hasTrackDetails()?vertexChi2():-1", float, doc="vertex chi2",precision=10), - trkChi2 = Var("?hasTrackDetails()?pseudoTrack().normalizedChi2():-1", float, doc="normalized trk chi2", precision=10), - dz = Var("?hasTrackDetails()?dz():-1", float, doc="pf dz", precision=10), - dzErr = Var("?hasTrackDetails()?dzError():-1", float, doc="pf dz err", precision=10), - d0 = Var("?hasTrackDetails()?dxy():-1", float, doc="pf d0", precision=10), - d0Err = Var("?hasTrackDetails()?dxyError():-1", float, doc="pf d0 err", precision=10), - pvAssocQuality = Var("pvAssociationQuality()", int, doc="primary vertex association quality. 0: NotReconstructedPrimary, 1: OtherDeltaZ, 4: CompatibilityBTag, 5: CompatibilityDz, 6: UsedInFitLoose, 7: UsedInFitTight"), - lostInnerHits = Var("lostInnerHits()", int, doc="lost inner hits. -1: validHitInFirstPixelBarrelLayer, 0: noLostInnerHits, 1: oneLostInnerHit, 2: moreLostInnerHits"), - lostOuterHits = Var("?hasTrackDetails()?pseudoTrack().hitPattern().numberOfLostHits('MISSING_OUTER_HITS'):0", int, doc="lost outer hits"), - numberOfHits = Var("numberOfHits()", int, doc="number of hits"), - numberOfPixelHits = Var("numberOfPixelHits()", int, doc="number of pixel hits"), - trkQuality = Var("?hasTrackDetails()?pseudoTrack().qualityMask():0", int, doc="track quality mask"), - trkHighPurity = Var("?hasTrackDetails()?pseudoTrack().quality('highPurity'):0", bool, doc="track is high purity"), - trkAlgo = Var("?hasTrackDetails()?pseudoTrack().algo():-1", int, doc="track algorithm"), - trkP = Var("?hasTrackDetails()?pseudoTrack().p():-1", float, doc="track momemtum", precision=-1), - trkPt = Var("?hasTrackDetails()?pseudoTrack().pt():-1", float, doc="track pt", precision=-1), - trkEta = Var("?hasTrackDetails()?pseudoTrack().eta():-1", float, doc="track pt", precision=12), - trkPhi = Var("?hasTrackDetails()?pseudoTrack().phi():-1", float, doc="track phi", precision=12), - ) - ) - process.customAK8ConstituentsTable = cms.EDProducer("PatJetConstituentTableProducer", - candidates = candInput, - jets = cms.InputTag("finalJetsAK8"), - jet_radius = cms.double(0.8), - name = cms.string("FatJetPFCands"), - idx_name = cms.string("pFCandsIdx"), - nameSV = cms.string("FatJetSVs"), - idx_nameSV = cms.string("sVIdx"), - ) - process.customAK4ConstituentsTable = cms.EDProducer("PatJetConstituentTableProducer", - candidates = candInput, - jets = cms.InputTag("finalJetsPuppi"), # was finalJets before - jet_radius = cms.double(0.4), - name = cms.string("JetPFCands"), - idx_name = cms.string("pFCandsIdx"), - nameSV = cms.string("JetSVs"), - idx_nameSV = cms.string("sVIdx"), - ) - if not allPF: - process.customizedPFCandsTask.add(process.finalJetsConstituents) - process.customizedPFCandsTask.add(process.customConstituentsExtTable) - # linkedObjects are WIP for Run3 - process.customizedPFCandsTask.add(process.customAK8ConstituentsTable) - process.customizedPFCandsTask.add(process.customAK4ConstituentsTable) - - if runOnMC: - - process.genJetsAK8Constituents = cms.EDProducer("GenJetPackedConstituentPtrSelector", - src = cms.InputTag("slimmedGenJetsAK8"), - cut = cms.string("pt > 100.") - ) - - - process.genJetsAK4Constituents = process.genJetsAK8Constituents.clone( - src = cms.InputTag("slimmedGenJets"), - cut = cms.string("pt > 20") - ) - if allPF: - genCandInput = cms.InputTag("packedGenParticles") - elif onlyAK4: - genCandList = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents")) - genCandInput = cms.InputTag("genJetsConstituents") - process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - elif onlyAK8: - genCandList = cms.VInputTag(cms.InputTag("genJetsAK8Constituents", "constituents")) - genCandInput = cms.InputTag("genJetsConstituents") - process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - else: - genCandList = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents"), cms.InputTag("genJetsAK8Constituents", "constituents")) - genCandInput = cms.InputTag("genJetsConstituents") - process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - process.genJetsParticleTable = cms.EDProducer("SimpleCandidateFlatTableProducer", - src = genCandInput, - cut = cms.string(""), #we should not filter after pruning - name= cms.string("GenCands"), - doc = cms.string("interesting gen particles from AK4 and AK8 jets"), - singleton = cms.bool(False), # the number of entries is variable - extension = cms.bool(False), # this is the main table for the AK8 constituents - variables = cms.PSet(CandVars - ) - ) - process.genAK8ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", - candidates = genCandInput, - jets = cms.InputTag("genJetsAK8Constituents"), # Note: The name has "Constituents" in it, but these are the jets - name = cms.string("GenFatJetCands"), - nameSV = cms.string("GenFatJetSVs"), - idx_name = cms.string("pFCandsIdx"), - idx_nameSV = cms.string("sVIdx"), - readBtag = cms.bool(False)) - process.genAK4ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", - candidates = genCandInput, - jets = cms.InputTag("genJetsAK4Constituents"), # Note: The name has "Constituents" in it, but these are the jets - name = cms.string("GenJetCands"), - nameSV = cms.string("GenJetSVs"), - idx_name = cms.string("pFCandsIdx"), - idx_nameSV = cms.string("sVIdx"), - readBtag = cms.bool(False)) - process.customizedPFCandsTask.add(process.genJetsAK4Constituents) #Note: For gen need to add jets to the process to keep pt cuts. - process.customizedPFCandsTask.add(process.genJetsAK8Constituents) - if not allPF: - process.customizedPFCandsTask.add(process.genJetsConstituents) - process.customizedPFCandsTask.add(process.genJetsParticleTable) - process.customizedPFCandsTask.add(process.genAK8ConstituentsTable) - process.customizedPFCandsTask.add(process.genAK4ConstituentsTable) - - return process - - -def add_BTV(process, runOnMC=False, onlyAK4=False, onlyAK8=False, keepInputs=['DeepCSV','DeepJet','DDX']): - addAK4 = not onlyAK8 - addAK8 = not onlyAK4 - +def add_BTV(process, runOnMC=False, addAK4=False, addAK8=False): if addAK4: process = update_jets_AK4(process) if addAK8: @@ -681,7 +567,7 @@ def add_BTV(process, runOnMC=False, onlyAK4=False, onlyAK8=False, keepInputs=['D variables=cms.PSet( CommonVars, HadronCountingVars if runOnMC else cms.PSet(), # hadrons from Generator only relevant for MC - get_DeepCSV_vars() if ('DeepCSV' in keepInputs) else cms.PSet(), + get_DeepCSV_vars(), get_DeepJet_outputs(), # outputs are added in any case, inputs only if requested get_ParticleNetAK4_outputs(), get_ParticleTransformerAK4_outputs(), @@ -697,9 +583,9 @@ def add_BTV(process, runOnMC=False, onlyAK4=False, onlyAK8=False, keepInputs=['D btagRobustParTAK4QG = None, ) - if ('DeepJet' in keepInputs): - # from Run3 onwards, always set storeAK4Truth to True for MC - process.customAK4ConstituentsForDeepJetTable = cms.EDProducer("PatJetDeepJetTableProducer", + + # from Run3 onwards, always set storeAK4Truth to True for MC + process.customAK4ConstituentsForDeepJetTable = cms.EDProducer("PatJetDeepJetTableProducer", jets = cms.InputTag("linkedObjects","jets"), storeAK4Truth = cms.bool(runOnMC), ) @@ -716,7 +602,7 @@ def add_BTV(process, runOnMC=False, onlyAK4=False, onlyAK8=False, keepInputs=['D variables=cms.PSet( CommonVars, #HadronCountingVars if runOnMC else cms.PSet(), # only necessary before 106x - get_DDX_vars() if ('DDX' in keepInputs) else cms.PSet(), + get_DDX_vars() , )) # Subjets @@ -750,8 +636,7 @@ def add_BTV(process, runOnMC=False, onlyAK4=False, onlyAK8=False, keepInputs=['D if addAK4: process.customizeJetTask.add(process.customJetExtTable) - if ('DeepJet' in keepInputs): - process.customizeJetTask.add(process.customAK4ConstituentsForDeepJetTable) + process.customizeJetTask.add(process.customAK4ConstituentsForDeepJetTable) if addAK8: process.customizeJetTask.add(process.customFatJetExtTable) @@ -763,64 +648,169 @@ def add_BTV(process, runOnMC=False, onlyAK4=False, onlyAK8=False, keepInputs=['D if runOnMC: customize_BTV_GenTable(process) - return process - +# From https://github.com/cms-jet/PFNano/blob/13_0_7_from124MiniAOD/python/addPFCands_cff.py +def addPFCands(process, runOnMC=False, allPF = False, addAK4=False, addAK8=False): + print(allPF,addAK4,addAK8) + process.customizedPFCandsTask = cms.Task( ) + process.schedule.associate(process.customizedPFCandsTask) + process.finalJetsAK8Constituents = cms.EDProducer("PatJetConstituentPtrSelector", + src = cms.InputTag("finalJetsAK8"), + cut = cms.string("") + ) + process.finalJetsAK4Constituents = cms.EDProducer("PatJetConstituentPtrSelector", + src = cms.InputTag("finalJetsPuppi"), + cut = cms.string("") + ) + if allPF: + candInput = cms.InputTag("packedPFCandidates") + elif not addAK8: + candList = cms.VInputTag(cms.InputTag("finalJetsAK4Constituents", "constituents")) + process.customizedPFCandsTask.add(process.finalJetsAK4Constituents) + process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituents") + elif not addAK4: + candList = cms.VInputTag(cms.InputTag("finalJetsAK8Constituents", "constituents")) + process.customizedPFCandsTask.add(process.finalJetsAK8Constituents) + process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituents") + else: + candList = cms.VInputTag(cms.InputTag("finalJetsAK4Constituents", "constituents"), cms.InputTag("finalJetsAK8Constituents", "constituents")) + process.customizedPFCandsTask.add(process.finalJetsAK4Constituents) + process.customizedPFCandsTask.add(process.finalJetsAK8Constituents) + process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituents") + process.customConstituentsExtTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = candInput, + cut = cms.string(""), #we should not filter after pruning + name = cms.string("PFCands"), + doc = cms.string("interesting particles from AK4 and AK8 jets"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the extension table for the AK8 constituents + variables = cms.PSet(CandVars, + puppiWeight = Var("puppiWeight()", float, doc="Puppi weight",precision=10), + puppiWeightNoLep = Var("puppiWeightNoLep()", float, doc="Puppi weight removing leptons",precision=10), + vtxChi2 = Var("?hasTrackDetails()?vertexChi2():-1", float, doc="vertex chi2",precision=10), + trkChi2 = Var("?hasTrackDetails()?pseudoTrack().normalizedChi2():-1", float, doc="normalized trk chi2", precision=10), + dz = Var("?hasTrackDetails()?dz():-1", float, doc="pf dz", precision=10), + dzErr = Var("?hasTrackDetails()?dzError():-1", float, doc="pf dz err", precision=10), + d0 = Var("?hasTrackDetails()?dxy():-1", float, doc="pf d0", precision=10), + d0Err = Var("?hasTrackDetails()?dxyError():-1", float, doc="pf d0 err", precision=10), + pvAssocQuality = Var("pvAssociationQuality()", int, doc="primary vertex association quality. 0: NotReconstructedPrimary, 1: OtherDeltaZ, 4: CompatibilityBTag, 5: CompatibilityDz, 6: UsedInFitLoose, 7: UsedInFitTight"), + lostInnerHits = Var("lostInnerHits()", int, doc="lost inner hits. -1: validHitInFirstPixelBarrelLayer, 0: noLostInnerHits, 1: oneLostInnerHit, 2: moreLostInnerHits"), + lostOuterHits = Var("?hasTrackDetails()?pseudoTrack().hitPattern().numberOfLostHits('MISSING_OUTER_HITS'):0", int, doc="lost outer hits"), + numberOfHits = Var("numberOfHits()", int, doc="number of hits"), + numberOfPixelHits = Var("numberOfPixelHits()", int, doc="number of pixel hits"), + trkQuality = Var("?hasTrackDetails()?pseudoTrack().qualityMask():0", int, doc="track quality mask"), + trkHighPurity = Var("?hasTrackDetails()?pseudoTrack().quality('highPurity'):0", bool, doc="track is high purity"), + trkAlgo = Var("?hasTrackDetails()?pseudoTrack().algo():-1", int, doc="track algorithm"), + trkP = Var("?hasTrackDetails()?pseudoTrack().p():-1", float, doc="track momemtum", precision=-1), + trkPt = Var("?hasTrackDetails()?pseudoTrack().pt():-1", float, doc="track pt", precision=-1), + trkEta = Var("?hasTrackDetails()?pseudoTrack().eta():-1", float, doc="track pt", precision=12), + trkPhi = Var("?hasTrackDetails()?pseudoTrack().phi():-1", float, doc="track phi", precision=12), + ) + ) + process.customAK8ConstituentsTable = cms.EDProducer("PatJetConstituentTableProducer", + candidates = candInput, + jets = cms.InputTag("finalJetsAK8"), + jet_radius = cms.double(0.8), + name = cms.string("FatJetPFCands"), + idx_name = cms.string("pFCandsIdx"), + nameSV = cms.string("FatJetSVs"), + idx_nameSV = cms.string("sVIdx"), + ) + process.customAK4ConstituentsTable = cms.EDProducer("PatJetConstituentTableProducer", + candidates = candInput, + jets = cms.InputTag("finalJetsPuppi"), # was finalJets before + jet_radius = cms.double(0.4), + name = cms.string("JetPFCands"), + idx_name = cms.string("pFCandsIdx"), + nameSV = cms.string("JetSVs"), + idx_nameSV = cms.string("sVIdx"), + ) + if not allPF: + process.customizedPFCandsTask.add(process.finalJetsConstituents) + process.customizedPFCandsTask.add(process.customConstituentsExtTable) + # linkedObjects are WIP for Run3 + process.customizedPFCandsTask.add(process.customAK8ConstituentsTable) + process.customizedPFCandsTask.add(process.customAK4ConstituentsTable) -def PFnano_customizeMC(process): - addPFCands(process, True) - add_BTV(process, True, keepInputs=['DeepCSV','DeepJet','DDX']) - return process - -def PFnano_customizeMC_allPF(process): - addPFCands(process, True, True) - add_BTV(process, True, keepInputs=['DeepCSV','DeepJet','DDX']) - return process - -def PFnano_customizeMC_AK4JetsOnly(process): - addPFCands(process, True, False, True) - add_BTV(process, True, True, keepInputs=['DeepCSV','DeepJet']) - return process - -def PFnano_customizeMC_AK8JetsOnly(process): - addPFCands(process, True, False, False, True) - add_BTV(process, True, False, True, keepInputs=['DDX']) - return process - -def PFnano_customizeMC_noPF(process): - add_BTV(process, True, keepInputs=['DeepCSV','DeepJet','DDX']) - return process - -def PFnano_customizeMC_noInputs(process): - add_BTV(process, True, keepInputs=[]) - return process - - -#### DATA customization -def PFnano_customizeData(process): - addPFCands(process, False) - add_BTV(process, False, keepInputs=['DeepCSV','DeepJet','DDX']) - return process + if runOnMC: -def PFnano_customizeData_allPF(process): - addPFCands(process, False, True) - add_BTV(process, False, keepInputs=['DeepCSV','DeepJet','DDX']) - return process + process.genJetsAK8Constituents = cms.EDProducer("GenJetPackedConstituentPtrSelector", + src = cms.InputTag("slimmedGenJetsAK8"), + cut = cms.string("pt > 100.") + ) -def PFnano_customizeData_AK4JetsOnly(process): - addPFCands(process, False, False, True) - add_BTV(process, False, True, keepInputs=['DeepCSV','DeepJet']) + + process.genJetsAK4Constituents = process.genJetsAK8Constituents.clone( + src = cms.InputTag("slimmedGenJets"), + cut = cms.string("pt > 20") + ) + if allPF: + genCandInput = cms.InputTag("packedGenParticles") + elif addAK4 and not addAK8: + genCandList = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents")) + genCandInput = cms.InputTag("genJetsConstituents") + process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + elif addAK8 and not addAK4: + genCandList = cms.VInputTag(cms.InputTag("genJetsAK8Constituents", "constituents")) + genCandInput = cms.InputTag("genJetsConstituents") + process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + else: + genCandList = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents"), cms.InputTag("genJetsAK8Constituents", "constituents")) + genCandInput = cms.InputTag("genJetsConstituents") + process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + process.genJetsParticleTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = genCandInput, + cut = cms.string(""), #we should not filter after pruning + name= cms.string("GenCands"), + doc = cms.string("interesting gen particles from AK4 and AK8 jets"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the AK8 constituents + variables = cms.PSet(CandVars + ) + ) + process.genAK8ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", + candidates = genCandInput, + jets = cms.InputTag("genJetsAK8Constituents"), # Note: The name has "Constituents" in it, but these are the jets + name = cms.string("GenFatJetCands"), + nameSV = cms.string("GenFatJetSVs"), + idx_name = cms.string("pFCandsIdx"), + idx_nameSV = cms.string("sVIdx"), + readBtag = cms.bool(False)) + process.genAK4ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", + candidates = genCandInput, + jets = cms.InputTag("genJetsAK4Constituents"), # Note: The name has "Constituents" in it, but these are the jets + name = cms.string("GenJetCands"), + nameSV = cms.string("GenJetSVs"), + idx_name = cms.string("pFCandsIdx"), + idx_nameSV = cms.string("sVIdx"), + readBtag = cms.bool(False)) + process.customizedPFCandsTask.add(process.genJetsAK4Constituents) #Note: For gen need to add jets to the process to keep pt cuts. + process.customizedPFCandsTask.add(process.genJetsAK8Constituents) + if not allPF: + process.customizedPFCandsTask.add(process.genJetsConstituents) + process.customizedPFCandsTask.add(process.genJetsParticleTable) + process.customizedPFCandsTask.add(process.genAK8ConstituentsTable) + process.customizedPFCandsTask.add(process.genAK4ConstituentsTable) + return process -def PFnano_customizeData_AK8JetsOnly(process): - addPFCands(process, False, False, False, True) - add_BTV(process, False, False, True, keepInputs=['DDX']) - return process +## Switches for BTV nano +# Default(store SFs PFCands+TaggerInputs) for both AK4 & AK8 jets +# nanoAOD_addbtagAK4_switch, nanoAOD_addbtagAK8_switch True, nanoAOD_allPF_switch False -def PFnano_customizeData_noPF(process): - add_BTV(process, False, keepInputs=['DeepCSV','DeepJet','DDX']) - return process +nanoAOD_allPF_switch = False # Add all PF candidates, use for training +nanoAOD_addbtagAK4_switch = True # AAK +nanoAOD_addbtagAK8_switch = True -def PFnano_customizeData_noInputs(process): - add_BTV(process, False, keepInputs=[]) +def PrepBTVCustomNanoAOD_MC(process): + addPFCands(process, True, nanoAOD_allPF_switch,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) + add_BTV(process, True,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) return process +def PrepBTVCustomNanoAOD_DATA(process): + # only run if SFvar or allPFCands + addPFCands(process, False, nanoAOD_allPF_switch,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) + add_BTV(process, False,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) + return process \ No newline at end of file diff --git a/PhysicsTools/NanoAOD/python/nano_cff.py b/PhysicsTools/NanoAOD/python/nano_cff.py index 7be976259950e..515c0c75d066a 100644 --- a/PhysicsTools/NanoAOD/python/nano_cff.py +++ b/PhysicsTools/NanoAOD/python/nano_cff.py @@ -28,7 +28,6 @@ from PhysicsTools.NanoAOD.fsrPhotons_cff import * from PhysicsTools.NanoAOD.softActivity_cff import * from PhysicsTools.NanoAOD.l1trig_cff import * -from PhysicsTools.NanoAOD.custom_btv_cff import * nanoMetadata = cms.EDProducer("UniqueStringProducer", strings = cms.PSet( @@ -235,7 +234,6 @@ def nanoAOD_customizeCommon(process): addParticleNet=nanoAOD_addDeepInfoAK8_switch.nanoAOD_addParticleNet_switch, jecPayload=nanoAOD_addDeepInfoAK8_switch.jecPayload ) - process = PFnano_customizeMC(process) nanoAOD_tau_switch = cms.PSet( idsToAdd = cms.vstring(), diff --git a/PhysicsTools/PatAlgos/python/tools/jetTools.py b/PhysicsTools/PatAlgos/python/tools/jetTools.py index f1ed59547d7cb..7270022048df3 100644 --- a/PhysicsTools/PatAlgos/python/tools/jetTools.py +++ b/PhysicsTools/PatAlgos/python/tools/jetTools.py @@ -7,12 +7,10 @@ from PhysicsTools.PatAlgos.recoLayer0.bTagging_cff import * import sys from FWCore.ParameterSet.MassReplace import MassSearchReplaceAnyInputTagVisitor -from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4PuppiCentralTagInfos,pfParticleNetFromMiniAODAK4PuppiCentralJetTags,pfParticleNetFromMiniAODAK4PuppiCentralDiscriminatorsJetTags +from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4PuppiCentralTagInfos,pfParticleNetFromMiniAODAK4PuppiCentralJetTags,pfParticleNetFromMiniAODAK4PuppiCentralDiscriminatorsJetTags,pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4PuppiForwardTagInfos,pfParticleNetFromMiniAODAK4PuppiForwardJetTags,pfParticleNetFromMiniAODAK4PuppiForwardDiscriminatorsJetTags -from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4CHSCentralTagInfos,pfParticleNetFromMiniAODAK4CHSCentralJetTags,pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags +from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4CHSCentralTagInfos,pfParticleNetFromMiniAODAK4CHSCentralJetTags,pfParticleNetFromMiniAODAK4CHSCentralDiscriminatorsJetTags,pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfParticleNetFromMiniAODAK4CHSForwardTagInfos,pfParticleNetFromMiniAODAK4CHSForwardJetTags,pfParticleNetFromMiniAODAK4CHSForwardDiscriminatorsJetTags -from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfNegativeParticleNetFromMiniAODAK4PuppiCentralTagInfos,pfNegativeParticleNetFromMiniAODAK4PuppiCentralJetTags -from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK4_cff import pfNegativeParticleNetFromMiniAODAK4CHSCentralTagInfos,pfNegativeParticleNetFromMiniAODAK4CHSCentralJetTags from RecoBTag.ONNXRuntime.pfParticleNetFromMiniAODAK8_cff import pfParticleNetFromMiniAODAK8TagInfos,pfParticleNetFromMiniAODAK8JetTags,pfParticleNetFromMiniAODAK8DiscriminatorsJetTags ## dictionary with supported jet clustering algorithms @@ -686,10 +684,9 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou if 'ParticleTransformerAK4TagInfos' in btagInfo: svUsed = svSource if btagInfo == 'pfNegativeParticleTransformerAK4TagInfos': - svUsed = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix) - flip = True + svUsed, flip, max_sip3dsig_for_flip = cms.InputTag(btagPrefix+'inclusiveCandidateNegativeSecondaryVertices'+labelName+postfix), True, 10. else: - flip = False + svUsed, flip, max_sip3dsig_for_flip = svSource, False, -1. # use right input tags when running with RECO PF candidates, which actually # depends of whether jets use "particleFlow" if pfCandidates.value() == 'packedPFCandidates': @@ -711,7 +708,8 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou puppi_value_map = puppi_value_map, vertex_associator = vertex_associator, is_weighted_jet = is_weighted_jet, - flip = flip), + flip = flip, + max_sip3dsig_for_flip=max_sip3dsig_for_flip), process, task) if btagInfo == 'pfDeepDoubleXTagInfos': # can only run on PAT jets, so the updater needs to be used diff --git a/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc b/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc index 2867d4ed34139..e79d4fc54e4b9 100644 --- a/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc +++ b/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc @@ -64,7 +64,7 @@ class ParticleNetFeatureEvaluator : public edm::stream::EDProducer<> { const double max_eta_for_taus_; const bool include_neutrals_; const bool flip_ip_sign_; - const double max_sip3dsig_for_flip_ip_sign_; + const double max_sip3dsig_for_flip_; edm::EDGetTokenT muon_token_; edm::EDGetTokenT electron_token_; @@ -264,7 +264,7 @@ ParticleNetFeatureEvaluator::ParticleNetFeatureEvaluator(const edm::ParameterSet max_eta_for_taus_(iConfig.getParameter("max_eta_for_taus")), include_neutrals_(iConfig.getParameter("include_neutrals")), flip_ip_sign_(iConfig.getParameter("flip_ip_sign")), - max_sip3dsig_for_flip_ip_sign_(iConfig.getParameter("max_sip3dsig_for_flip")), + max_sip3dsig_for_flip_(iConfig.getParameter("max_sip3dsig_for_flip")), muon_token_(consumes(iConfig.getParameter("muons"))), electron_token_(consumes(iConfig.getParameter("electrons"))), photon_token_(consumes(iConfig.getParameter("photons"))), @@ -297,7 +297,7 @@ void ParticleNetFeatureEvaluator::fillDescriptions(edm::ConfigurationDescription desc.add("max_eta_for_taus", 2.5); desc.add("include_neutrals", true); desc.add("flip_ip_sign", false); - desc.add("max_sip3dsig_for_flip", -1); + desc.add("max_sip3dsig_for_flip", 99999); desc.add("vertices", edm::InputTag("offlineSlimmedPrimaryVertices")); desc.add("secondary_vertices", edm::InputTag("slimmedSecondaryVertices")); desc.add("pf_candidates", edm::InputTag("packedPFCandidates")); @@ -458,13 +458,11 @@ void ParticleNetFeatureEvaluator::fillParticleFeatures(DeepBoostedJetFeatures &f TVector3 cand_direction(candP3.x(), candP3.y(), candP3.z()); // only when computing the nagative tagger: remove charged candidates with high sip3d - if (flip_ip_sign_ && max_sip3dsig_for_flip_ip_sign_ > 0. && track) { + if (flip_ip_sign_ && track) { reco::TransientTrack transientTrack = track_builder_->build(*track); Measurement1D meas_ip3d = IPTools::signedImpactParameter3D(transientTrack, jet_ref_track_dir, *pv_).second; - float d3dsig = std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance()); - if (d3dsig > max_sip3dsig_for_flip_ip_sign_) { + if (!std::isnan(meas_ip3d.significance()) && meas_ip3d.significance() > max_sip3dsig_for_flip_) { continue; - std::cout << "// removed!!!" << d3dsig << std::endl; } } float ip_sign = flip_ip_sign_ ? -1.f : 1.f; @@ -537,8 +535,8 @@ void ParticleNetFeatureEvaluator::fillParticleFeatures(DeepBoostedJetFeatures &f fts.fill("jet_pfcand_trackjet_d3d", ip_sign * (std::isnan(meas_ip3d.value()) ? 0 : meas_ip3d.value())); fts.fill("jet_pfcand_trackjet_d3dsig", std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance())); - fts.fill("jet_pfcand_trackjet_dist", ip_sign * (std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value())); - fts.fill("jet_pfcand_trackjet_decayL", ip_sign * (std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value())); + fts.fill("jet_pfcand_trackjet_dist", std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value()); + fts.fill("jet_pfcand_trackjet_decayL", std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value()); } else { fts.fill("jet_pfcand_dzsig", 0); fts.fill("jet_pfcand_dxysig", 0); @@ -758,12 +756,12 @@ void ParticleNetFeatureEvaluator::fillLostTrackFeatures(DeepBoostedJetFeatures & const reco::Track *track = ltrack.bestTrack(); // only when computing the nagative tagger: remove charged candidates with high sip3d - if (flip_ip_sign_ && max_sip3dsig_for_flip_ip_sign_ > 0.) { + if (flip_ip_sign_) { reco::TransientTrack transientTrack = track_builder_->build(*track); Measurement1D meas_ip3d = IPTools::signedImpactParameter3D(transientTrack, jet_ref_track_dir, *pv_).second; - float d3dsig = std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance()); - if (d3dsig > max_sip3dsig_for_flip_ip_sign_) + if (!std::isnan(meas_ip3d.significance()) && meas_ip3d.significance() > max_sip3dsig_for_flip_) { continue; + } } float ip_sign = flip_ip_sign_ ? -1.f : 1.f; @@ -804,8 +802,8 @@ void ParticleNetFeatureEvaluator::fillLostTrackFeatures(DeepBoostedJetFeatures & fts.fill("jet_losttrack_trackjet_d3d", ip_sign * (std::isnan(meas_ip3d.value()) ? 0 : meas_ip3d.value())); fts.fill("jet_losttrack_trackjet_d3dsig", std::isnan(fabs(meas_ip3d.significance())) ? 0 : fabs(meas_ip3d.significance())); - fts.fill("jet_losttrack_trackjet_dist", ip_sign * (std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value())); - fts.fill("jet_losttrack_trackjet_decayL", ip_sign * (std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value())); + fts.fill("jet_losttrack_trackjet_dist", std::isnan(-meas_jetdist.value()) ? 0 : -meas_jetdist.value()); + fts.fill("jet_losttrack_trackjet_decayL", std::isnan(meas_decayl.value()) ? 0 : meas_decayl.value()); } else { fts.fill("jet_losttrack_track_chi2", 0); fts.fill("jet_losttrack_track_qual", 0); diff --git a/RecoBTag/FeatureTools/plugins/ParticleTransformerAK4TagInfoProducer.cc b/RecoBTag/FeatureTools/plugins/ParticleTransformerAK4TagInfoProducer.cc index 312dfd9852d57..048e5e62041bb 100644 --- a/RecoBTag/FeatureTools/plugins/ParticleTransformerAK4TagInfoProducer.cc +++ b/RecoBTag/FeatureTools/plugins/ParticleTransformerAK4TagInfoProducer.cc @@ -78,6 +78,7 @@ class ParticleTransformerAK4TagInfoProducer : public edm::stream::EDProducer<> { const double jet_radius_; const double min_candidate_pt_; const bool flip_; + const double max_sip3dsig_for_flip_; const edm::EDGetTokenT> jet_token_; const edm::EDGetTokenT vtx_token_; @@ -105,6 +106,7 @@ ParticleTransformerAK4TagInfoProducer::ParticleTransformerAK4TagInfoProducer(con : jet_radius_(iConfig.getParameter("jet_radius")), min_candidate_pt_(iConfig.getParameter("min_candidate_pt")), flip_(iConfig.getParameter("flip")), + max_sip3dsig_for_flip_(iConfig.getParameter("max_sip3dsig_for_flip")), jet_token_(consumes>(iConfig.getParameter("jets"))), vtx_token_(consumes(iConfig.getParameter("vertices"))), sv_token_(consumes(iConfig.getParameter("secondary_vertices"))), @@ -150,6 +152,7 @@ void ParticleTransformerAK4TagInfoProducer::fillDescriptions(edm::ConfigurationD desc.add("jet_radius", 0.4); desc.add("min_candidate_pt", 0.95); desc.add("flip", false); + desc.add("max_sip3dsig_for_flip", 99999); desc.add("vertices", edm::InputTag("offlinePrimaryVertices")); desc.add("puppi_value_map", edm::InputTag("puppi")); desc.add("secondary_vertices", edm::InputTag("inclusiveCandidateSecondaryVertices")); @@ -350,7 +353,9 @@ void ParticleTransformerAK4TagInfoProducer::produce(edm::Event& iEvent, const ed // get cached track info auto& trackinfo = trackinfos.at(i); - + if (flip_ && (trackinfo.getTrackSip3dSig() > max_sip3dsig_for_flip_)) { + continue; + } // get_ref to vector element auto& c_pf_features = features.c_pf_features.at(entry); // fill feature structure From 4b574a785996336826b1db8f17db0558c871dd7d Mon Sep 17 00:00:00 2001 From: Ming-Yan Lee Date: Thu, 23 Nov 2023 21:33:22 +0100 Subject: [PATCH 4/9] fix: undone PuppiJet JEC to extract btag info --- PhysicsTools/NanoAOD/interface/BTV_flavor.h | 12 +- .../NanoAOD/plugins/DeepJetTableProducer.cc | 953 +++++++++--------- .../plugins/JetConstituentTableProducer.cc | 85 +- PhysicsTools/NanoAOD/python/custom_btv_cff.py | 84 +- .../plugins/ParticleNetFeatureEvaluator.cc | 3 +- .../TemplatedTrackCountingComputer.h | 6 +- 6 files changed, 527 insertions(+), 616 deletions(-) diff --git a/PhysicsTools/NanoAOD/interface/BTV_flavor.h b/PhysicsTools/NanoAOD/interface/BTV_flavor.h index ac766bb251c34..78a51f1cf7300 100644 --- a/PhysicsTools/NanoAOD/interface/BTV_flavor.h +++ b/PhysicsTools/NanoAOD/interface/BTV_flavor.h @@ -1,7 +1,7 @@ int jet_flavour(const pat::Jet& jet, - const std::vector& gToBB, - const std::vector& gToCC, - const std::vector& neutrinosLepB, - const std::vector& neutrinosLepB_C, - const std::vector& alltaus, - bool usePhysForLightAndUndefined); + const std::vector& gToBB, + const std::vector& gToCC, + const std::vector& neutrinosLepB, + const std::vector& neutrinosLepB_C, + const std::vector& alltaus, + bool usePhysForLightAndUndefined); diff --git a/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc b/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc index ecc62e73c0451..e477f6690f1b9 100644 --- a/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc @@ -15,7 +15,7 @@ using namespace btagbtvdeep; #include "CommonTools/Utils/interface/StringCutObjectSelector.h" #include "DataFormats/NanoAOD/interface/FlatTable.h" -#include +#include // add tag info and a way to go back to the jet reference #include "FWCore/Framework/interface/makeRefToBaseProdFrom.h" @@ -28,545 +28,542 @@ using namespace btagbtvdeep; #include "PhysicsTools/NanoAOD/interface/BTV_flavor.h" -template +template class DeepJetTableProducer : public edm::stream::EDProducer<> { public: - explicit DeepJetTableProducer(const edm::ParameterSet &); + explicit DeepJetTableProducer(const edm::ParameterSet&); ~DeepJetTableProducer() override; - static void fillDescriptions(edm::ConfigurationDescriptions &descriptions); - + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); + int jet_flavour(const pat::Jet& jet, - const std::vector& gToBB, - const std::vector& gToCC, - const std::vector& neutrinosLepB, - const std::vector& neutrinosLepB_C, - const std::vector& alltaus, - bool usePhysForLightAndUndefined) { - - int hflav = abs(jet.hadronFlavour()); - int pflav = abs(jet.partonFlavour()); - int physflav = 0; - if ( !( jet.genJet() ) ){ - if (pflav == 0) return 999; - else return 1000; - } - if(jet.genParton()) physflav=abs(jet.genParton()->pdgId()); - std::size_t nbs = jet.jetFlavourInfo().getbHadrons().size(); - std::size_t ncs = jet.jetFlavourInfo().getcHadrons().size(); - - unsigned int nbFromGSP(0); - for (reco::GenParticle p : gToBB) { - double dr2(reco::deltaR2(jet, p)); - if (dr2 < jetR_ * jetR_) ++nbFromGSP; - } - - unsigned int ncFromGSP(0); - for (reco::GenParticle p : gToCC) { - double dr2(reco::deltaR2(jet, p)); - if (dr2 < jetR_ * jetR_) ++ncFromGSP; - } - - //std::cout << " jet pt = " << jet.pt() << " hfl = " << hflav << " pfl = " << pflav << " genpart = " << physflav - // << " nbFromGSP = " << nbFromGSP << " ncFromGSP = " << ncFromGSP - // << " nBhadrons " << nbs << " nCHadrons " << ncs << std::endl; - if(hflav == 5) { //B jet - if(nbs > 1) { - if (nbFromGSP > 0) return 511; - else return 510; - } - else if(nbs == 1) { - for (std::vector::const_iterator it = neutrinosLepB.begin(); it != neutrinosLepB.end(); ++it){ - if(reco::deltaR2(it->eta(),it->phi(),jet.eta(),jet.phi()) < 0.4*0.4) { - return 520; - } - } - for (std::vector::const_iterator it = neutrinosLepB_C.begin(); it != neutrinosLepB_C.end(); ++it){ - if(reco::deltaR2(it->eta(),it->phi(),jet.eta(),jet.phi()) < 0.4*0.4) { - return 521; - } - } - return 500; + const std::vector& gToBB, + const std::vector& gToCC, + const std::vector& neutrinosLepB, + const std::vector& neutrinosLepB_C, + const std::vector& alltaus, + bool usePhysForLightAndUndefined) { + int hflav = abs(jet.hadronFlavour()); + int pflav = abs(jet.partonFlavour()); + int physflav = 0; + if (!(jet.genJet())) { + if (pflav == 0) + return 999; + else + return 1000; + } + if (jet.genParton()) + physflav = abs(jet.genParton()->pdgId()); + std::size_t nbs = jet.jetFlavourInfo().getbHadrons().size(); + std::size_t ncs = jet.jetFlavourInfo().getcHadrons().size(); + + unsigned int nbFromGSP(0); + for (const reco::GenParticle& p : gToBB) { + double dr2(reco::deltaR2(jet, p)); + if (dr2 < jetR_ * jetR_) + ++nbFromGSP; + } + + unsigned int ncFromGSP(0); + for (const reco::GenParticle& p : gToCC) { + double dr2(reco::deltaR2(jet, p)); + if (dr2 < jetR_ * jetR_) + ++ncFromGSP; + } + + //std::cout << " jet pt = " << jet.pt() << " hfl = " << hflav << " pfl = " << pflav << " genpart = " << physflav + // << " nbFromGSP = " << nbFromGSP << " ncFromGSP = " << ncFromGSP + // << " nBhadrons " << nbs << " nCHadrons " << ncs << std::endl; + if (hflav == 5) { //B jet + if (nbs > 1) { + if (nbFromGSP > 0) + return 511; + else + return 510; + } else if (nbs == 1) { + for (std::vector::const_iterator it = neutrinosLepB.begin(); it != neutrinosLepB.end(); + ++it) { + if (reco::deltaR2(it->eta(), it->phi(), jet.eta(), jet.phi()) < 0.4 * 0.4) { + return 520; } - else { - if(usePhysForLightAndUndefined){ - if(physflav == 21) return 0; - else if(physflav == 3) return 2; - else if(physflav == 2 || physflav ==1) return 1; - else return 1000; - } - else return 1000; + } + for (std::vector::const_iterator it = neutrinosLepB_C.begin(); it != neutrinosLepB_C.end(); + ++it) { + if (reco::deltaR2(it->eta(), it->phi(), jet.eta(), jet.phi()) < 0.4 * 0.4) { + return 521; } + } + return 500; + } else { + if (usePhysForLightAndUndefined) { + if (physflav == 21) + return 0; + else if (physflav == 3) + return 2; + else if (physflav == 2 || physflav == 1) + return 1; + else + return 1000; + } else + return 1000; } - else if(hflav == 4) { //C jet - if (ncs > 1) { - if (ncFromGSP > 0) return 411; - else return 410; + } else if (hflav == 4) { //C jet + if (ncs > 1) { + if (ncFromGSP > 0) + return 411; + else + return 410; + } else + return 400; + } else { //not a heavy jet + if (!alltaus.empty()) { //check for tau in a simplistic way + bool ishadrtaucontained = true; + for (const auto& p : alltaus) { + size_t ndau = p.numberOfDaughters(); + for (size_t i = 0; i < ndau; i++) { + const reco::Candidate* dau = p.daughter(i); + int daupid = std::abs(dau->pdgId()); + if (daupid == 13 || daupid == 11) { + ishadrtaucontained = false; + break; + } + if (daupid != 12 && daupid != 14 && daupid != 16 && reco::deltaR2(*dau, jet) > jetR_ * jetR_) { + ishadrtaucontained = false; + break; + } } - else return 400; + } + if (ishadrtaucontained) + return 600; + } + if (std::abs(pflav) == 4 || std::abs(pflav) == 5 || nbs || ncs) { + if (usePhysForLightAndUndefined) { + if (physflav == 21) + return 0; + else if (physflav == 3) + return 2; + else if (physflav == 2 || physflav == 1) + return 1; + else + return 1000; + } else + return 1000; + } else if (usePhysForLightAndUndefined) { + if (physflav == 21) + return 0; + else if (physflav == 3) + return 2; + else if (physflav == 2 || physflav == 1) + return 1; + else + return 1000; + } else { + if (pflav == 21) + return 0; + else if (pflav == 3) + return 2; + else if (pflav == 2 || pflav == 1) + return 1; + else + return 1000; } - else { //not a heavy jet - if(alltaus.size()>0){ //check for tau in a simplistic way - bool ishadrtaucontained=true; - for(const auto& p:alltaus){ - size_t ndau=p.numberOfDaughters(); - for(size_t i=0;ipdgId()); - if(daupid == 13 || daupid == 11){ - ishadrtaucontained=false; - break; - } - if(daupid != 12 && daupid!=14 && daupid!=16 && - reco::deltaR2(*dau,jet) > jetR_*jetR_){ - ishadrtaucontained=false; - break; - } - } - } - if(ishadrtaucontained) return 600; - } - if(std::abs(pflav) == 4 || std::abs(pflav) == 5 || nbs || ncs) { - if(usePhysForLightAndUndefined){ - if(physflav == 21) return 0; - else if(physflav == 3) return 2; - else if(physflav == 2 || physflav ==1) return 1; - else return 1000; - } - else return 1000; - } - else if(usePhysForLightAndUndefined){ - if(physflav == 21) return 0; - else if(physflav == 3) return 2; - else if(physflav == 2 || physflav ==1) return 1; - else return 1000; - } - else { - if(pflav == 21) return 0; - else if(pflav == 3) return 2; - else if(pflav == 2 || pflav ==1) return 1; - else return 1000; - } - } - } - + } + private: - void produce(edm::Event &, const edm::EventSetup &) override; - + void produce(edm::Event&, const edm::EventSetup&) override; + const std::string nameDeepJet_; const std::string idx_nameDeepJet_; - const bool storeAK4Truth_; - - + const bool storeAK4Truth_; + const edm::EDGetTokenT genParticlesToken_; - + edm::EDGetTokenT> jet_token_; - + typedef std::vector TagInfoCollection; const edm::EDGetTokenT tag_info_src_; - + constexpr static unsigned n_cpf_ = 3; constexpr static unsigned n_npf_ = 3; - constexpr static unsigned n_sv_ = 4; // 5 - - constexpr static double jetR_ = 0.4; - - constexpr static bool usePhysForLightAndUndefined = false; - - + constexpr static unsigned n_sv_ = 4; // 5 + + constexpr static double jetR_ = 0.4; + + constexpr static bool usePhysForLightAndUndefined = false; }; // // constructors and destructor // -template< typename T> -DeepJetTableProducer::DeepJetTableProducer(const edm::ParameterSet &iConfig) +template +DeepJetTableProducer::DeepJetTableProducer(const edm::ParameterSet& iConfig) : nameDeepJet_(iConfig.getParameter("nameDeepJet")), idx_nameDeepJet_(iConfig.getParameter("idx_nameDeepJet")), storeAK4Truth_(iConfig.getParameter("storeAK4Truth")), genParticlesToken_(consumes(iConfig.getParameter("genparticles"))), jet_token_(consumes>(iConfig.getParameter("jets"))), - tag_info_src_(consumes(iConfig.getParameter("tagInfo_src"))){ + tag_info_src_(consumes(iConfig.getParameter("tagInfo_src"))) { produces(nameDeepJet_); } -template< typename T> +template DeepJetTableProducer::~DeepJetTableProducer() {} -template< typename T> -void DeepJetTableProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { +template +void DeepJetTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { // elements in all these collections must have the same order! - + // only necessary to explicitly check correct matching of jets // std::vector jetIdx_dj; - + edm::Handle genParticlesHandle; iEvent.getByToken(genParticlesToken_, genParticlesHandle); - + auto jets = iEvent.getHandle(jet_token_); edm::Handle tag_infos; iEvent.getByToken(tag_info_src_, tag_infos); - - - std::vector neutrinosLepB; - std::vector neutrinosLepB_C; - + + std::vector neutrinosLepB; + std::vector neutrinosLepB_C; + std::vector gToBB; std::vector gToCC; std::vector alltaus; - - + unsigned nJets = jets->size(); - + std::vector jet_N_CPFCands(nJets); std::vector jet_N_NPFCands(nJets); - std::vector jet_N_PVs(nJets); - std::vector jet_N_SVs(nJets); - - - std::vector jet_FlavSplit(nJets); - + std::vector jet_N_PVs(nJets); + std::vector jet_N_SVs(nJets); + + std::vector jet_FlavSplit(nJets); + // should default to 0 if less than nCpf cpf with information std::vector> Cpfcan_BtagPf_trackEtaRel_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_BtagPf_trackPtRel_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_BtagPf_trackPPar_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_BtagPf_trackDeltaR_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_BtagPf_trackPParRatio_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_BtagPf_trackSip2dVal_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_BtagPf_trackSip2dSig_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_BtagPf_trackSip3dVal_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_BtagPf_trackSip3dSig_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackPtRel_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackPPar_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackDeltaR_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackPParRatio_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackSip2dVal_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackSip2dSig_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackSip3dVal_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_BtagPf_trackSip3dSig_nCpf(n_cpf_, std::vector(nJets)); std::vector> Cpfcan_BtagPf_trackJetDistVal_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_ptrel_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_ptrel_nCpf(n_cpf_, std::vector(nJets)); std::vector> Cpfcan_drminsv_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_VTX_ass_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_VTX_ass_nCpf(n_cpf_, std::vector(nJets)); std::vector> Cpfcan_puppiw_nCpf(n_cpf_, std::vector(nJets)); - std::vector> Cpfcan_chi2_nCpf(n_cpf_, std::vector(nJets)); + std::vector> Cpfcan_chi2_nCpf(n_cpf_, std::vector(nJets)); std::vector> Cpfcan_quality_nCpf(n_cpf_, std::vector(nJets)); - - + // should default to 0 if less than nNpf npf with information std::vector> Npfcan_ptrel_nNpf(n_npf_, std::vector(nJets)); - std::vector> Npfcan_deltaR_nNpf(n_npf_, std::vector(nJets)); - std::vector> Npfcan_isGamma_nNpf(n_npf_, std::vector(nJets)); - std::vector> Npfcan_HadFrac_nNpf(n_npf_, std::vector(nJets)); - std::vector> Npfcan_drminsv_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_deltaR_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_isGamma_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_HadFrac_nNpf(n_npf_, std::vector(nJets)); + std::vector> Npfcan_drminsv_nNpf(n_npf_, std::vector(nJets)); std::vector> Npfcan_puppiw_nNpf(n_npf_, std::vector(nJets)); /* // only after dataformat updated as well std::vector> Npfcan_etarel_nNpf(n_npf_, std::vector(nJets)); std::vector> Npfcan_phirel_nNpf(n_npf_, std::vector(nJets)); */ - - + // should default to 0 if less than nSv SVs with information std::vector> sv_mass_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_pt_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_ntracks_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_chi2_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_normchi2_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_dxy_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_dxysig_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_d3d_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_d3dsig_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_pt_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_ntracks_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_chi2_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_normchi2_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_dxy_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_dxysig_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_d3d_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_d3dsig_nSV(n_sv_, std::vector(nJets)); std::vector> sv_costhetasvpv_nSV(n_sv_, std::vector(nJets)); /* // only after dataformat updated as well std::vector> sv_etarel_nSV(n_sv_, std::vector(nJets)); std::vector> sv_phirel_nSV(n_sv_, std::vector(nJets)); */ - std::vector> sv_deltaR_nSV(n_sv_, std::vector(nJets)); - std::vector> sv_enratio_nSV(n_sv_, std::vector(nJets)); - - if (storeAK4Truth_) { + std::vector> sv_deltaR_nSV(n_sv_, std::vector(nJets)); + std::vector> sv_enratio_nSV(n_sv_, std::vector(nJets)); + if (storeAK4Truth_) { neutrinosLepB.clear(); neutrinosLepB_C.clear(); gToBB.clear(); gToCC.clear(); - alltaus.clear(); - - for (const reco::Candidate &genC : *genParticlesHandle) { - const reco::GenParticle &gen = static_cast< const reco::GenParticle &>(genC); - if(abs(gen.pdgId())==12||abs(gen.pdgId())==14||abs(gen.pdgId())==16) { - const reco::GenParticle* mother = static_cast< const reco::GenParticle*> (gen.mother()); - if(mother!=NULL) { - if((abs(mother->pdgId())>500&&abs(mother->pdgId())<600)||(abs(mother->pdgId())>5000&&abs(mother->pdgId())<6000)) { - neutrinosLepB.emplace_back(gen); - } - if((abs(mother->pdgId())>400&&abs(mother->pdgId())<500)||(abs(mother->pdgId())>4000&&abs(mother->pdgId())<5000)) { - neutrinosLepB_C.emplace_back(gen); - } + alltaus.clear(); + + for (const reco::Candidate& genC : *genParticlesHandle) { + const reco::GenParticle& gen = static_cast(genC); + if (abs(gen.pdgId()) == 12 || abs(gen.pdgId()) == 14 || abs(gen.pdgId()) == 16) { + const reco::GenParticle* mother = static_cast(gen.mother()); + if (mother != nullptr) { + if ((abs(mother->pdgId()) > 500 && abs(mother->pdgId()) < 600) || + (abs(mother->pdgId()) > 5000 && abs(mother->pdgId()) < 6000)) { + neutrinosLepB.emplace_back(gen); } - else { - std::cout << "No mother" << std::endl; + if ((abs(mother->pdgId()) > 400 && abs(mother->pdgId()) < 500) || + (abs(mother->pdgId()) > 4000 && abs(mother->pdgId()) < 5000)) { + neutrinosLepB_C.emplace_back(gen); } + } else { + std::cout << "No mother" << std::endl; + } } - int id(std::abs(gen.pdgId())); + int id(std::abs(gen.pdgId())); int status(gen.status()); - if (id == 21 && status >= 21 && status <= 59) { //// Pythia8 hard scatter, ISR, or FSR - if ( gen.numberOfDaughters() == 2 ) { - const reco::Candidate* d0 = gen.daughter(0); - const reco::Candidate* d1 = gen.daughter(1); - if ( std::abs(d0->pdgId()) == 5 && std::abs(d1->pdgId()) == 5 - && d0->pdgId()*d1->pdgId() < 0 && reco::deltaR2(*d0, *d1) < jetR_ * jetR_) gToBB.push_back(gen) ; - if ( std::abs(d0->pdgId()) == 4 && std::abs(d1->pdgId()) == 4 - && d0->pdgId()*d1->pdgId() < 0 && reco::deltaR2(*d0, *d1) < jetR_ * jetR_) gToCC.push_back(gen) ; - } + if (id == 21 && status >= 21 && status <= 59) { //// Pythia8 hard scatter, ISR, or FSR + if (gen.numberOfDaughters() == 2) { + const reco::Candidate* d0 = gen.daughter(0); + const reco::Candidate* d1 = gen.daughter(1); + if (std::abs(d0->pdgId()) == 5 && std::abs(d1->pdgId()) == 5 && d0->pdgId() * d1->pdgId() < 0 && + reco::deltaR2(*d0, *d1) < jetR_ * jetR_) + gToBB.push_back(gen); + if (std::abs(d0->pdgId()) == 4 && std::abs(d1->pdgId()) == 4 && d0->pdgId() * d1->pdgId() < 0 && + reco::deltaR2(*d0, *d1) < jetR_ * jetR_) + gToCC.push_back(gen); + } } - if(id == 15 && false){ - alltaus.push_back(gen); + if (id == 15 && false) { + alltaus.push_back(gen); } - } - } - - if (!tag_infos->empty()) { - - for (unsigned i_jet = 0; i_jet < nJets; ++i_jet) { - - - if (storeAK4Truth_) { - - // from DeepNTuples - const auto &jet = jets->at(i_jet); - - - jet_FlavSplit[i_jet] = jet_flavour(jet, gToBB, gToCC, neutrinosLepB, neutrinosLepB_C, alltaus, usePhysForLightAndUndefined); - - } - - // jet loop reads tag info instead of constituent info - - const auto& taginfo = (*tag_infos)[i_jet]; - const auto& features = taginfo.features(); - - - // jet.pt and jet.eta as well as other jet variables (ShallowTagInfo) already included (via DeepCSV) - - // number of elements in different collections - jet_N_CPFCands[i_jet] = features.c_pf_features.size(); - jet_N_NPFCands[i_jet] = features.n_pf_features.size(); - jet_N_SVs[i_jet] = features.sv_features.size(); - jet_N_PVs[i_jet] = features.npv; - - // c_pf candidates - auto max_c_pf_n = std::min(features.c_pf_features.size(), (std::size_t)n_cpf_); - for (std::size_t c_pf_n = 0; c_pf_n < max_c_pf_n; c_pf_n++) { - const auto& c_pf_features = features.c_pf_features.at(c_pf_n); - Cpfcan_BtagPf_trackEtaRel_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackEtaRel; - Cpfcan_BtagPf_trackPtRel_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPtRel; - Cpfcan_BtagPf_trackPPar_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPPar; - Cpfcan_BtagPf_trackDeltaR_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackDeltaR; - Cpfcan_BtagPf_trackPParRatio_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPParRatio; - Cpfcan_BtagPf_trackSip2dVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip2dVal; - Cpfcan_BtagPf_trackSip2dSig_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip2dSig; - Cpfcan_BtagPf_trackSip3dVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip3dVal; - Cpfcan_BtagPf_trackSip3dSig_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip3dSig; - Cpfcan_BtagPf_trackJetDistVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackJetDistVal; - Cpfcan_ptrel_nCpf[c_pf_n][i_jet] = c_pf_features.ptrel; - Cpfcan_drminsv_nCpf[c_pf_n][i_jet] = c_pf_features.drminsv; - Cpfcan_VTX_ass_nCpf[c_pf_n][i_jet] = c_pf_features.vtx_ass; - Cpfcan_puppiw_nCpf[c_pf_n][i_jet] = c_pf_features.puppiw; - Cpfcan_chi2_nCpf[c_pf_n][i_jet] = c_pf_features.chi2; - Cpfcan_quality_nCpf[c_pf_n][i_jet] = c_pf_features.quality; - } - - // n_pf candidates - auto max_n_pf_n = std::min(features.n_pf_features.size(), (std::size_t)n_npf_); - for (std::size_t n_pf_n = 0; n_pf_n < max_n_pf_n; n_pf_n++) { - const auto& n_pf_features = features.n_pf_features.at(n_pf_n); - Npfcan_ptrel_nNpf[n_pf_n][i_jet] = n_pf_features.ptrel; - Npfcan_deltaR_nNpf[n_pf_n][i_jet] = n_pf_features.deltaR; - Npfcan_isGamma_nNpf[n_pf_n][i_jet] = n_pf_features.isGamma; - Npfcan_HadFrac_nNpf[n_pf_n][i_jet] = n_pf_features.hadFrac; - Npfcan_drminsv_nNpf[n_pf_n][i_jet] = n_pf_features.drminsv; - Npfcan_puppiw_nNpf[n_pf_n][i_jet] = n_pf_features.puppiw; - /* + + if (!tag_infos->empty()) { + for (unsigned i_jet = 0; i_jet < nJets; ++i_jet) { + if (storeAK4Truth_) { + // from DeepNTuples + const auto& jet = jets->at(i_jet); + + jet_FlavSplit[i_jet] = + jet_flavour(jet, gToBB, gToCC, neutrinosLepB, neutrinosLepB_C, alltaus, usePhysForLightAndUndefined); + } + + // jet loop reads tag info instead of constituent info + + const auto& taginfo = (*tag_infos)[i_jet]; + const auto& features = taginfo.features(); + + // jet.pt and jet.eta as well as other jet variables (ShallowTagInfo) already included (via DeepCSV) + + // number of elements in different collections + jet_N_CPFCands[i_jet] = features.c_pf_features.size(); + jet_N_NPFCands[i_jet] = features.n_pf_features.size(); + jet_N_SVs[i_jet] = features.sv_features.size(); + jet_N_PVs[i_jet] = features.npv; + + // c_pf candidates + auto max_c_pf_n = std::min(features.c_pf_features.size(), (std::size_t)n_cpf_); + for (std::size_t c_pf_n = 0; c_pf_n < max_c_pf_n; c_pf_n++) { + const auto& c_pf_features = features.c_pf_features.at(c_pf_n); + Cpfcan_BtagPf_trackEtaRel_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackEtaRel; + Cpfcan_BtagPf_trackPtRel_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPtRel; + Cpfcan_BtagPf_trackPPar_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPPar; + Cpfcan_BtagPf_trackDeltaR_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackDeltaR; + Cpfcan_BtagPf_trackPParRatio_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackPParRatio; + Cpfcan_BtagPf_trackSip2dVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip2dVal; + Cpfcan_BtagPf_trackSip2dSig_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip2dSig; + Cpfcan_BtagPf_trackSip3dVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip3dVal; + Cpfcan_BtagPf_trackSip3dSig_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackSip3dSig; + Cpfcan_BtagPf_trackJetDistVal_nCpf[c_pf_n][i_jet] = c_pf_features.btagPf_trackJetDistVal; + Cpfcan_ptrel_nCpf[c_pf_n][i_jet] = c_pf_features.ptrel; + Cpfcan_drminsv_nCpf[c_pf_n][i_jet] = c_pf_features.drminsv; + Cpfcan_VTX_ass_nCpf[c_pf_n][i_jet] = c_pf_features.vtx_ass; + Cpfcan_puppiw_nCpf[c_pf_n][i_jet] = c_pf_features.puppiw; + Cpfcan_chi2_nCpf[c_pf_n][i_jet] = c_pf_features.chi2; + Cpfcan_quality_nCpf[c_pf_n][i_jet] = c_pf_features.quality; + } + + // n_pf candidates + auto max_n_pf_n = std::min(features.n_pf_features.size(), (std::size_t)n_npf_); + for (std::size_t n_pf_n = 0; n_pf_n < max_n_pf_n; n_pf_n++) { + const auto& n_pf_features = features.n_pf_features.at(n_pf_n); + Npfcan_ptrel_nNpf[n_pf_n][i_jet] = n_pf_features.ptrel; + Npfcan_deltaR_nNpf[n_pf_n][i_jet] = n_pf_features.deltaR; + Npfcan_isGamma_nNpf[n_pf_n][i_jet] = n_pf_features.isGamma; + Npfcan_HadFrac_nNpf[n_pf_n][i_jet] = n_pf_features.hadFrac; + Npfcan_drminsv_nNpf[n_pf_n][i_jet] = n_pf_features.drminsv; + Npfcan_puppiw_nNpf[n_pf_n][i_jet] = n_pf_features.puppiw; + /* // only after dataformat updated as well Npfcan_etarel_nNpf[n_pf_n][i_jet] = n_pf_features.etarel; Npfcan_phirel_nNpf[n_pf_n][i_jet] = n_pf_features.phirel; */ - } + } - // sv candidates - auto max_sv_n = std::min(features.sv_features.size(), (std::size_t)n_sv_); - for (std::size_t sv_n = 0; sv_n < max_sv_n; sv_n++) { - const auto& sv_features = features.sv_features.at(sv_n); - sv_pt_nSV[sv_n][i_jet] = sv_features.pt; - sv_deltaR_nSV[sv_n][i_jet] = sv_features.deltaR; - sv_mass_nSV[sv_n][i_jet] = sv_features.mass; - sv_ntracks_nSV[sv_n][i_jet] = sv_features.ntracks; - sv_chi2_nSV[sv_n][i_jet] = sv_features.chi2; - sv_normchi2_nSV[sv_n][i_jet] = sv_features.normchi2; - sv_dxy_nSV[sv_n][i_jet] = sv_features.dxy; - sv_dxysig_nSV[sv_n][i_jet] = sv_features.dxysig; - sv_d3d_nSV[sv_n][i_jet] = sv_features.d3d; - sv_d3dsig_nSV[sv_n][i_jet] = sv_features.d3dsig; - sv_costhetasvpv_nSV[sv_n][i_jet] = sv_features.costhetasvpv; - sv_enratio_nSV[sv_n][i_jet] = sv_features.enratio; - /* + // sv candidates + auto max_sv_n = std::min(features.sv_features.size(), (std::size_t)n_sv_); + for (std::size_t sv_n = 0; sv_n < max_sv_n; sv_n++) { + const auto& sv_features = features.sv_features.at(sv_n); + sv_pt_nSV[sv_n][i_jet] = sv_features.pt; + sv_deltaR_nSV[sv_n][i_jet] = sv_features.deltaR; + sv_mass_nSV[sv_n][i_jet] = sv_features.mass; + sv_ntracks_nSV[sv_n][i_jet] = sv_features.ntracks; + sv_chi2_nSV[sv_n][i_jet] = sv_features.chi2; + sv_normchi2_nSV[sv_n][i_jet] = sv_features.normchi2; + sv_dxy_nSV[sv_n][i_jet] = sv_features.dxy; + sv_dxysig_nSV[sv_n][i_jet] = sv_features.dxysig; + sv_d3d_nSV[sv_n][i_jet] = sv_features.d3d; + sv_d3dsig_nSV[sv_n][i_jet] = sv_features.d3dsig; + sv_costhetasvpv_nSV[sv_n][i_jet] = sv_features.costhetasvpv; + sv_enratio_nSV[sv_n][i_jet] = sv_features.enratio; + /* // only after dataformat updated as well sv_etarel_nSV[sv_n][i_jet] = sv_features.etarel; sv_phirel_nSV[sv_n][i_jet] = sv_features.phirel; */ - } } + } } - + // DeepJetInputs table auto djTable = std::make_unique(jet_N_CPFCands.size(), nameDeepJet_, false, true); //djTable->addColumn("DeepJet_jetIdx", jetIdx_dj, "Index of the parent jet", ); - - - djTable->addColumn("DeepJet_nCpfcand", - jet_N_CPFCands, - "Number of charged PF candidates in the jet" - ); - djTable->addColumn("DeepJet_nNpfcand", - jet_N_NPFCands, - "Number of neutral PF candidates in the jet" - ); - djTable->addColumn("DeepJet_nsv", - jet_N_SVs, - "Number of secondary vertices in the jet" - ); - djTable->addColumn("DeepJet_npv", - jet_N_PVs, - "Number of primary vertices" - ); - - //if (true) { - if (storeAK4Truth_) { - //std::cout << "Start filling table with truth info" << std::endl; - djTable->addColumn("FlavSplit", - jet_FlavSplit, - "Flavour of the jet, numerical codes: " - "isG: 0, " - "isUD: 1, " - "isS: 2, " - "isC: 400, " - "isCC: 410, " - "isGCC: 411, " - "isB: 500, " - "isBB: 510, " - "isGBB: 511, " - "isLeptonicB: 520, " - "isLeptonicB_C: 521, " - "isTAU: 600, " - "isPU: 999," - "isUndefined: 1000. " - "May be combined to form coarse labels for tagger training and flavour dependent attacks using the loss surface." - ); + + djTable->addColumn("DeepJet_nCpfcand", jet_N_CPFCands, "Number of charged PF candidates in the jet"); + djTable->addColumn("DeepJet_nNpfcand", jet_N_NPFCands, "Number of neutral PF candidates in the jet"); + djTable->addColumn("DeepJet_nsv", jet_N_SVs, "Number of secondary vertices in the jet"); + djTable->addColumn("DeepJet_npv", jet_N_PVs, "Number of primary vertices"); + + //if (true) { + if (storeAK4Truth_) { + //std::cout << "Start filling table with truth info" << std::endl; + djTable->addColumn("FlavSplit", + jet_FlavSplit, + "Flavour of the jet, numerical codes: " + "isG: 0, " + "isUD: 1, " + "isS: 2, " + "isC: 400, " + "isCC: 410, " + "isGCC: 411, " + "isB: 500, " + "isBB: 510, " + "isGBB: 511, " + "isLeptonicB: 520, " + "isLeptonicB_C: 521, " + "isTAU: 600, " + "isPU: 999," + "isUndefined: 1000. " + "May be combined to form coarse labels for tagger training and flavour dependent attacks " + "using the loss surface."); } - + // ============================================================== Cpfs =================================================================== for (unsigned int p = 0; p < n_cpf_; p++) { - auto s = std::to_string(p); - - djTable->addColumn("DeepJet_Cpfcan_puppiw_" + s, - Cpfcan_puppiw_nCpf[p], - "charged candidate PUPPI weight of the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_VTX_ass_" + s, - Cpfcan_VTX_ass_nCpf[p], - "integer flag that indicates whether the track was used in the primary vertex fit for the " + s + ". cpf", + auto s = std::to_string(p); + + djTable->addColumn("DeepJet_Cpfcan_puppiw_" + s, + Cpfcan_puppiw_nCpf[p], + "charged candidate PUPPI weight of the " + s + ". cpf", 10); - djTable->addColumn("DeepJet_Cpfcan_drminsv_" + s, - Cpfcan_drminsv_nCpf[p], - "track pseudoangular distance from the closest secondary vertex of the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_ptrel_" + s, - Cpfcan_ptrel_nCpf[p], - "fraction of the jet momentum carried by the track for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_quality_" + s, - Cpfcan_quality_nCpf[p], - "integer flag which indicates the quality of the fitted track, based on number of detector hits used for the reconstruction as well as the overall chi2 of the charged track fit for the " + s + ". cpf", + djTable->addColumn( + "DeepJet_Cpfcan_VTX_ass_" + s, + Cpfcan_VTX_ass_nCpf[p], + "integer flag that indicates whether the track was used in the primary vertex fit for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_drminsv_" + s, + Cpfcan_drminsv_nCpf[p], + "track pseudoangular distance from the closest secondary vertex of the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_ptrel_" + s, + Cpfcan_ptrel_nCpf[p], + "fraction of the jet momentum carried by the track for the " + s + ". cpf", + 10); + djTable->addColumn( + "DeepJet_Cpfcan_quality_" + s, + Cpfcan_quality_nCpf[p], + "integer flag which indicates the quality of the fitted track, based on number of detector hits used for the " + "reconstruction as well as the overall chi2 of the charged track fit for the " + + s + ". cpf", + 10); + djTable->addColumn( + "DeepJet_Cpfcan_chi2_" + s, Cpfcan_chi2_nCpf[p], "chi2 of the charged track fit for the " + s + ". cpf", 10); + + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackDeltaR_" + s, + Cpfcan_BtagPf_trackDeltaR_nCpf[p], + "track pseudoangular distance from the jet axis for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackEtaRel_" + s, + Cpfcan_BtagPf_trackEtaRel_nCpf[p], + "track pseudorapidity, relative to the jet axis for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackJetDistVal_" + s, + Cpfcan_BtagPf_trackJetDistVal_nCpf[p], + "minimum track approach distance to jet axis for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackPPar_" + s, + Cpfcan_BtagPf_trackPPar_nCpf[p], + "dot product of the jet and track momentum for the " + s + ". cpf", + 10); + djTable->addColumn( + "DeepJet_Cpfcan_BtagPf_trackPParRatio_" + s, + Cpfcan_BtagPf_trackPParRatio_nCpf[p], + "dot product of the jet and track momentum divided by the magnitude of the jet momentum for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackPtRel_" + s, + Cpfcan_BtagPf_trackPtRel_nCpf[p], + "track transverse momentum, relative to the jet axis for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip2dSig_" + s, + Cpfcan_BtagPf_trackSip2dSig_nCpf[p], + "track 2D signed impact parameter significance for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip3dSig_" + s, + Cpfcan_BtagPf_trackSip3dSig_nCpf[p], + "track 3D signed impact parameter significance for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip2dVal_" + s, + Cpfcan_BtagPf_trackSip2dVal_nCpf[p], + "track 2D signed impact parameter for the " + s + ". cpf", + 10); + djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip3dVal_" + s, + Cpfcan_BtagPf_trackSip3dVal_nCpf[p], + "track 3D signed impact parameter for the " + s + ". cpf", 10); - djTable->addColumn("DeepJet_Cpfcan_chi2_" + s, - Cpfcan_chi2_nCpf[p], - "chi2 of the charged track fit for the " + s + ". cpf", - 10); - - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackDeltaR_" + s, - Cpfcan_BtagPf_trackDeltaR_nCpf[p], - "track pseudoangular distance from the jet axis for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackEtaRel_" + s, - Cpfcan_BtagPf_trackEtaRel_nCpf[p], - "track pseudorapidity, relative to the jet axis for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackJetDistVal_" + s, - Cpfcan_BtagPf_trackJetDistVal_nCpf[p], - "minimum track approach distance to jet axis for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackPPar_" + s, - Cpfcan_BtagPf_trackPPar_nCpf[p], - "dot product of the jet and track momentum for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackPParRatio_" + s, - Cpfcan_BtagPf_trackPParRatio_nCpf[p], - "dot product of the jet and track momentum divided by the magnitude of the jet momentum for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackPtRel_" + s, - Cpfcan_BtagPf_trackPtRel_nCpf[p], - "track transverse momentum, relative to the jet axis for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip2dSig_" + s, - Cpfcan_BtagPf_trackSip2dSig_nCpf[p], - "track 2D signed impact parameter significance for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip3dSig_" + s, - Cpfcan_BtagPf_trackSip3dSig_nCpf[p], - "track 3D signed impact parameter significance for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip2dVal_" + s, - Cpfcan_BtagPf_trackSip2dVal_nCpf[p], - "track 2D signed impact parameter for the " + s + ". cpf", - 10); - djTable->addColumn("DeepJet_Cpfcan_BtagPf_trackSip3dVal_" + s, - Cpfcan_BtagPf_trackSip3dVal_nCpf[p], - "track 3D signed impact parameter for the " + s + ". cpf", - 10); - } - + // ============================================================== Npfs =================================================================== for (unsigned int p = 0; p < n_npf_; p++) { - auto s = std::to_string(p); - - djTable->addColumn("DeepJet_Npfcan_puppiw_" + s, - Npfcan_puppiw_nNpf[p], - "neutral candidate PUPPI weight for the " + s + ". npf", - 10); - djTable->addColumn("DeepJet_Npfcan_deltaR_" + s, - Npfcan_deltaR_nNpf[p], - "pseudoangular distance between the neutral candidate and the jet axis for the " + s + ". npf", - 10); - djTable->addColumn("DeepJet_Npfcan_drminsv_" + s, - Npfcan_drminsv_nNpf[p], - "pseudoangular distance between the neutral candidate and the closest secondary vertex for the " + s + ". npf", - 10); - djTable->addColumn("DeepJet_Npfcan_HadFrac_" + s, - Npfcan_HadFrac_nNpf[p], - "fraction of the neutral candidate energy deposited in the hadronic calorimeter for the " + s + ". npf", - 10); - djTable->addColumn("DeepJet_Npfcan_ptrel_" + s, - Npfcan_ptrel_nNpf[p], - "fraction of the jet momentum carried by the neutral candidate for the " + s + ". npf", - 10); - djTable->addColumn("DeepJet_Npfcan_isGamma_" + s, - Npfcan_isGamma_nNpf[p], - "integer flag indicating whether the neutral candidate is a photon for the " + s + ". npf", + auto s = std::to_string(p); + + djTable->addColumn("DeepJet_Npfcan_puppiw_" + s, + Npfcan_puppiw_nNpf[p], + "neutral candidate PUPPI weight for the " + s + ". npf", 10); - /* + djTable->addColumn( + "DeepJet_Npfcan_deltaR_" + s, + Npfcan_deltaR_nNpf[p], + "pseudoangular distance between the neutral candidate and the jet axis for the " + s + ". npf", + 10); + djTable->addColumn( + "DeepJet_Npfcan_drminsv_" + s, + Npfcan_drminsv_nNpf[p], + "pseudoangular distance between the neutral candidate and the closest secondary vertex for the " + s + ". npf", + 10); + djTable->addColumn( + "DeepJet_Npfcan_HadFrac_" + s, + Npfcan_HadFrac_nNpf[p], + "fraction of the neutral candidate energy deposited in the hadronic calorimeter for the " + s + ". npf", + 10); + djTable->addColumn("DeepJet_Npfcan_ptrel_" + s, + Npfcan_ptrel_nNpf[p], + "fraction of the jet momentum carried by the neutral candidate for the " + s + ". npf", + 10); + djTable->addColumn("DeepJet_Npfcan_isGamma_" + s, + Npfcan_isGamma_nNpf[p], + "integer flag indicating whether the neutral candidate is a photon for the " + s + ". npf", + 10); + /* // only after dataformat updated as well djTable->addColumn("DeepJetExtra_Npfcan_etarel_" + s, Npfcan_etarel_nNpf[p], @@ -577,53 +574,36 @@ void DeepJetTableProducer::produce(edm::Event &iEvent, const edm::EventSetup "DeltaPhi(npf, jet) for the " + s + ". npf", 10); */ - } + } // ============================================================== SVs =================================================================== for (unsigned int p = 0; p < n_sv_; p++) { - auto s = std::to_string(p); - - djTable->addColumn("DeepJet_sv_mass_" + s, - sv_mass_nSV[p], - "SV mass of the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_pt_" + s, - sv_pt_nSV[p], - "SV pt of the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_ntracks_" + s, - sv_ntracks_nSV[p], - "Number of tracks asociated to the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_chi2_" + s, - sv_chi2_nSV[p], - "chi2 of the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_normchi2_" + s, - sv_normchi2_nSV[p], - "chi2/dof of the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_dxy_" + s, - sv_dxy_nSV[p], - "2D impact parameter (flight distance) value of the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_dxysig_" + s, - sv_dxysig_nSV[p], - "2D impact parameter (flight distance) significance of the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_d3d_" + s, - sv_d3d_nSV[p], - "3D impact parameter (flight distance) value of the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_d3dsig_" + s, - sv_d3dsig_nSV[p], - "3D impact parameter (flight distance) significance of the " + s + ". SV", - 10); - djTable->addColumn("DeepJet_sv_costhetasvpv_" + s, - sv_costhetasvpv_nSV[p], - "cosine of the angle between the " + s + ". SV flight direction and the direction of the " + s + ". SV momentum", - 10); - /* + auto s = std::to_string(p); + + djTable->addColumn("DeepJet_sv_mass_" + s, sv_mass_nSV[p], "SV mass of the " + s + ". SV", 10); + djTable->addColumn("DeepJet_sv_pt_" + s, sv_pt_nSV[p], "SV pt of the " + s + ". SV", 10); + djTable->addColumn( + "DeepJet_sv_ntracks_" + s, sv_ntracks_nSV[p], "Number of tracks asociated to the " + s + ". SV", 10); + djTable->addColumn("DeepJet_sv_chi2_" + s, sv_chi2_nSV[p], "chi2 of the " + s + ". SV", 10); + djTable->addColumn("DeepJet_sv_normchi2_" + s, sv_normchi2_nSV[p], "chi2/dof of the " + s + ". SV", 10); + djTable->addColumn( + "DeepJet_sv_dxy_" + s, sv_dxy_nSV[p], "2D impact parameter (flight distance) value of the " + s + ". SV", 10); + djTable->addColumn("DeepJet_sv_dxysig_" + s, + sv_dxysig_nSV[p], + "2D impact parameter (flight distance) significance of the " + s + ". SV", + 10); + djTable->addColumn( + "DeepJet_sv_d3d_" + s, sv_d3d_nSV[p], "3D impact parameter (flight distance) value of the " + s + ". SV", 10); + djTable->addColumn("DeepJet_sv_d3dsig_" + s, + sv_d3dsig_nSV[p], + "3D impact parameter (flight distance) significance of the " + s + ". SV", + 10); + djTable->addColumn("DeepJet_sv_costhetasvpv_" + s, + sv_costhetasvpv_nSV[p], + "cosine of the angle between the " + s + + ". SV flight direction and the direction of the " + s + ". SV momentum", + 10); + /* // only after dataformat updated as well djTable->addColumn("DeepJetExtra_sv_etarel_" + s, sv_etarel_nSV[p], @@ -634,31 +614,26 @@ void DeepJetTableProducer::produce(edm::Event &iEvent, const edm::EventSetup "DeltaPhi(sv, jet) for the " + s + ". SV", 10); */ - djTable->addColumn("DeepJet_sv_deltaR_" + s, - sv_deltaR_nSV[p], - "pseudoangular distance between jet axis and the " + s + ". SV direction", - 10); - djTable->addColumn("DeepJet_sv_enratio_" + s, - sv_enratio_nSV[p], - "ratio of the " + s + ". SV energy ratio to the jet energy", - 10); - + djTable->addColumn("DeepJet_sv_deltaR_" + s, + sv_deltaR_nSV[p], + "pseudoangular distance between jet axis and the " + s + ". SV direction", + 10); + djTable->addColumn( + "DeepJet_sv_enratio_" + s, sv_enratio_nSV[p], "ratio of the " + s + ". SV energy ratio to the jet energy", 10); } - - - iEvent.put(std::move(djTable), nameDeepJet_); - + + iEvent.put(std::move(djTable), nameDeepJet_); } -template< typename T> -void DeepJetTableProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { +template +void DeepJetTableProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { edm::ParameterSetDescription desc; desc.add("nameDeepJet", "Jet"); desc.add("idx_nameDeepJet", "djIdx"); desc.add("storeAK4Truth", false); desc.add("genparticles", edm::InputTag("prunedGenParticles")); desc.add("jets", edm::InputTag("slimmedJetsPuppi")); - desc.add("tagInfo_src", edm::InputTag("pfDeepFlavourTagInfosWithDeepInfo")); + desc.add("tagInfo_src", edm::InputTag("pfDeepFlavourTagInfosPuppiWithDeepInfo")); descriptions.addWithDefaultLabel(desc); } diff --git a/PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc b/PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc index 9874556078a67..4ec45ef3a21ed 100644 --- a/PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/JetConstituentTableProducer.cc @@ -30,7 +30,7 @@ using namespace btagbtvdeep; #include "CommonTools/Utils/interface/StringCutObjectSelector.h" #include "DataFormats/NanoAOD/interface/FlatTable.h" -template +template class JetConstituentTableProducer : public edm::stream::EDProducer<> { public: explicit JetConstituentTableProducer(const edm::ParameterSet &); @@ -65,13 +65,12 @@ class JetConstituentTableProducer : public edm::stream::EDProducer<> { edm::ESGetToken track_builder_token_; const reco::Vertex *pv_ = nullptr; - }; // // constructors and destructor // -template< typename T> +template JetConstituentTableProducer::JetConstituentTableProducer(const edm::ParameterSet &iConfig) : name_(iConfig.getParameter("name")), nameSV_(iConfig.getParameter("nameSV")), @@ -84,25 +83,27 @@ JetConstituentTableProducer::JetConstituentTableProducer(const edm::Parameter cand_token_(consumes(iConfig.getParameter("candidates"))), sv_token_(consumes(iConfig.getParameter("secondary_vertices"))), track_builder_token_( - esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))){ + esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))) { produces(name_); produces(nameSV_); produces>(); } -template< typename T> +template JetConstituentTableProducer::~JetConstituentTableProducer() {} -template< typename T> +template void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) { // elements in all these collections must have the same order! auto outCands = std::make_unique>(); - auto outSVs = std::make_unique> (); + auto outSVs = std::make_unique>(); std::vector jetIdx_pf, jetIdx_sv, pfcandIdx, svIdx; // PF Cands - std::vector btagEtaRel, btagPtRatio, btagPParRatio, btagSip3dVal, btagSip3dSig, btagJetDistVal, btagDecayLenVal, cand_pt, cand_dzFromPV, cand_dxyFromPV, cand_dzErrFromPV, cand_dxyErrFromPV; + std::vector btagEtaRel, btagPtRatio, btagPParRatio, btagSip3dVal, btagSip3dSig, btagJetDistVal, + btagDecayLenVal, cand_pt, cand_dzFromPV, cand_dxyFromPV, cand_dzErrFromPV, cand_dxyErrFromPV; // Secondary vertices - std::vector sv_mass, sv_pt, sv_ntracks, sv_chi2, sv_normchi2, sv_dxy, sv_dxysig, sv_d3d, sv_d3dsig, sv_costhetasvpv; + std::vector sv_mass, sv_pt, sv_ntracks, sv_chi2, sv_normchi2, sv_dxy, sv_dxysig, sv_d3d, sv_d3dsig, + sv_costhetasvpv; std::vector sv_ptrel, sv_phirel, sv_deltaR, sv_enratio; auto jets = iEvent.getHandle(jet_token_); @@ -110,7 +111,7 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even iEvent.getByToken(cand_token_, cands_); iEvent.getByToken(sv_token_, svs_); - if(readBtag_){ + if (readBtag_) { track_builder_ = iSetup.getHandle(track_builder_token_); } @@ -121,15 +122,16 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even VertexDistance3D vdist; pv_ = &vtxs_->at(0); - + ////////////////////// // Secondary Vertices std::vector jetSVs; - std::vector allSVs; + std::vector allSVs; for (const auto &sv : *svs_) { // Factor in cuts in NanoAOD for indexing - Measurement1D dl= vdist.distance(vtxs_->front(), VertexState(RecoVertex::convertPos(sv.position()),RecoVertex::convertError(sv.error()))); - if(dl.significance() > 3){ + Measurement1D dl = vdist.distance( + vtxs_->front(), VertexState(RecoVertex::convertPos(sv.position()), RecoVertex::convertError(sv.error()))); + if (dl.significance() > 3) { allSVs.push_back(&sv); } if (reco::deltaR2(sv, jet) < jet_radius_ * jet_radius_) { @@ -145,11 +147,11 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even for (const auto &sv : jetSVs) { // auto svPtrs = svs_->ptrs(); - auto svInNewList = std::find(allSVs.begin(), allSVs.end(), sv ); + auto svInNewList = std::find(allSVs.begin(), allSVs.end(), sv); if (svInNewList == allSVs.end()) { // continue; svIdx.push_back(-1); - } else{ + } else { svIdx.push_back(svInNewList - allSVs.begin()); } outSVs->push_back(sv); @@ -162,10 +164,10 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even sv_ntracks.push_back(sv->numberOfDaughters()); sv_chi2.push_back(sv->vertexChi2()); sv_normchi2.push_back(catch_infs_and_bound(sv->vertexChi2() / sv->vertexNdof(), 1000, -1000, 1000)); - const auto& dxy_meas = vertexDxy(*sv, *pv_); + const auto &dxy_meas = vertexDxy(*sv, *pv_); sv_dxy.push_back(dxy_meas.value()); sv_dxysig.push_back(catch_infs_and_bound(dxy_meas.value() / dxy_meas.error(), 0, -1, 800)); - const auto& d3d_meas = vertexD3d(*sv, *pv_); + const auto &d3d_meas = vertexD3d(*sv, *pv_); sv_d3d.push_back(d3d_meas.value()); sv_d3dsig.push_back(catch_infs_and_bound(d3d_meas.value() / d3d_meas.error(), 0, -1, 800)); sv_costhetasvpv.push_back(vertexDdotP(*sv, *pv_)); @@ -177,13 +179,13 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even } } - // PF Cands - std::vector const & daughters = jet.daughterPtrVector(); + // PF Cands + std::vector const &daughters = jet.daughterPtrVector(); for (const auto &cand : daughters) { auto candPtrs = cands_->ptrs(); - auto candInNewList = std::find( candPtrs.begin(), candPtrs.end(), cand ); - if ( candInNewList == candPtrs.end() ) { + auto candInNewList = std::find(candPtrs.begin(), candPtrs.end(), cand); + if (candInNewList == candPtrs.end()) { //std::cout << "Cannot find candidate : " << cand.id() << ", " << cand.key() << ", pt = " << cand->pt() << std::endl; continue; } @@ -191,9 +193,9 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even jetIdx_pf.push_back(i_jet); pfcandIdx.push_back(candInNewList - candPtrs.begin()); cand_pt.push_back(cand->pt()); - auto const *packedCand = dynamic_cast (cand.get()); + auto const *packedCand = dynamic_cast(cand.get()); if (packedCand && packedCand->hasTrackDetails()) { - const reco::Track* track_ptr = &(packedCand->pseudoTrack()); + const reco::Track *track_ptr = &(packedCand->pseudoTrack()); cand_dzFromPV.push_back(track_ptr->dz(pv_->position())); cand_dxyFromPV.push_back(track_ptr->dxy(pv_->position())); cand_dzErrFromPV.push_back(std::hypot(track_ptr->dzError(), pv_->zError())); @@ -206,10 +208,12 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even } if (readBtag_ && !vtxs_->empty()) { - if ( cand.isNull() ) continue; - auto const *packedCand = dynamic_cast (cand.get()); - if ( packedCand == nullptr ) continue; - if ( packedCand && packedCand->hasTrackDetails()){ + if (cand.isNull()) + continue; + auto const *packedCand = dynamic_cast(cand.get()); + if (packedCand == nullptr) + continue; + if (packedCand && packedCand->hasTrackDetails()) { btagbtvdeep::TrackInfoBuilder trkinfo(track_builder_); trkinfo.buildTrackInfo(&(*packedCand), jet_dir, jet_ref_track_dir, vtxs_->at(0)); btagEtaRel.push_back(trkinfo.getTrackEtaRel()); @@ -219,23 +223,24 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even btagSip3dSig.push_back(trkinfo.getTrackSip3dSig()); btagJetDistVal.push_back(trkinfo.getTrackJetDistVal()); // decay length - const reco::Track* track_ptr = packedCand->bestTrack(); + const reco::Track *track_ptr = packedCand->bestTrack(); reco::TransientTrack transient_track = track_builder_->build(track_ptr); double decayLength = -1; - TrajectoryStateOnSurface closest = IPTools::closestApproachToJet(transient_track.impactPointState(), *pv_, jet_ref_track_dir, transient_track.field()); + TrajectoryStateOnSurface closest = IPTools::closestApproachToJet( + transient_track.impactPointState(), *pv_, jet_ref_track_dir, transient_track.field()); if (closest.isValid()) - decayLength = (closest.globalPosition() - RecoVertex::convertPos(pv_->position())).mag(); + decayLength = (closest.globalPosition() - RecoVertex::convertPos(pv_->position())).mag(); else decayLength = -1; btagDecayLenVal.push_back(decayLength); } else { - btagEtaRel.push_back(0); - btagPtRatio.push_back(0); - btagPParRatio.push_back(0); - btagSip3dVal.push_back(0); - btagSip3dSig.push_back(0); - btagJetDistVal.push_back(0); - btagDecayLenVal.push_back(0); + btagEtaRel.push_back(0); + btagPtRatio.push_back(0); + btagPParRatio.push_back(0); + btagSip3dVal.push_back(0); + btagSip3dSig.push_back(0); + btagJetDistVal.push_back(0); + btagDecayLenVal.push_back(0); } } } // end jet loop @@ -261,7 +266,7 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even } iEvent.put(std::move(candTable), name_); - // SV table + // SV table auto svTable = std::make_unique(outSVs->size(), nameSV_, false); // We fill from here only stuff that cannot be created with the SimpleFlatTnameableProducer svTable->addColumn("jetIdx", jetIdx_sv, "Index of the parent jet"); @@ -288,7 +293,7 @@ void JetConstituentTableProducer::produce(edm::Event &iEvent, const edm::Even iEvent.put(std::move(outCands)); } -template< typename T> +template void JetConstituentTableProducer::fillDescriptions(edm::ConfigurationDescriptions &descriptions) { edm::ParameterSetDescription desc; desc.add("name", "JetPFCands"); diff --git a/PhysicsTools/NanoAOD/python/custom_btv_cff.py b/PhysicsTools/NanoAOD/python/custom_btv_cff.py index 0b8f89cc97c76..edba473d1089e 100644 --- a/PhysicsTools/NanoAOD/python/custom_btv_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_btv_cff.py @@ -42,10 +42,6 @@ def update_jets_AK4(process): 'pfJetBProbabilityBJetTags', 'pfNegativeOnlyJetProbabilityBJetTags', 'pfNegativeOnlyJetBProbabilityBJetTags', - 'pfDeepCSVJetTags:probb', - 'pfDeepCSVJetTags:probc', - 'pfDeepCSVJetTags:probbb', - 'pfDeepCSVJetTags:probudsg', 'pfDeepFlavourJetTags:probb', 'pfDeepFlavourJetTags:probbb', 'pfDeepFlavourJetTags:problepb', @@ -69,17 +65,16 @@ def update_jets_AK4(process): ['L1FastJet', 'L2Relative', 'L3Absolute', 'L2L3Residual']), 'None'), btagDiscriminators=_btagDiscriminators, - postfix='WithDeepInfo', + postfix='PuppiWithDeepInfo', ) process.load("Configuration.StandardSequences.MagneticField_cff") - process.jetPuppiCorrFactorsNano.src = "selectedUpdatedPatJetsWithDeepInfo" - process.updatedJetsPuppi.jetSource = "selectedUpdatedPatJetsWithDeepInfo" - - process.updatedPatJetsTransientCorrectedWithDeepInfo.tagInfoSources.append(cms.InputTag("pfDeepCSVTagInfosWithDeepInfo")) - process.updatedPatJetsTransientCorrectedWithDeepInfo.tagInfoSources.append(cms.InputTag("pfDeepFlavourTagInfosWithDeepInfo")) + process.jetPuppiCorrFactorsNano.src = "selectedUpdatedPatJetsPuppiWithDeepInfo" + process.updatedJetsPuppi.jetSource = "selectedUpdatedPatJetsPuppiWithDeepInfo" - process.updatedPatJetsTransientCorrectedWithDeepInfo.addTagInfos = cms.bool(True) + process.updatedPatJetsTransientCorrectedPuppiWithDeepInfo.tagInfoSources.append(cms.InputTag("pfDeepFlavourTagInfosPuppiWithDeepInfo")) + process.updatedPatJetsTransientCorrectedPuppiWithDeepInfo.addTagInfos = cms.bool(True) + return process @@ -89,14 +84,6 @@ def update_jets_AK8(process): # in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/nano_cff.py # Care needs to be taken to make sure no discriminators from stock Nano are excluded -> would results in unfilled vars _btagDiscriminators = [ - 'pfJetProbabilityBJetTags', - 'pfDeepCSVJetTags:probb', - 'pfDeepCSVJetTags:probc', - 'pfDeepCSVJetTags:probbb', - 'pfDeepCSVJetTags:probudsg', - 'pfMassIndependentDeepDoubleBvLJetTags:probHbb', - 'pfMassIndependentDeepDoubleCvLJetTags:probHcc', - 'pfMassIndependentDeepDoubleCvBJetTags:probHcc', 'pfMassIndependentDeepDoubleBvLV2JetTags:probHbb', 'pfMassIndependentDeepDoubleCvLV2JetTags:probHcc', 'pfMassIndependentDeepDoubleCvBV2JetTags:probHcc', @@ -462,44 +449,6 @@ def get_ParticleTransformerAK4_outputs(): return ParticleTransformerAK4OutputVars -def get_CommVars(): - # store all nodes and negative tagger for BTV SFs - CommonVars = cms.PSet( - Proba=Var("bDiscriminator('pfJetProbabilityBJetTags')", - float, - doc="Jet Probability (Usage:BTV)", - precision=10), - ProbaN=Var("bDiscriminator('pfNegativeOnlyJetProbabilityBJetTags')", - float, - doc="Negative-only Jet Probability (Usage:BTV)", - precision=10), - Bprob=Var("bDiscriminator('pfJetBProbabilityBJetTags')", - float, - doc="Jet B Probability (Usage:BTV)", - precision=10), - BprobN=Var("bDiscriminator('pfNegativeOnlyJetBProbabilityBJetTags')", - float, - doc="Negative-only Jet B Probability (Usage:BTV)", - precision=10), - btagDeepB_b=Var("bDiscriminator('pfDeepCSVJetTags:probb')", - float, - doc="DeepCSV b tag discriminator", - precision=10), - btagDeepB_bb=Var("bDiscriminator('pfDeepCSVJetTags:probbb')", - float, - doc="DeepCSV bb tag discriminator", - precision=10), - btagDeepC=Var("bDiscriminator('pfDeepCSVJetTags:probc')", - float, - doc="DeepCSV c btag discriminator", - precision=10), - btagDeepL=Var("bDiscriminator('pfDeepCSVJetTags:probudsg')", - float, - doc="DeepCSV light btag discriminator", - precision=10), - ) - return CommonVars - def add_BTV(process, runOnMC=False, addAK4=False, addAK8=False): if addAK4: process = update_jets_AK4(process) @@ -527,22 +476,6 @@ def add_BTV(process, runOnMC=False, addAK4=False, addAK8=False): float, doc="Negative-only Jet B Probability (Usage:BTV)", precision=10), - btagDeepB_b=Var("bDiscriminator('pfDeepCSVJetTags:probb')", - float, - doc="DeepCSV b tag discriminator", - precision=10), - btagDeepB_bb=Var("bDiscriminator('pfDeepCSVJetTags:probbb')", - float, - doc="DeepCSV bb tag discriminator", - precision=10), - btagDeepC=Var("bDiscriminator('pfDeepCSVJetTags:probc')", - float, - doc="DeepCSV c btag discriminator", - precision=10), - btagDeepL=Var("bDiscriminator('pfDeepCSVJetTags:probudsg')", - float, - doc="DeepCSV light btag discriminator", - precision=10), ) # decouple these from CommonVars, not relevant for data @@ -650,7 +583,6 @@ def add_BTV(process, runOnMC=False, addAK4=False, addAK8=False): # From https://github.com/cms-jet/PFNano/blob/13_0_7_from124MiniAOD/python/addPFCands_cff.py def addPFCands(process, runOnMC=False, allPF = False, addAK4=False, addAK8=False): - print(allPF,addAK4,addAK8) process.customizedPFCandsTask = cms.Task( ) process.schedule.associate(process.customizedPFCandsTask) @@ -802,8 +734,8 @@ def addPFCands(process, runOnMC=False, allPF = False, addAK4=False, addAK8=False # nanoAOD_addbtagAK4_switch, nanoAOD_addbtagAK8_switch True, nanoAOD_allPF_switch False nanoAOD_allPF_switch = False # Add all PF candidates, use for training -nanoAOD_addbtagAK4_switch = True # AAK -nanoAOD_addbtagAK8_switch = True +nanoAOD_addbtagAK4_switch = True # AK4 SFs vars +nanoAOD_addbtagAK8_switch = False # AK8 SFs vars def PrepBTVCustomNanoAOD_MC(process): addPFCands(process, True, nanoAOD_allPF_switch,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) diff --git a/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc b/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc index e79d4fc54e4b9..03feb93b0b1e7 100644 --- a/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc +++ b/RecoBTag/FeatureTools/plugins/ParticleNetFeatureEvaluator.cc @@ -467,7 +467,6 @@ void ParticleNetFeatureEvaluator::fillParticleFeatures(DeepBoostedJetFeatures &f } float ip_sign = flip_ip_sign_ ? -1.f : 1.f; - fts.fill("jet_pfcand_pt_log", std::isnan(std::log(candP4.pt())) ? 0 : std::log(candP4.pt())); fts.fill("jet_pfcand_energy_log", std::isnan(std::log(candP4.energy())) ? 0 : std::log(candP4.energy())); fts.fill("jet_pfcand_eta", candP4.eta()); @@ -700,7 +699,7 @@ void ParticleNetFeatureEvaluator::fillSVFeatures(DeepBoostedJetFeatures &fts, co fts.reserve(name, jetSVs.size()); GlobalVector jet_global_vec(jet.px(), jet.py(), jet.pz()); - + float ip_sign = flip_ip_sign_ ? -1.f : 1.f; for (const auto *sv : jetSVs) { diff --git a/RecoBTag/ImpactParameter/interface/TemplatedTrackCountingComputer.h b/RecoBTag/ImpactParameter/interface/TemplatedTrackCountingComputer.h index 4973868927ddb..58a5b79e6c079 100644 --- a/RecoBTag/ImpactParameter/interface/TemplatedTrackCountingComputer.h +++ b/RecoBTag/ImpactParameter/interface/TemplatedTrackCountingComputer.h @@ -97,9 +97,9 @@ class TemplatedTrackCountingComputer : public JetTagComputer { if (tkip.variableJTA(varJTApars)[i]) significances.insert(significance); } else // no using variable JTA, use the default method - if (m_deltaR <= 0 || - ROOT::Math::VectorUtil::DeltaR((*tkip.jet()).p4().Vect(), (*tracks[i]).momentum()) < m_deltaR) - significances.insert(significance); + if (m_deltaR <= 0 || + ROOT::Math::VectorUtil::DeltaR((*tkip.jet()).p4().Vect(), (*tracks[i]).momentum()) < m_deltaR) + significances.insert(significance); } } From 433063322d9c6e19c357e44e01b53a020d9ed39b Mon Sep 17 00:00:00 2001 From: Ming-Yan Date: Thu, 29 Feb 2024 14:11:28 +0100 Subject: [PATCH 5/9] feat: seperate sequences --- .gitignore | 4 - .../plugins/BTVMCFlavourTableProducer.cc | 274 ++++++++++++++++++ .../NanoAOD/plugins/DeepJetTableProducer.cc | 252 +--------------- PhysicsTools/NanoAOD/python/autoNANO.py | 1 + PhysicsTools/NanoAOD/python/btvMC_cff.py | 170 +++++++++++ PhysicsTools/NanoAOD/python/custom_btv_cff.py | 248 ++++++++-------- PhysicsTools/NanoAOD/python/nano_cff.py | 1 + .../TemplatedTrackCountingComputer.h | 6 +- 8 files changed, 579 insertions(+), 377 deletions(-) create mode 100644 PhysicsTools/NanoAOD/plugins/BTVMCFlavourTableProducer.cc create mode 100644 PhysicsTools/NanoAOD/python/btvMC_cff.py diff --git a/.gitignore b/.gitignore index 8925c98ef58da..18f4f414b9425 100644 --- a/.gitignore +++ b/.gitignore @@ -11,10 +11,6 @@ __init__.py *.orig - - - - # ignore files under the top level $CMSSW_BASE/src directory, but not its subdirectories /* !/*/ diff --git a/PhysicsTools/NanoAOD/plugins/BTVMCFlavourTableProducer.cc b/PhysicsTools/NanoAOD/plugins/BTVMCFlavourTableProducer.cc new file mode 100644 index 0000000000000..a5f7c93ef01f7 --- /dev/null +++ b/PhysicsTools/NanoAOD/plugins/BTVMCFlavourTableProducer.cc @@ -0,0 +1,274 @@ +// system include files +#include + +// user include files +#include "FWCore/Framework/interface/Frameworkfwd.h" +#include "FWCore/Framework/interface/stream/EDProducer.h" + +#include "FWCore/Framework/interface/Event.h" + +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h" +#include "FWCore/ParameterSet/interface/ParameterSetDescription.h" + +#include "DataFormats/PatCandidates/interface/Jet.h" +#include "DataFormats/HepMCCandidate/interface/GenParticle.h" +#include "PhysicsTools/NanoAOD/interface/BTV_flavor.h" +#include "DataFormats/Math/interface/deltaR.h" + +#include "DataFormats/NanoAOD/interface/FlatTable.h" + +#include "CommonTools/Utils/interface/StringCutObjectSelector.h" +#include "CommonTools/Utils/interface/StringObjectFunction.h" + +class BTVMCFlavourTableProducer : public edm::stream::EDProducer<> { +public: + explicit BTVMCFlavourTableProducer(const edm::ParameterSet& iConfig) + : name_(iConfig.getParameter("name")), + src_(consumes >(iConfig.getParameter("src"))), + genParticlesToken_(consumes(iConfig.getParameter("genparticles"))) { + produces(); + } + + ~BTVMCFlavourTableProducer() override{}; + int jet_flavour(const pat::Jet& jet, + const std::vector& gToBB, + const std::vector& gToCC, + const std::vector& neutrinosLepB, + const std::vector& neutrinosLepB_C, + const std::vector& alltaus, + bool usePhysForLightAndUndefined) { + int hflav = abs(jet.hadronFlavour()); + int pflav = abs(jet.partonFlavour()); + int physflav = 0; + if (!(jet.genJet())) { + if (pflav == 0) + return 999; + else + return 1000; + } + if (jet.genParton()) + physflav = abs(jet.genParton()->pdgId()); + std::size_t nbs = jet.jetFlavourInfo().getbHadrons().size(); + std::size_t ncs = jet.jetFlavourInfo().getcHadrons().size(); + + unsigned int nbFromGSP(0); + for (const reco::GenParticle& p : gToBB) { + double dr2(reco::deltaR2(jet, p)); + if (dr2 < jetR_ * jetR_) + ++nbFromGSP; + } + + unsigned int ncFromGSP(0); + for (const reco::GenParticle& p : gToCC) { + double dr2(reco::deltaR2(jet, p)); + if (dr2 < jetR_ * jetR_) + ++ncFromGSP; + } + + //std::cout << " jet pt = " << jet.pt() << " hfl = " << hflav << " pfl = " << pflav << " genpart = " << physflav + // << " nbFromGSP = " << nbFromGSP << " ncFromGSP = " << ncFromGSP + // << " nBhadrons " << nbs << " nCHadrons " << ncs << std::endl; + if (hflav == 5) { //B jet + if (nbs > 1) { + if (nbFromGSP > 0) + return 511; + else + return 510; + } else if (nbs == 1) { + for (std::vector::const_iterator it = neutrinosLepB.begin(); it != neutrinosLepB.end(); + ++it) { + if (reco::deltaR2(it->eta(), it->phi(), jet.eta(), jet.phi()) < 0.4 * 0.4) { + return 520; + } + } + for (std::vector::const_iterator it = neutrinosLepB_C.begin(); it != neutrinosLepB_C.end(); + ++it) { + if (reco::deltaR2(it->eta(), it->phi(), jet.eta(), jet.phi()) < 0.4 * 0.4) { + return 521; + } + } + return 500; + } else { + if (usePhysForLightAndUndefined) { + if (physflav == 21) + return 0; + else if (physflav == 3) + return 2; + else if (physflav == 2 || physflav == 1) + return 1; + else + return 1000; + } else + return 1000; + } + } else if (hflav == 4) { //C jet + if (ncs > 1) { + if (ncFromGSP > 0) + return 411; + else + return 410; + } else + return 400; + } else { //not a heavy jet + if (!alltaus.empty()) { //check for tau in a simplistic way + bool ishadrtaucontained = true; + for (const auto& p : alltaus) { + size_t ndau = p.numberOfDaughters(); + for (size_t i = 0; i < ndau; i++) { + const reco::Candidate* dau = p.daughter(i); + int daupid = std::abs(dau->pdgId()); + if (daupid == 13 || daupid == 11) { + ishadrtaucontained = false; + break; + } + if (daupid != 12 && daupid != 14 && daupid != 16 && reco::deltaR2(*dau, jet) > jetR_ * jetR_) { + ishadrtaucontained = false; + break; + } + } + } + if (ishadrtaucontained) + return 600; + } + if (std::abs(pflav) == 4 || std::abs(pflav) == 5 || nbs || ncs) { + if (usePhysForLightAndUndefined) { + if (physflav == 21) + return 0; + else if (physflav == 3) + return 2; + else if (physflav == 2 || physflav == 1) + return 1; + else + return 1000; + } else + return 1000; + } else if (usePhysForLightAndUndefined) { + if (physflav == 21) + return 0; + else if (physflav == 3) + return 2; + else if (physflav == 2 || physflav == 1) + return 1; + else + return 1000; + } else { + if (pflav == 21) + return 0; + else if (pflav == 3) + return 2; + else if (pflav == 2 || pflav == 1) + return 1; + else + return 1000; + } + } + } + + static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) { + edm::ParameterSetDescription desc; + desc.add("src")->setComment("input Jet collection"); + desc.add("genparticles")->setComment("input genparticles info collection"); + desc.add("name")->setComment("name of the genJet FlatTable we are extending with flavour information"); + descriptions.add("btvMCTable", desc); + } + +private: + void produce(edm::Event&, edm::EventSetup const&) override; + + std::string name_; + + edm::EDGetTokenT > src_; + constexpr static double jetR_ = 0.4; + + constexpr static bool usePhysForLightAndUndefined = false; + edm::EDGetTokenT genParticlesToken_; +}; + +// ------------ method called to produce the data ------------ +void BTVMCFlavourTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) { + auto jets = iEvent.getHandle(src_); + // const auto& jetFlavourInfosProd = iEvent.get(genParticlesToken_); + edm::Handle genParticlesHandle; + iEvent.getByToken(genParticlesToken_, genParticlesHandle); + std::vector neutrinosLepB; + std::vector neutrinosLepB_C; + + std::vector gToBB; + std::vector gToCC; + std::vector alltaus; + + unsigned int nJets = jets->size(); + + std::vector jet_FlavSplit(nJets); + for (const reco::Candidate& genC : *genParticlesHandle) { + const reco::GenParticle& gen = static_cast(genC); + if (abs(gen.pdgId()) == 12 || abs(gen.pdgId()) == 14 || abs(gen.pdgId()) == 16) { + const reco::GenParticle* mother = static_cast(gen.mother()); + if (mother != nullptr) { + if ((abs(mother->pdgId()) > 500 && abs(mother->pdgId()) < 600) || + (abs(mother->pdgId()) > 5000 && abs(mother->pdgId()) < 6000)) { + neutrinosLepB.emplace_back(gen); + } + if ((abs(mother->pdgId()) > 400 && abs(mother->pdgId()) < 500) || + (abs(mother->pdgId()) > 4000 && abs(mother->pdgId()) < 5000)) { + neutrinosLepB_C.emplace_back(gen); + } + } else { + std::cout << "No mother" << std::endl; + } + } + + int id(std::abs(gen.pdgId())); + int status(gen.status()); + + if (id == 21 && status >= 21 && status <= 59) { //// Pythia8 hard scatter, ISR, or FSR + if (gen.numberOfDaughters() == 2) { + const reco::Candidate* d0 = gen.daughter(0); + const reco::Candidate* d1 = gen.daughter(1); + if (std::abs(d0->pdgId()) == 5 && std::abs(d1->pdgId()) == 5 && d0->pdgId() * d1->pdgId() < 0 && + reco::deltaR2(*d0, *d1) < jetR_ * jetR_) + gToBB.push_back(gen); + if (std::abs(d0->pdgId()) == 4 && std::abs(d1->pdgId()) == 4 && d0->pdgId() * d1->pdgId() < 0 && + reco::deltaR2(*d0, *d1) < jetR_ * jetR_) + gToCC.push_back(gen); + } + } + + if (id == 15 && false) { + alltaus.push_back(gen); + } + } + for (unsigned i_jet = 0; i_jet < nJets; ++i_jet) { + // from DeepNTuples + const auto& jet = jets->at(i_jet); + + jet_FlavSplit[i_jet] = + jet_flavour(jet, gToBB, gToCC, neutrinosLepB, neutrinosLepB_C, alltaus, usePhysForLightAndUndefined); + } + auto newtab = std::make_unique(nJets, name_, false, true); + newtab->addColumn("FlavSplit", + jet_FlavSplit, + "Flavour of the jet, numerical codes: " + "isG: 0, " + "isUD: 1, " + "isS: 2, " + "isC: 400, " + "isCC: 410, " + "isGCC: 411, " + "isB: 500, " + "isBB: 510, " + "isGBB: 511, " + "isLeptonicB: 520, " + "isLeptonicB_C: 521, " + "isTAU: 600, " + "isPU: 999," + "isUndefined: 1000. " + "May be combined to form coarse labels for tagger training and flavour dependent attacks " + "using the loss surface."); + iEvent.put(std::move(newtab)); +} + +#include "FWCore/Framework/interface/MakerMacros.h" +//define this as a plug-in +DEFINE_FWK_MODULE(BTVMCFlavourTableProducer); diff --git a/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc b/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc index e477f6690f1b9..a81469218288e 100644 --- a/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc @@ -24,7 +24,6 @@ using namespace btagbtvdeep; // To store the gen info to get the truth flavour of the jet #include "DataFormats/PatCandidates/interface/Jet.h" -#include "DataFormats/HepMCCandidate/interface/GenParticle.h" #include "PhysicsTools/NanoAOD/interface/BTV_flavor.h" @@ -36,160 +35,20 @@ class DeepJetTableProducer : public edm::stream::EDProducer<> { static void fillDescriptions(edm::ConfigurationDescriptions& descriptions); - int jet_flavour(const pat::Jet& jet, - const std::vector& gToBB, - const std::vector& gToCC, - const std::vector& neutrinosLepB, - const std::vector& neutrinosLepB_C, - const std::vector& alltaus, - bool usePhysForLightAndUndefined) { - int hflav = abs(jet.hadronFlavour()); - int pflav = abs(jet.partonFlavour()); - int physflav = 0; - if (!(jet.genJet())) { - if (pflav == 0) - return 999; - else - return 1000; - } - if (jet.genParton()) - physflav = abs(jet.genParton()->pdgId()); - std::size_t nbs = jet.jetFlavourInfo().getbHadrons().size(); - std::size_t ncs = jet.jetFlavourInfo().getcHadrons().size(); - - unsigned int nbFromGSP(0); - for (const reco::GenParticle& p : gToBB) { - double dr2(reco::deltaR2(jet, p)); - if (dr2 < jetR_ * jetR_) - ++nbFromGSP; - } - - unsigned int ncFromGSP(0); - for (const reco::GenParticle& p : gToCC) { - double dr2(reco::deltaR2(jet, p)); - if (dr2 < jetR_ * jetR_) - ++ncFromGSP; - } - - //std::cout << " jet pt = " << jet.pt() << " hfl = " << hflav << " pfl = " << pflav << " genpart = " << physflav - // << " nbFromGSP = " << nbFromGSP << " ncFromGSP = " << ncFromGSP - // << " nBhadrons " << nbs << " nCHadrons " << ncs << std::endl; - if (hflav == 5) { //B jet - if (nbs > 1) { - if (nbFromGSP > 0) - return 511; - else - return 510; - } else if (nbs == 1) { - for (std::vector::const_iterator it = neutrinosLepB.begin(); it != neutrinosLepB.end(); - ++it) { - if (reco::deltaR2(it->eta(), it->phi(), jet.eta(), jet.phi()) < 0.4 * 0.4) { - return 520; - } - } - for (std::vector::const_iterator it = neutrinosLepB_C.begin(); it != neutrinosLepB_C.end(); - ++it) { - if (reco::deltaR2(it->eta(), it->phi(), jet.eta(), jet.phi()) < 0.4 * 0.4) { - return 521; - } - } - return 500; - } else { - if (usePhysForLightAndUndefined) { - if (physflav == 21) - return 0; - else if (physflav == 3) - return 2; - else if (physflav == 2 || physflav == 1) - return 1; - else - return 1000; - } else - return 1000; - } - } else if (hflav == 4) { //C jet - if (ncs > 1) { - if (ncFromGSP > 0) - return 411; - else - return 410; - } else - return 400; - } else { //not a heavy jet - if (!alltaus.empty()) { //check for tau in a simplistic way - bool ishadrtaucontained = true; - for (const auto& p : alltaus) { - size_t ndau = p.numberOfDaughters(); - for (size_t i = 0; i < ndau; i++) { - const reco::Candidate* dau = p.daughter(i); - int daupid = std::abs(dau->pdgId()); - if (daupid == 13 || daupid == 11) { - ishadrtaucontained = false; - break; - } - if (daupid != 12 && daupid != 14 && daupid != 16 && reco::deltaR2(*dau, jet) > jetR_ * jetR_) { - ishadrtaucontained = false; - break; - } - } - } - if (ishadrtaucontained) - return 600; - } - if (std::abs(pflav) == 4 || std::abs(pflav) == 5 || nbs || ncs) { - if (usePhysForLightAndUndefined) { - if (physflav == 21) - return 0; - else if (physflav == 3) - return 2; - else if (physflav == 2 || physflav == 1) - return 1; - else - return 1000; - } else - return 1000; - } else if (usePhysForLightAndUndefined) { - if (physflav == 21) - return 0; - else if (physflav == 3) - return 2; - else if (physflav == 2 || physflav == 1) - return 1; - else - return 1000; - } else { - if (pflav == 21) - return 0; - else if (pflav == 3) - return 2; - else if (pflav == 2 || pflav == 1) - return 1; - else - return 1000; - } - } - } - private: void produce(edm::Event&, const edm::EventSetup&) override; const std::string nameDeepJet_; const std::string idx_nameDeepJet_; - const bool storeAK4Truth_; - - const edm::EDGetTokenT genParticlesToken_; + const unsigned int n_cpf_ = 25; + const unsigned int n_npf_ = 25; + const unsigned int n_sv_ = 12; edm::EDGetTokenT> jet_token_; typedef std::vector TagInfoCollection; const edm::EDGetTokenT tag_info_src_; - constexpr static unsigned n_cpf_ = 3; - constexpr static unsigned n_npf_ = 3; - constexpr static unsigned n_sv_ = 4; // 5 - - constexpr static double jetR_ = 0.4; - constexpr static bool usePhysForLightAndUndefined = false; }; @@ -200,8 +59,9 @@ template DeepJetTableProducer::DeepJetTableProducer(const edm::ParameterSet& iConfig) : nameDeepJet_(iConfig.getParameter("nameDeepJet")), idx_nameDeepJet_(iConfig.getParameter("idx_nameDeepJet")), - storeAK4Truth_(iConfig.getParameter("storeAK4Truth")), - genParticlesToken_(consumes(iConfig.getParameter("genparticles"))), + n_cpf_(iConfig.getParameter("n_cpf")), + n_npf_(iConfig.getParameter("n_npf")), + n_sv_(iConfig.getParameter("n_sv")), jet_token_(consumes>(iConfig.getParameter("jets"))), tag_info_src_(consumes(iConfig.getParameter("tagInfo_src"))) { produces(nameDeepJet_); @@ -217,21 +77,11 @@ void DeepJetTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& // only necessary to explicitly check correct matching of jets // std::vector jetIdx_dj; - edm::Handle genParticlesHandle; - iEvent.getByToken(genParticlesToken_, genParticlesHandle); - auto jets = iEvent.getHandle(jet_token_); edm::Handle tag_infos; iEvent.getByToken(tag_info_src_, tag_infos); - std::vector neutrinosLepB; - std::vector neutrinosLepB_C; - - std::vector gToBB; - std::vector gToCC; - std::vector alltaus; - unsigned nJets = jets->size(); std::vector jet_N_CPFCands(nJets); @@ -239,8 +89,6 @@ void DeepJetTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& std::vector jet_N_PVs(nJets); std::vector jet_N_SVs(nJets); - std::vector jet_FlavSplit(nJets); - // should default to 0 if less than nCpf cpf with information std::vector> Cpfcan_BtagPf_trackEtaRel_nCpf(n_cpf_, std::vector(nJets)); std::vector> Cpfcan_BtagPf_trackPtRel_nCpf(n_cpf_, std::vector(nJets)); @@ -291,70 +139,14 @@ void DeepJetTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& std::vector> sv_deltaR_nSV(n_sv_, std::vector(nJets)); std::vector> sv_enratio_nSV(n_sv_, std::vector(nJets)); - if (storeAK4Truth_) { - neutrinosLepB.clear(); - neutrinosLepB_C.clear(); - gToBB.clear(); - gToCC.clear(); - alltaus.clear(); - - for (const reco::Candidate& genC : *genParticlesHandle) { - const reco::GenParticle& gen = static_cast(genC); - if (abs(gen.pdgId()) == 12 || abs(gen.pdgId()) == 14 || abs(gen.pdgId()) == 16) { - const reco::GenParticle* mother = static_cast(gen.mother()); - if (mother != nullptr) { - if ((abs(mother->pdgId()) > 500 && abs(mother->pdgId()) < 600) || - (abs(mother->pdgId()) > 5000 && abs(mother->pdgId()) < 6000)) { - neutrinosLepB.emplace_back(gen); - } - if ((abs(mother->pdgId()) > 400 && abs(mother->pdgId()) < 500) || - (abs(mother->pdgId()) > 4000 && abs(mother->pdgId()) < 5000)) { - neutrinosLepB_C.emplace_back(gen); - } - } else { - std::cout << "No mother" << std::endl; - } - } - - int id(std::abs(gen.pdgId())); - int status(gen.status()); - - if (id == 21 && status >= 21 && status <= 59) { //// Pythia8 hard scatter, ISR, or FSR - if (gen.numberOfDaughters() == 2) { - const reco::Candidate* d0 = gen.daughter(0); - const reco::Candidate* d1 = gen.daughter(1); - if (std::abs(d0->pdgId()) == 5 && std::abs(d1->pdgId()) == 5 && d0->pdgId() * d1->pdgId() < 0 && - reco::deltaR2(*d0, *d1) < jetR_ * jetR_) - gToBB.push_back(gen); - if (std::abs(d0->pdgId()) == 4 && std::abs(d1->pdgId()) == 4 && d0->pdgId() * d1->pdgId() < 0 && - reco::deltaR2(*d0, *d1) < jetR_ * jetR_) - gToCC.push_back(gen); - } - } - - if (id == 15 && false) { - alltaus.push_back(gen); - } - } - } - if (!tag_infos->empty()) { for (unsigned i_jet = 0; i_jet < nJets; ++i_jet) { - if (storeAK4Truth_) { - // from DeepNTuples - const auto& jet = jets->at(i_jet); - - jet_FlavSplit[i_jet] = - jet_flavour(jet, gToBB, gToCC, neutrinosLepB, neutrinosLepB_C, alltaus, usePhysForLightAndUndefined); - } - // jet loop reads tag info instead of constituent info const auto& taginfo = (*tag_infos)[i_jet]; const auto& features = taginfo.features(); // jet.pt and jet.eta as well as other jet variables (ShallowTagInfo) already included (via DeepCSV) - // number of elements in different collections jet_N_CPFCands[i_jet] = features.c_pf_features.size(); jet_N_NPFCands[i_jet] = features.n_pf_features.size(); @@ -434,30 +226,6 @@ void DeepJetTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& djTable->addColumn("DeepJet_nsv", jet_N_SVs, "Number of secondary vertices in the jet"); djTable->addColumn("DeepJet_npv", jet_N_PVs, "Number of primary vertices"); - //if (true) { - if (storeAK4Truth_) { - //std::cout << "Start filling table with truth info" << std::endl; - djTable->addColumn("FlavSplit", - jet_FlavSplit, - "Flavour of the jet, numerical codes: " - "isG: 0, " - "isUD: 1, " - "isS: 2, " - "isC: 400, " - "isCC: 410, " - "isGCC: 411, " - "isB: 500, " - "isBB: 510, " - "isGBB: 511, " - "isLeptonicB: 520, " - "isLeptonicB_C: 521, " - "isTAU: 600, " - "isPU: 999," - "isUndefined: 1000. " - "May be combined to form coarse labels for tagger training and flavour dependent attacks " - "using the loss surface."); - } - // ============================================================== Cpfs =================================================================== for (unsigned int p = 0; p < n_cpf_; p++) { auto s = std::to_string(p); @@ -630,15 +398,15 @@ void DeepJetTableProducer::fillDescriptions(edm::ConfigurationDescriptions& d edm::ParameterSetDescription desc; desc.add("nameDeepJet", "Jet"); desc.add("idx_nameDeepJet", "djIdx"); - desc.add("storeAK4Truth", false); - desc.add("genparticles", edm::InputTag("prunedGenParticles")); + + desc.add("n_cpf", 3); + desc.add("n_npf", 3); + desc.add("n_sv", 4); desc.add("jets", edm::InputTag("slimmedJetsPuppi")); desc.add("tagInfo_src", edm::InputTag("pfDeepFlavourTagInfosPuppiWithDeepInfo")); descriptions.addWithDefaultLabel(desc); } typedef DeepJetTableProducer PatJetDeepJetTableProducer; -//typedef DeepJetTableProducer GenJetDeepJetTableProducer; DEFINE_FWK_MODULE(PatJetDeepJetTableProducer); -//DEFINE_FWK_MODULE(GenJetDeepJetTableProducer); diff --git a/PhysicsTools/NanoAOD/python/autoNANO.py b/PhysicsTools/NanoAOD/python/autoNANO.py index 74e48e3bdadd6..8e7894f96a20c 100644 --- a/PhysicsTools/NanoAOD/python/autoNANO.py +++ b/PhysicsTools/NanoAOD/python/autoNANO.py @@ -50,4 +50,5 @@ def expandNanoMapping(seqList, mapping, key): # Add lepton time-life info tables through customize combined with PHYS 'LepTimeLife' : {'sequence': '@PHYS', 'customize': '@PHYS+PhysicsTools/NanoAOD/leptonTimeLifeInfo_common_cff.addTimeLifeInfo'}, + 'BTVNano' : {'customize':'@PHYS+PhysicsTools/NanoAOD/custom_btv_cff.BTVCustomNanoAOD'} } diff --git a/PhysicsTools/NanoAOD/python/btvMC_cff.py b/PhysicsTools/NanoAOD/python/btvMC_cff.py new file mode 100644 index 0000000000000..0ae1f0b01fcc3 --- /dev/null +++ b/PhysicsTools/NanoAOD/python/btvMC_cff.py @@ -0,0 +1,170 @@ +import FWCore.ParameterSet.Config as cms + +from PhysicsTools.NanoAOD.common_cff import * +from PhysicsTools.NanoAOD.simpleCandidateFlatTableProducer_cfi import simpleCandidateFlatTableProducer +from PhysicsTools.NanoAOD.jetsAK8_cff import fatJetTable, subJetTable +from PhysicsTools.NanoAOD.jetsAK4_Puppi_cff import jetPuppiTable +from PhysicsTools.NanoAOD.genparticles_cff import * +# when storing the flat table, always do "T"able in the naming convention + + +finalGenParticles.select = finalGenParticles.select+[ + "keep (4 <= abs(pdgId) <= 5) && statusFlags().isLastCopy()", # BTV: keep b/c quarks in their last copy + "keep (abs(pdgId) == 310 || abs(pdgId) == 3122) && statusFlags().isLastCopy()", # BTV: keep K0s and Lambdas in their last copy + ] + +btvGenTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src=finalGenParticles.src, + name= cms.string("GenPart"), + doc = cms.string("interesting gen particles "), + singleton=cms.bool(False), + variables= + cms.PSet( + genParticleTable.variables, + vx = Var("vx", "float", doc="x coordinate of vertex position"), + vy = Var("vy", "float", doc="y coordinate of vertex position"), + vz = Var("vz", "float", doc="z coordinate of vertex position"), + genPartIdxMother2 = Var("?numberOfMothers>1?motherRef(1).key():-1", "int", doc="index of the second mother particle, if valid") + )) +genParticleTablesTask.replace(genParticleTable,btvGenTable) +btvMCTable = cms.EDProducer("BTVMCFlavourTableProducer",name=jetPuppiTable.name,src=cms.InputTag("linkedObjects","jets"),genparticles=cms.InputTag("prunedGenParticles")) + +btvAK4JetExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src=jetPuppiTable.src, + cut=jetPuppiTable.cut, + name=jetPuppiTable.name, + doc=jetPuppiTable.doc, + singleton=cms.bool(False), # the number of entries is variable + extension=cms.bool(True), # this is the extension table for Jets + variables=cms.PSet( + nBHadrons=Var("jetFlavourInfo().getbHadrons().size()", + int, + doc="number of b-hadrons"), + nCHadrons=Var("jetFlavourInfo().getcHadrons().size()", + int, + doc="number of c-hadrons"), + )) + +btvSubJetMCExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src = subJetTable.src, + cut = subJetTable.cut, + name = subJetTable.name, + doc=subJetTable.doc, + singleton = cms.bool(False), + extension = cms.bool(True), + variables = cms.PSet( + subGenJetAK8Idx = Var("?genJetFwdRef().backRef().isNonnull()?genJetFwdRef().backRef().key():-1", + int, + doc="index of matched gen Sub jet"), + ) + ) +genJetsAK8Constituents = cms.EDProducer("GenJetPackedConstituentPtrSelector", + src = cms.InputTag("slimmedGenJetsAK8"), + cut = cms.string("pt > 100.") + ) + + +genJetsAK4Constituents = cms.EDProducer("GenJetPackedConstituentPtrSelector", + src = cms.InputTag("slimmedGenJets"), + cut = cms.string("pt > 20") + ) + + + + + +ak4onlygenJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents")), skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + +ak8onlygenJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = cms.VInputTag(cms.InputTag("genJetsAK8Constituents", "constituents")), skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) +ak4ak8genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents"), cms.InputTag("genJetsAK8Constituents", "constituents")), skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + +allPFParticleTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = cms.InputTag("packedGenParticles"), + cut = cms.string(""), #we should not filter after pruning + name= cms.string("GenCands"), + doc = cms.string("interesting gen particles from PF candidates"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the AK8 constituents + variables = cms.PSet(CandVars + ) + ) +ak4onlygenJetsParticleTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = cms.InputTag("ak4onlygenJetsConstituents"), + cut = cms.string(""), #we should not filter after pruning + name= cms.string("GenCands"), + doc = cms.string("interesting gen particles from AK4 jets"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the AK8 constituents + variables = cms.PSet(CandVars + ) + ) +ak8onlygenJetsParticleTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = cms.InputTag("ak8onlygenJetsConstituents"), + cut = cms.string(""), #we should not filter after pruning + name= cms.string("GenCands"), + doc = cms.string("interesting gen particles from AK8 jets"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the AK8 constituents + variables = cms.PSet(CandVars + ) + ) +ak4ak8genJetsParticleTable = cms.EDProducer("SimpleCandidateFlatTableProducer", + src = cms.InputTag("ak4ak8genJetsConstituents"), + cut = cms.string(""), #we should not filter after pruning + name= cms.string("GenCands"), + doc = cms.string("interesting gen particles from AK4, AK8 jets"), + singleton = cms.bool(False), # the number of entries is variable + extension = cms.bool(False), # this is the main table for the AK8 constituents + variables = cms.PSet(CandVars + ) + ) +ak8onlygenAK8ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", + candidates = cms.InputTag("genJetsConstituents"), + jets = cms.InputTag("genJetsAK8Constituents"), # Note: The name has "Constituents" in it, but these are the jets + name = cms.string("GenFatJetCands"), + nameSV = cms.string("GenFatJetSVs"), + idx_name = cms.string("pFCandsIdx"), + idx_nameSV = cms.string("sVIdx"), + readBtag = cms.bool(False)) +ak4onlygenAK4ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", + candidates = cms.InputTag("genJetsConstituents"), + jets = cms.InputTag("genJetsAK4Constituents"), # Note: The name has "Constituents" in it, but these are the jets + name = cms.string("GenJetCands"), + nameSV = cms.string("GenJetSVs"), + idx_name = cms.string("pFCandsIdx"), + idx_nameSV = cms.string("sVIdx"), + readBtag = cms.bool(False)) +ak4ak8genAK4ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", + candidates = cms.InputTag("genJetsConstituents"), + jets = cms.InputTag("genJetsAK4Constituents"), # Note: The name has "Constituents" in it, but these are the jets + name = cms.string("GenJetCands"), + nameSV = cms.string("GenJetSVs"), + idx_name = cms.string("pFCandsIdx"), + idx_nameSV = cms.string("sVIdx"), + readBtag = cms.bool(False)) + +ak4ak8genAK8ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", + candidates = cms.InputTag("genJetsConstituents"), + jets = cms.InputTag("genJetsAK8Constituents"), # Note: The name has "Constituents" in it, but these are the jets + name = cms.string("GenFatJetCands"), + nameSV = cms.string("GenFatJetSVs"), + idx_name = cms.string("pFCandsIdx"), + idx_nameSV = cms.string("sVIdx"), + readBtag = cms.bool(False)) +btvAK4MCSequence = cms.Sequence(btvGenTable+btvAK4JetExtTable+btvMCTable) +btvAK8MCSequence = cms.Sequence(btvGenTable+btvSubJetMCExtTable) +#PF Cands of AK4 only , with cross linking to AK4 jets +ak4onlyPFCandsMCSequence=cms.Sequence(genJetsAK4Constituents+ak4onlygenJetsConstituents+ak4onlygenJetsParticleTable+ak4onlygenAK4ConstituentsTable)+btvAK4MCSequence +#PF Cands of AK8 only , with cross linking to AK8 jets +ak8onlyPFCandsMCSequence=cms.Sequence(genJetsAK8Constituents+ak8onlygenJetsConstituents+ak8onlygenJetsParticleTable+ak8onlygenAK8ConstituentsTable)+btvAK8MCSequence +#PF Cands of AK4+AK8, with cross linking to AK4,AK8 jets +ak4ak8PFCandsMCSequence=cms.Sequence(genJetsAK4Constituents+genJetsAK8Constituents+ak4ak8genJetsConstituents+ak4ak8genJetsParticleTable+ak4ak8genAK4ConstituentsTable+ak4ak8genAK8ConstituentsTable)+btvAK4MCSequence+btvAK8MCSequence +#All PFCands, with cross linking to AK4,AK8 jets +allPFPFCandsMCSequence=cms.Sequence(genJetsAK4Constituents+genJetsAK8Constituents+ak4ak8genJetsConstituents+allPFParticleTable+ak4ak8genAK4ConstituentsTable+ak4ak8genAK8ConstituentsTable)+btvAK4MCSequence+btvAK8MCSequence + + + + diff --git a/PhysicsTools/NanoAOD/python/custom_btv_cff.py b/PhysicsTools/NanoAOD/python/custom_btv_cff.py index edba473d1089e..b4e3029c9da86 100644 --- a/PhysicsTools/NanoAOD/python/custom_btv_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_btv_cff.py @@ -1,31 +1,15 @@ import FWCore.ParameterSet.Config as cms from PhysicsTools.NanoAOD.common_cff import Var -#from PhysicsTools.NanoAOD.jetsAK4_CHS_cff import jetTable, jetCorrFactorsNano, updatedJets, finalJets, qgtagger, hfJetShowerShapeforNanoAOD from PhysicsTools.NanoAOD.jetsAK4_Puppi_cff import jetPuppiTable, jetPuppiCorrFactorsNano, updatedJetsPuppi, updatedJetsPuppiWithUserData from PhysicsTools.NanoAOD.jetsAK8_cff import fatJetTable, subJetTable from PhysicsTools.PatAlgos.tools.jetTools import updateJetCollection from PhysicsTools.PatAlgos.tools.helpers import addToProcessAndTask, getPatAlgosToolsTask from PhysicsTools.NanoAOD.common_cff import Var, CandVars from PhysicsTools.NanoAOD.simpleCandidateFlatTableProducer_cfi import simpleCandidateFlatTableProducer - +from PhysicsTools.NanoAOD.btvMC_cff import * ## Move PFNano (https://github.com/cms-jet/PFNano/) to NanoAOD - ## From: https://github.com/cms-jet/PFNano/blob/13_0_7_from124MiniAOD/python/addBTV.py -## Define customized GenParticles -def customize_BTV_GenTable(process): - process.finalGenParticles.select += [ - "keep (4 <= abs(pdgId) <= 5) && statusFlags().isLastCopy()", # BTV: keep b/c quarks in their last copy - "keep (abs(pdgId) == 310 || abs(pdgId) == 3122) && statusFlags().isLastCopy()", # BTV: keep K0s and Lambdas in their last copy - ] - process.genParticleTable.variables = cms.PSet( - process.genParticleTable.variables, - vx = Var("vx", "float", doc="x coordinate of vertex position"), - vy = Var("vy", "float", doc="y coordinate of vertex position"), - vz = Var("vz", "float", doc="z coordinate of vertex position"), - genPartIdxMother2 = Var("?numberOfMothers>1?motherRef(1).key():-1", "int", doc="index of the second mother particle, if valid"), - ) - def update_jets_AK4(process): # Based on ``nanoAOD_addDeepInfo`` # in https://github.com/cms-sw/cmssw/blob/master/PhysicsTools/NanoAOD/python/nano_cff.py @@ -449,16 +433,10 @@ def get_ParticleTransformerAK4_outputs(): return ParticleTransformerAK4OutputVars -def add_BTV(process, runOnMC=False, addAK4=False, addAK8=False): - if addAK4: - process = update_jets_AK4(process) - if addAK8: - process = update_jets_AK8(process) - process = update_jets_AK8_subjet(process) - +def add_BTV(process, addAK4=False, addAK8=False, scheme="btvSF"): process.customizeJetTask = cms.Task() process.schedule.associate(process.customizeJetTask) - + CommonVars = cms.PSet( Proba=Var("bDiscriminator('pfJetProbabilityBJetTags')", float, @@ -489,89 +467,90 @@ def add_BTV(process, runOnMC=False, addAK4=False, addAK8=False): ) # AK4 - process.customJetExtTable = cms.EDProducer( - "SimpleCandidateFlatTableProducer", - src=jetPuppiTable.src, - cut=jetPuppiTable.cut, - name=jetPuppiTable.name, - doc=jetPuppiTable.doc, - singleton=cms.bool(False), # the number of entries is variable - extension=cms.bool(True), # this is the extension table for Jets - variables=cms.PSet( - CommonVars, - HadronCountingVars if runOnMC else cms.PSet(), # hadrons from Generator only relevant for MC - get_DeepCSV_vars(), - get_DeepJet_outputs(), # outputs are added in any case, inputs only if requested - get_ParticleNetAK4_outputs(), - get_ParticleTransformerAK4_outputs(), - )) - - # disable the ParT branches in default jetPuppi table - from PhysicsTools.NanoAOD.nano_eras_cff import run3_nanoAOD_122, run3_nanoAOD_124 - (run3_nanoAOD_122 | run3_nanoAOD_124).toModify( - process.jetPuppiTable.variables, - btagRobustParTAK4B = None, - btagRobustParTAK4CvL = None, - btagRobustParTAK4CvB = None, - btagRobustParTAK4QG = None, - ) + if addAK4: + if scheme == "btvSF": + _n_cpf = 3 + _n_npf = 3 + _n_sv = 4 + elif scheme == "DeepJet": + _n_cpf = 25 + _n_npf = 25 + _n_sv = 4 + elif scheme == "RobustParTAK4": + _n_cpf = 25 + _n_npf = 25 + _n_sv = 12 + process = update_jets_AK4(process) + + process.customJetExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src=jetPuppiTable.src, + cut=jetPuppiTable.cut, + name=jetPuppiTable.name, + doc=jetPuppiTable.doc, + singleton=cms.bool(False), # the number of entries is variable + extension=cms.bool(True), # this is the extension table for Jets + variables=cms.PSet( + CommonVars, + get_DeepCSV_vars(), + get_DeepJet_outputs(), # outputs are added in any case, inputs only if requested + get_ParticleNetAK4_outputs(), + get_ParticleTransformerAK4_outputs(), + )) + + # disable the ParT branches in default jetPuppi table + from PhysicsTools.NanoAOD.nano_eras_cff import run3_nanoAOD_122, run3_nanoAOD_124 + (run3_nanoAOD_122 | run3_nanoAOD_124).toModify( + process.jetPuppiTable.variables, + btagRobustParTAK4B = None, + btagRobustParTAK4CvL = None, + btagRobustParTAK4CvB = None, + btagRobustParTAK4QG = None, + ) - # from Run3 onwards, always set storeAK4Truth to True for MC - process.customAK4ConstituentsForDeepJetTable = cms.EDProducer("PatJetDeepJetTableProducer", - jets = cms.InputTag("linkedObjects","jets"), - storeAK4Truth = cms.bool(runOnMC), + # from Run3 onwards, always set storeAK4Truth to True for MC + process.customAK4ConstituentsForDeepJetTable = cms.EDProducer("PatJetDeepJetTableProducer", + jets = cms.InputTag("linkedObjects","jets"), + n_cpf=cms.uint32(_n_cpf), + n_npf=cms.uint32(_n_npf), + n_sv=cms.uint32(_n_sv) ) - - # AK8 - process.customFatJetExtTable = cms.EDProducer( - "SimpleCandidateFlatTableProducer", - src=fatJetTable.src, - cut=fatJetTable.cut, - name=fatJetTable.name, - doc=fatJetTable.doc, - singleton=cms.bool(False), # the number of entries is variable - extension=cms.bool(True), # this is the extension table for FatJets - variables=cms.PSet( - CommonVars, - #HadronCountingVars if runOnMC else cms.PSet(), # only necessary before 106x - get_DDX_vars() , - )) - - # Subjets - process.customSubJetExtTable = cms.EDProducer( - "SimpleCandidateFlatTableProducer", - src=subJetTable.src, - cut=subJetTable.cut, - name=subJetTable.name, - doc=subJetTable.doc, - singleton=cms.bool(False), # the number of entries is variable - extension=cms.bool(True), # this is the extension table for FatJets - variables=cms.PSet( - CommonVars, - #HadronCountingVars if runOnMC else cms.PSet(), # only necessary before 106x - )) - - process.customSubJetMCExtTable = cms.EDProducer( - "SimpleCandidateFlatTableProducer", - src = subJetTable.src, - cut = subJetTable.cut, - name = subJetTable.name, - doc=subJetTable.doc, - singleton = cms.bool(False), - extension = cms.bool(True), - variables = cms.PSet( - subGenJetAK8Idx = Var("?genJetFwdRef().backRef().isNonnull()?genJetFwdRef().backRef().key():-1", - int, - doc="index of matched gen Sub jet"), - ) - ) - - if addAK4: process.customizeJetTask.add(process.customJetExtTable) process.customizeJetTask.add(process.customAK4ConstituentsForDeepJetTable) - + # AK8 if addAK8: + process = update_jets_AK8(process) + process = update_jets_AK8_subjet(process) + process.customFatJetExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src=fatJetTable.src, + cut=fatJetTable.cut, + name=fatJetTable.name, + doc=fatJetTable.doc, + singleton=cms.bool(False), # the number of entries is variable + extension=cms.bool(True), # this is the extension table for FatJets + variables=cms.PSet( + CommonVars, + #HadronCountingVars if runOnMC else cms.PSet(), # only necessary before 106x + get_DDX_vars() , + )) + + + # Subjets + process.customSubJetExtTable = cms.EDProducer( + "SimpleCandidateFlatTableProducer", + src=subJetTable.src, + cut=subJetTable.cut, + name=subJetTable.name, + doc=subJetTable.doc, + singleton=cms.bool(False), # the number of entries is variable + extension=cms.bool(True), # this is the extension table for FatJets + variables=cms.PSet( + CommonVars, + #HadronCountingVars if runOnMC else cms.PSet(), # only necessary before 106x + )) + process.customizeJetTask.add(process.customFatJetExtTable) process.customizeJetTask.add(process.customSubJetExtTable) if runOnMC: @@ -582,8 +561,8 @@ def add_BTV(process, runOnMC=False, addAK4=False, addAK8=False): customize_BTV_GenTable(process) # From https://github.com/cms-jet/PFNano/blob/13_0_7_from124MiniAOD/python/addPFCands_cff.py -def addPFCands(process, runOnMC=False, allPF = False, addAK4=False, addAK8=False): - process.customizedPFCandsTask = cms.Task( ) +def addPFCands(process, allPF = False, addAK4=False, addAK8=False): + process.customizedPFCandsTask = cms.Task() process.schedule.associate(process.customizedPFCandsTask) process.finalJetsAK8Constituents = cms.EDProducer("PatJetConstituentPtrSelector", @@ -599,19 +578,20 @@ def addPFCands(process, runOnMC=False, allPF = False, addAK4=False, addAK8=False elif not addAK8: candList = cms.VInputTag(cms.InputTag("finalJetsAK4Constituents", "constituents")) process.customizedPFCandsTask.add(process.finalJetsAK4Constituents) - process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - candInput = cms.InputTag("finalJetsConstituents") + process.finalJetsConstituentsTable = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituentsTable") elif not addAK4: candList = cms.VInputTag(cms.InputTag("finalJetsAK8Constituents", "constituents")) process.customizedPFCandsTask.add(process.finalJetsAK8Constituents) - process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - candInput = cms.InputTag("finalJetsConstituents") + process.finalJetsConstituentsTable = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituentsTable") else: candList = cms.VInputTag(cms.InputTag("finalJetsAK4Constituents", "constituents"), cms.InputTag("finalJetsAK8Constituents", "constituents")) process.customizedPFCandsTask.add(process.finalJetsAK4Constituents) process.customizedPFCandsTask.add(process.finalJetsAK8Constituents) - process.finalJetsConstituents = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - candInput = cms.InputTag("finalJetsConstituents") + process.finalJetsConstituentsTable = cms.EDProducer("PackedCandidatePtrMerger", src = candList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) + candInput = cms.InputTag("finalJetsConstituentsTable") + process.customConstituentsExtTable = cms.EDProducer("SimpleCandidateFlatTableProducer", src = candInput, cut = cms.string(""), #we should not filter after pruning @@ -660,12 +640,15 @@ def addPFCands(process, runOnMC=False, allPF = False, addAK4=False, addAK8=False nameSV = cms.string("JetSVs"), idx_nameSV = cms.string("sVIdx"), ) - if not allPF: - process.customizedPFCandsTask.add(process.finalJetsConstituents) process.customizedPFCandsTask.add(process.customConstituentsExtTable) + + if not allPF: + process.customizedPFCandsTask.add(process.finalJetsConstituentsTable) # linkedObjects are WIP for Run3 - process.customizedPFCandsTask.add(process.customAK8ConstituentsTable) - process.customizedPFCandsTask.add(process.customAK4ConstituentsTable) + if addAK8: + process.customizedPFCandsTask.add(process.customAK8ConstituentsTable) + if addAK4: + process.customizedPFCandsTask.add(process.customAK4ConstituentsTable) if runOnMC: @@ -731,18 +714,27 @@ def addPFCands(process, runOnMC=False, allPF = False, addAK4=False, addAK8=False ## Switches for BTV nano # Default(store SFs PFCands+TaggerInputs) for both AK4 & AK8 jets -# nanoAOD_addbtagAK4_switch, nanoAOD_addbtagAK8_switch True, nanoAOD_allPF_switch False - -nanoAOD_allPF_switch = False # Add all PF candidates, use for training -nanoAOD_addbtagAK4_switch = True # AK4 SFs vars -nanoAOD_addbtagAK8_switch = False # AK8 SFs vars - -def PrepBTVCustomNanoAOD_MC(process): - addPFCands(process, True, nanoAOD_allPF_switch,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) - add_BTV(process, True,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) +# btvNano_addAK4_switch, btvNano_addAK8_switch True, btvNano_addPF_switch False, TaggerInput = "btvSF" + +btvNano_switch = cms.PSet( + btvNano_addAK4_switch = cms.untracked.bool(True), + btvNano_addAK8_switch = cms.untracked.bool(False), + btvNano_addallPF_switch = cms.untracked.bool(False), + TaggerInput = cms.string("btvSF") + ) + +def BTVCustomNanoAOD(process): + addPFCands(process,btvNano_switch.btvNano_addallPF_switch,btvNano_switch.btvNano_addAK4_switch,btvNano_switch.btvNano_addAK8_switch) + add_BTV(process, btvNano_switch.btvNano_addAK4_switch,btvNano_switch.btvNano_addAK8_switch,btvNano_switch.TaggerInput) + ### for MC + customize_BTV_GenTable(process) + if btvNano_switch.btvNano_addallPF_switch: + process.nanoSequenceMC+=allPFPFCandsMCSequence + else: + if btvNano_switch.btvNano_addAK4_switch and btvNano_switch.btvNano_addAK8_switch : + process.nanoSequenceMC+=process.nanoSequenceMC+ak4ak8PFCandsMCSequence + elif btvNano_switch.btvNano_addAK4_switch and not btvNano_switch.btvNano_addAK8_switch : + process.nanoSequenceMC+=ak4onlyPFCandsMCSequence + elif not btvNano_switch.btvNano_addAK4_switch and btvNano_switch.btvNano_addAK8_switch: + process.nanoSequenceMC+=ak8onlyPFCandsMCSequence return process -def PrepBTVCustomNanoAOD_DATA(process): - # only run if SFvar or allPFCands - addPFCands(process, False, nanoAOD_allPF_switch,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) - add_BTV(process, False,nanoAOD_addbtagAK4_switch,nanoAOD_addbtagAK8_switch) - return process \ No newline at end of file diff --git a/PhysicsTools/NanoAOD/python/nano_cff.py b/PhysicsTools/NanoAOD/python/nano_cff.py index 515c0c75d066a..696fc2094cfc0 100644 --- a/PhysicsTools/NanoAOD/python/nano_cff.py +++ b/PhysicsTools/NanoAOD/python/nano_cff.py @@ -28,6 +28,7 @@ from PhysicsTools.NanoAOD.fsrPhotons_cff import * from PhysicsTools.NanoAOD.softActivity_cff import * from PhysicsTools.NanoAOD.l1trig_cff import * +from PhysicsTools.NanoAOD.custom_btv_cff import * nanoMetadata = cms.EDProducer("UniqueStringProducer", strings = cms.PSet( diff --git a/RecoBTag/ImpactParameter/interface/TemplatedTrackCountingComputer.h b/RecoBTag/ImpactParameter/interface/TemplatedTrackCountingComputer.h index 58a5b79e6c079..4973868927ddb 100644 --- a/RecoBTag/ImpactParameter/interface/TemplatedTrackCountingComputer.h +++ b/RecoBTag/ImpactParameter/interface/TemplatedTrackCountingComputer.h @@ -97,9 +97,9 @@ class TemplatedTrackCountingComputer : public JetTagComputer { if (tkip.variableJTA(varJTApars)[i]) significances.insert(significance); } else // no using variable JTA, use the default method - if (m_deltaR <= 0 || - ROOT::Math::VectorUtil::DeltaR((*tkip.jet()).p4().Vect(), (*tracks[i]).momentum()) < m_deltaR) - significances.insert(significance); + if (m_deltaR <= 0 || + ROOT::Math::VectorUtil::DeltaR((*tkip.jet()).p4().Vect(), (*tracks[i]).momentum()) < m_deltaR) + significances.insert(significance); } } From e8182adcc956f7e2a976ceed1257a8dafdef2f14 Mon Sep 17 00:00:00 2001 From: Ming-Yan Lee Date: Tue, 5 Mar 2024 16:25:12 +0100 Subject: [PATCH 6/9] feat: add workflow --- .../PyReleaseValidation/python/relval_nano.py | 14 ++++++++++++++ PhysicsTools/NanoAOD/python/autoNANO.py | 2 +- PhysicsTools/NanoAOD/python/btvMC_cff.py | 2 +- PhysicsTools/NanoAOD/python/nano_cff.py | 1 - 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Configuration/PyReleaseValidation/python/relval_nano.py b/Configuration/PyReleaseValidation/python/relval_nano.py index e9ee78a8d0664..f98b84b3a5980 100644 --- a/Configuration/PyReleaseValidation/python/relval_nano.py +++ b/Configuration/PyReleaseValidation/python/relval_nano.py @@ -182,6 +182,11 @@ def subnext(self): '-n' : '1000'}, steps['NANO_data13.0']]) +steps['BTVNANO_data13.0']=merge([{'-s' : 'NANO:@PHYS+@BTV', + '-n' : '1000'}, + steps['NANO_data13.0']]) + + ###current release cycle workflows : 13.2 steps['TTBarMINIAOD13.2'] = {'INPUT':InputInfo(location='STD', dataSet='/RelValTTbar_14TeV/CMSSW_13_2_0-PU_131X_mcRun3_2023_realistic_v9-v1/MINIAODSIM')} @@ -190,6 +195,7 @@ def subnext(self): '--conditions':'auto:phase1_2022_realistic'}, _NANO_mc]) + steps['muPOGNANO_mc13.2']=merge([{'-s' : 'NANO:@MUPOG,DQM:@nanoAODDQM', '-n' : '1000'}, steps['NANO_mc13.2']]) @@ -203,6 +209,10 @@ def subnext(self): '-n' : '1000'}, steps['NANO_mc13.2']]) +steps['BTVNANO_mc13.2']=merge([{'-s' : 'NANO:@PHYS+@BTV', + '-n' : '1000'}, + steps['NANO_mc13.2']]) + ##13.X INPUT steps['ScoutingPFRun32022DRAW13.X']={'INPUT':InputInfo(dataSet='/ScoutingPFRun3/Run2022D-v1/RAW',label='2022D',events=100000,location='STD', ls=Run2022D)} @@ -253,10 +263,12 @@ def subnext(self): workflows[_wfn()] = ['NANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'NANO_data13.0_prompt', 'HRV_NANO_data']] workflows[_wfn()] = ['muDPGNANO130Xrun3', ['ZMuSkim2023DRAWRECO13.0', 'muDPGNANO_data13.0']] workflows[_wfn()] = ['muDPGNANOBkg130Xrun3', ['ZeroBias2023DRAW13.0', 'muDPGNANOBkg_data13.0']] + workflows[_wfn()] = ['muPOGNANO130Xrun3', ['MuonEG2023MINIAOD13.0', 'muPOGNANO_data13.0']] workflows[_wfn()] = ['EGMNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'EGMNano_data13.0']] workflows[_wfn()] = ['jmeNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'jmeNano_data13.0']] workflows[_wfn()] = ['lepTimeLifeNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'lepTimeLifeNANO_data13.0']] +workflows[_wfn()] = ['BTVNANO_data13.0', ['MuonEG2023MINIAOD13.0', 'BTVNANO_data13.0']] _wfn.next() ################ @@ -266,6 +278,8 @@ def subnext(self): workflows[_wfn()] = ['EGMNANOmc132X', ['TTBarMINIAOD13.2', 'EGMNano_mc13.2']] workflows[_wfn()] = ['jmeNANOmc132X', ['TTBarMINIAOD13.2', 'jmeNANO_mc13.2']] workflows[_wfn()] = ['lepTimeLifeNANOmc132X', ['TTBarMINIAOD13.2', 'lepTimeLifeNANO_mc13.2']] +workflows[_wfn()] = ['BTVNANO_mc13.2', ['TTBarMINIAOD13.2', 'BTVNANO_mc13.2']] + _wfn.next() ################ diff --git a/PhysicsTools/NanoAOD/python/autoNANO.py b/PhysicsTools/NanoAOD/python/autoNANO.py index 8e7894f96a20c..f09ad91af0407 100644 --- a/PhysicsTools/NanoAOD/python/autoNANO.py +++ b/PhysicsTools/NanoAOD/python/autoNANO.py @@ -50,5 +50,5 @@ def expandNanoMapping(seqList, mapping, key): # Add lepton time-life info tables through customize combined with PHYS 'LepTimeLife' : {'sequence': '@PHYS', 'customize': '@PHYS+PhysicsTools/NanoAOD/leptonTimeLifeInfo_common_cff.addTimeLifeInfo'}, - 'BTVNano' : {'customize':'@PHYS+PhysicsTools/NanoAOD/custom_btv_cff.BTVCustomNanoAOD'} + 'BTV' : {'customize':'@PHYS+PhysicsTools/NanoAOD/custom_btv_cff.BTVCustomNanoAOD'} } diff --git a/PhysicsTools/NanoAOD/python/btvMC_cff.py b/PhysicsTools/NanoAOD/python/btvMC_cff.py index 0ae1f0b01fcc3..18bd5ff33448e 100644 --- a/PhysicsTools/NanoAOD/python/btvMC_cff.py +++ b/PhysicsTools/NanoAOD/python/btvMC_cff.py @@ -8,7 +8,7 @@ # when storing the flat table, always do "T"able in the naming convention -finalGenParticles.select = finalGenParticles.select+[ +finalGenParticles.select +=[ "keep (4 <= abs(pdgId) <= 5) && statusFlags().isLastCopy()", # BTV: keep b/c quarks in their last copy "keep (abs(pdgId) == 310 || abs(pdgId) == 3122) && statusFlags().isLastCopy()", # BTV: keep K0s and Lambdas in their last copy ] diff --git a/PhysicsTools/NanoAOD/python/nano_cff.py b/PhysicsTools/NanoAOD/python/nano_cff.py index 696fc2094cfc0..515c0c75d066a 100644 --- a/PhysicsTools/NanoAOD/python/nano_cff.py +++ b/PhysicsTools/NanoAOD/python/nano_cff.py @@ -28,7 +28,6 @@ from PhysicsTools.NanoAOD.fsrPhotons_cff import * from PhysicsTools.NanoAOD.softActivity_cff import * from PhysicsTools.NanoAOD.l1trig_cff import * -from PhysicsTools.NanoAOD.custom_btv_cff import * nanoMetadata = cms.EDProducer("UniqueStringProducer", strings = cms.PSet( From dec2f3724a7fd5102e638babf57325a0e6c2e6cc Mon Sep 17 00:00:00 2001 From: Ming-Yan Lee Date: Wed, 6 Mar 2024 14:18:45 +0100 Subject: [PATCH 7/9] feat:remove redudant files - fixing conflicts - remove BTV_flavor.h - compile issue --- .../PyReleaseValidation/python/relval_nano.py | 21 +++++- PhysicsTools/NanoAOD/interface/BTV_flavor.h | 7 -- .../plugins/BTVMCFlavourTableProducer.cc | 1 - .../NanoAOD/plugins/DeepJetTableProducer.cc | 2 - PhysicsTools/NanoAOD/python/autoNANO.py | 5 +- PhysicsTools/NanoAOD/python/custom_btv_cff.py | 72 ++----------------- 6 files changed, 28 insertions(+), 80 deletions(-) delete mode 100644 PhysicsTools/NanoAOD/interface/BTV_flavor.h diff --git a/Configuration/PyReleaseValidation/python/relval_nano.py b/Configuration/PyReleaseValidation/python/relval_nano.py index f98b84b3a5980..96731cf90cfd8 100644 --- a/Configuration/PyReleaseValidation/python/relval_nano.py +++ b/Configuration/PyReleaseValidation/python/relval_nano.py @@ -152,6 +152,7 @@ def subnext(self): steps['NANO_data13.0_prompt']=merge([{'--customise' : 'PhysicsTools/NanoAOD/nano_cff.nanoL1TrigObjCustomize', '-n' : '1000'}, steps['NANO_data13.0']]) + steps['muDPGNANO_data13.0']=merge([{'-s' : 'RAW2DIGI,NANO:@MUDPG', '--conditions':'auto:run3_data', '-n' : '100', @@ -175,6 +176,7 @@ def subnext(self): steps['EGMNano_mc13.0'] = merge([{'-s':'NANO:@EGM,DQM:@nanoAODDQM', '-n' : '1000'}, steps['NANO_mc13.0']]) + steps['jmeNano_data13.0'] = merge([{'-s':'NANO:@JME', '-n' : '1000'}, steps['NANO_data13.0']]) @@ -186,7 +188,6 @@ def subnext(self): '-n' : '1000'}, steps['NANO_data13.0']]) - ###current release cycle workflows : 13.2 steps['TTBarMINIAOD13.2'] = {'INPUT':InputInfo(location='STD', dataSet='/RelValTTbar_14TeV/CMSSW_13_2_0-PU_131X_mcRun3_2023_realistic_v9-v1/MINIAODSIM')} @@ -197,11 +198,11 @@ def subnext(self): steps['muPOGNANO_mc13.2']=merge([{'-s' : 'NANO:@MUPOG,DQM:@nanoAODDQM', '-n' : '1000'}, - steps['NANO_mc13.2']]) steps['EGMNano_mc13.2'] = merge([{'-s':'NANO:@EGM,DQM:@nanoAODDQM', '-n' : '1000'}, steps['NANO_mc13.2']]) + steps['jmeNANO_mc13.2']=merge([{'-s' : 'NANO:@JME ', '-n' : '1000'}, steps['NANO_mc13.2']]) @@ -209,10 +210,21 @@ def subnext(self): '-n' : '1000'}, steps['NANO_mc13.2']]) + steps['BTVNANO_mc13.2']=merge([{'-s' : 'NANO:@PHYS+@BTV', '-n' : '1000'}, steps['NANO_mc13.2']]) +steps['lepTimeLifeNANO_mc13.2']=merge([{'-s' : 'NANO:@LepTimeLife,DQM:@nanoAODDQM', '-n' : '1000'}, + steps['NANO_mc13.2']]) + +steps['jmeNANO_mc13.2']=merge([{'-s' : 'NANO:@JME ', '-n' : '1000'}, + steps['NANO_mc13.2']]) + +steps['lepTimeLifeNANO_mc13.2']=merge([{'-s' : 'NANO:@LepTimeLife,DQM:@nanoAODDQM', + '-n' : '1000'}, + steps['NANO_mc13.2']]) + ##13.X INPUT steps['ScoutingPFRun32022DRAW13.X']={'INPUT':InputInfo(dataSet='/ScoutingPFRun3/Run2022D-v1/RAW',label='2022D',events=100000,location='STD', ls=Run2022D)} @@ -264,10 +276,13 @@ def subnext(self): workflows[_wfn()] = ['muDPGNANO130Xrun3', ['ZMuSkim2023DRAWRECO13.0', 'muDPGNANO_data13.0']] workflows[_wfn()] = ['muDPGNANOBkg130Xrun3', ['ZeroBias2023DRAW13.0', 'muDPGNANOBkg_data13.0']] + workflows[_wfn()] = ['muPOGNANO130Xrun3', ['MuonEG2023MINIAOD13.0', 'muPOGNANO_data13.0']] workflows[_wfn()] = ['EGMNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'EGMNano_data13.0']] workflows[_wfn()] = ['jmeNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'jmeNano_data13.0']] workflows[_wfn()] = ['lepTimeLifeNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'lepTimeLifeNANO_data13.0']] +workflows[_wfn()] = ['EGMNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'EGMNano_data13.0']] + workflows[_wfn()] = ['BTVNANO_data13.0', ['MuonEG2023MINIAOD13.0', 'BTVNANO_data13.0']] _wfn.next() @@ -278,9 +293,9 @@ def subnext(self): workflows[_wfn()] = ['EGMNANOmc132X', ['TTBarMINIAOD13.2', 'EGMNano_mc13.2']] workflows[_wfn()] = ['jmeNANOmc132X', ['TTBarMINIAOD13.2', 'jmeNANO_mc13.2']] workflows[_wfn()] = ['lepTimeLifeNANOmc132X', ['TTBarMINIAOD13.2', 'lepTimeLifeNANO_mc13.2']] +workflows[_wfn()] = ['EGMNANOmc132X', ['TTBarMINIAOD13.2', 'EGMNano_mc13.2']] workflows[_wfn()] = ['BTVNANO_mc13.2', ['TTBarMINIAOD13.2', 'BTVNANO_mc13.2']] - _wfn.next() ################ #13.X workflows diff --git a/PhysicsTools/NanoAOD/interface/BTV_flavor.h b/PhysicsTools/NanoAOD/interface/BTV_flavor.h deleted file mode 100644 index 78a51f1cf7300..0000000000000 --- a/PhysicsTools/NanoAOD/interface/BTV_flavor.h +++ /dev/null @@ -1,7 +0,0 @@ -int jet_flavour(const pat::Jet& jet, - const std::vector& gToBB, - const std::vector& gToCC, - const std::vector& neutrinosLepB, - const std::vector& neutrinosLepB_C, - const std::vector& alltaus, - bool usePhysForLightAndUndefined); diff --git a/PhysicsTools/NanoAOD/plugins/BTVMCFlavourTableProducer.cc b/PhysicsTools/NanoAOD/plugins/BTVMCFlavourTableProducer.cc index a5f7c93ef01f7..01454c9a2c78d 100644 --- a/PhysicsTools/NanoAOD/plugins/BTVMCFlavourTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/BTVMCFlavourTableProducer.cc @@ -13,7 +13,6 @@ #include "DataFormats/PatCandidates/interface/Jet.h" #include "DataFormats/HepMCCandidate/interface/GenParticle.h" -#include "PhysicsTools/NanoAOD/interface/BTV_flavor.h" #include "DataFormats/Math/interface/deltaR.h" #include "DataFormats/NanoAOD/interface/FlatTable.h" diff --git a/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc b/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc index a81469218288e..1c4ac5df4bd76 100644 --- a/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc +++ b/PhysicsTools/NanoAOD/plugins/DeepJetTableProducer.cc @@ -25,8 +25,6 @@ using namespace btagbtvdeep; // To store the gen info to get the truth flavour of the jet #include "DataFormats/PatCandidates/interface/Jet.h" -#include "PhysicsTools/NanoAOD/interface/BTV_flavor.h" - template class DeepJetTableProducer : public edm::stream::EDProducer<> { public: diff --git a/PhysicsTools/NanoAOD/python/autoNANO.py b/PhysicsTools/NanoAOD/python/autoNANO.py index f09ad91af0407..0ed68007ab840 100644 --- a/PhysicsTools/NanoAOD/python/autoNANO.py +++ b/PhysicsTools/NanoAOD/python/autoNANO.py @@ -36,6 +36,7 @@ def expandNanoMapping(seqList, mapping, key): # Muon POG flavours : add tables through customize, supposed to be combined with PHYS 'MUPOG' : { 'sequence': '@PHYS', 'customize' : '@PHYS+PhysicsTools/NanoAOD/custom_muon_cff.PrepMuonCustomNanoAOD'}, + # MUDPG flavours: use their own sequence 'MUDPG' : {'sequence': 'DPGAnalysis/MuonTools/muNtupleProducer_cff.muDPGNanoProducer', 'customize': 'DPGAnalysis/MuonTools/muNtupleProducer_cff.muDPGNanoCustomize'}, @@ -50,5 +51,7 @@ def expandNanoMapping(seqList, mapping, key): # Add lepton time-life info tables through customize combined with PHYS 'LepTimeLife' : {'sequence': '@PHYS', 'customize': '@PHYS+PhysicsTools/NanoAOD/leptonTimeLifeInfo_common_cff.addTimeLifeInfo'}, - 'BTV' : {'customize':'@PHYS+PhysicsTools/NanoAOD/custom_btv_cff.BTVCustomNanoAOD'} + # Custom BTV Nano for SF measurements or tagger training + 'BTV' : {'sequence': '@PHYS', + 'customize':'@PHYS+PhysicsTools/NanoAOD/custom_btv_cff.BTVCustomNanoAOD'} } diff --git a/PhysicsTools/NanoAOD/python/custom_btv_cff.py b/PhysicsTools/NanoAOD/python/custom_btv_cff.py index b4e3029c9da86..7903493116b88 100644 --- a/PhysicsTools/NanoAOD/python/custom_btv_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_btv_cff.py @@ -553,12 +553,8 @@ def add_BTV(process, addAK4=False, addAK8=False, scheme="btvSF"): process.customizeJetTask.add(process.customFatJetExtTable) process.customizeJetTask.add(process.customSubJetExtTable) - if runOnMC: - process.customizeJetTask.add(process.customSubJetMCExtTable) - ## customize BTV GenTable - if runOnMC: - customize_BTV_GenTable(process) + # From https://github.com/cms-jet/PFNano/blob/13_0_7_from124MiniAOD/python/addPFCands_cff.py def addPFCands(process, allPF = False, addAK4=False, addAK8=False): @@ -650,65 +646,6 @@ def addPFCands(process, allPF = False, addAK4=False, addAK8=False): if addAK4: process.customizedPFCandsTask.add(process.customAK4ConstituentsTable) - if runOnMC: - - process.genJetsAK8Constituents = cms.EDProducer("GenJetPackedConstituentPtrSelector", - src = cms.InputTag("slimmedGenJetsAK8"), - cut = cms.string("pt > 100.") - ) - - - process.genJetsAK4Constituents = process.genJetsAK8Constituents.clone( - src = cms.InputTag("slimmedGenJets"), - cut = cms.string("pt > 20") - ) - if allPF: - genCandInput = cms.InputTag("packedGenParticles") - elif addAK4 and not addAK8: - genCandList = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents")) - genCandInput = cms.InputTag("genJetsConstituents") - process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - elif addAK8 and not addAK4: - genCandList = cms.VInputTag(cms.InputTag("genJetsAK8Constituents", "constituents")) - genCandInput = cms.InputTag("genJetsConstituents") - process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - else: - genCandList = cms.VInputTag(cms.InputTag("genJetsAK4Constituents", "constituents"), cms.InputTag("genJetsAK8Constituents", "constituents")) - genCandInput = cms.InputTag("genJetsConstituents") - process.genJetsConstituents = cms.EDProducer("PackedGenParticlePtrMerger", src = genCandList, skipNulls = cms.bool(True), warnOnSkip = cms.bool(True)) - process.genJetsParticleTable = cms.EDProducer("SimpleCandidateFlatTableProducer", - src = genCandInput, - cut = cms.string(""), #we should not filter after pruning - name= cms.string("GenCands"), - doc = cms.string("interesting gen particles from AK4 and AK8 jets"), - singleton = cms.bool(False), # the number of entries is variable - extension = cms.bool(False), # this is the main table for the AK8 constituents - variables = cms.PSet(CandVars - ) - ) - process.genAK8ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", - candidates = genCandInput, - jets = cms.InputTag("genJetsAK8Constituents"), # Note: The name has "Constituents" in it, but these are the jets - name = cms.string("GenFatJetCands"), - nameSV = cms.string("GenFatJetSVs"), - idx_name = cms.string("pFCandsIdx"), - idx_nameSV = cms.string("sVIdx"), - readBtag = cms.bool(False)) - process.genAK4ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", - candidates = genCandInput, - jets = cms.InputTag("genJetsAK4Constituents"), # Note: The name has "Constituents" in it, but these are the jets - name = cms.string("GenJetCands"), - nameSV = cms.string("GenJetSVs"), - idx_name = cms.string("pFCandsIdx"), - idx_nameSV = cms.string("sVIdx"), - readBtag = cms.bool(False)) - process.customizedPFCandsTask.add(process.genJetsAK4Constituents) #Note: For gen need to add jets to the process to keep pt cuts. - process.customizedPFCandsTask.add(process.genJetsAK8Constituents) - if not allPF: - process.customizedPFCandsTask.add(process.genJetsConstituents) - process.customizedPFCandsTask.add(process.genJetsParticleTable) - process.customizedPFCandsTask.add(process.genAK8ConstituentsTable) - process.customizedPFCandsTask.add(process.genAK4ConstituentsTable) return process @@ -727,14 +664,17 @@ def BTVCustomNanoAOD(process): addPFCands(process,btvNano_switch.btvNano_addallPF_switch,btvNano_switch.btvNano_addAK4_switch,btvNano_switch.btvNano_addAK8_switch) add_BTV(process, btvNano_switch.btvNano_addAK4_switch,btvNano_switch.btvNano_addAK8_switch,btvNano_switch.TaggerInput) ### for MC - customize_BTV_GenTable(process) if btvNano_switch.btvNano_addallPF_switch: + #process.allPFPFCandsMCSequence = allPFPFCandsMCSequence process.nanoSequenceMC+=allPFPFCandsMCSequence else: if btvNano_switch.btvNano_addAK4_switch and btvNano_switch.btvNano_addAK8_switch : - process.nanoSequenceMC+=process.nanoSequenceMC+ak4ak8PFCandsMCSequence + #process.ak4ak8PFCandsMCSequence = ak4ak8PFCandsMCSequence + process.nanoSequenceMC+=ak4ak8PFCandsMCSequence elif btvNano_switch.btvNano_addAK4_switch and not btvNano_switch.btvNano_addAK8_switch : + #process.ak4onlyPFCandsMCSequence = ak4onlyPFCandsMCSequence process.nanoSequenceMC+=ak4onlyPFCandsMCSequence elif not btvNano_switch.btvNano_addAK4_switch and btvNano_switch.btvNano_addAK8_switch: + #process.ak8onlyPFCandsMCSequence= ak8onlyPFCandsMCSequence process.nanoSequenceMC+=ak8onlyPFCandsMCSequence return process From e77460357384b69f68186ab4a94a98982b5d4a4c Mon Sep 17 00:00:00 2001 From: Ming-Yan Lee Date: Fri, 29 Mar 2024 16:17:32 +0100 Subject: [PATCH 8/9] fix: modify BTV sequence --- Configuration/PyReleaseValidation/python/relval_nano.py | 7 +++++-- PhysicsTools/NanoAOD/python/btvMC_cff.py | 8 ++++---- PhysicsTools/NanoAOD/python/custom_btv_cff.py | 8 +++----- PhysicsTools/NanoAOD/python/nanoDQM_cfi.py | 1 + 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/Configuration/PyReleaseValidation/python/relval_nano.py b/Configuration/PyReleaseValidation/python/relval_nano.py index 96731cf90cfd8..0312490aae3c7 100644 --- a/Configuration/PyReleaseValidation/python/relval_nano.py +++ b/Configuration/PyReleaseValidation/python/relval_nano.py @@ -176,6 +176,9 @@ def subnext(self): steps['EGMNano_mc13.0'] = merge([{'-s':'NANO:@EGM,DQM:@nanoAODDQM', '-n' : '1000'}, steps['NANO_mc13.0']]) +steps['BTVNANO_data13.0']=merge([{'-s' : 'NANO:@BTV', + '-n' : '1000'}, + steps['NANO_data13.0']]) steps['jmeNano_data13.0'] = merge([{'-s':'NANO:@JME', '-n' : '1000'}, steps['NANO_data13.0']]) @@ -203,6 +206,7 @@ def subnext(self): steps['NANO_mc13.2']]) + steps['jmeNANO_mc13.2']=merge([{'-s' : 'NANO:@JME ', '-n' : '1000'}, steps['NANO_mc13.2']]) @@ -210,8 +214,7 @@ def subnext(self): '-n' : '1000'}, steps['NANO_mc13.2']]) - -steps['BTVNANO_mc13.2']=merge([{'-s' : 'NANO:@PHYS+@BTV', +steps['BTVNANO_mc13.2']=merge([{'-s' : 'NANO:@BTV', '-n' : '1000'}, steps['NANO_mc13.2']]) diff --git a/PhysicsTools/NanoAOD/python/btvMC_cff.py b/PhysicsTools/NanoAOD/python/btvMC_cff.py index 18bd5ff33448e..0a72694f96112 100644 --- a/PhysicsTools/NanoAOD/python/btvMC_cff.py +++ b/PhysicsTools/NanoAOD/python/btvMC_cff.py @@ -122,7 +122,7 @@ ) ) ak8onlygenAK8ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", - candidates = cms.InputTag("genJetsConstituents"), + candidates = cms.InputTag("ak8onlygenJetsConstituents"), jets = cms.InputTag("genJetsAK8Constituents"), # Note: The name has "Constituents" in it, but these are the jets name = cms.string("GenFatJetCands"), nameSV = cms.string("GenFatJetSVs"), @@ -130,7 +130,7 @@ idx_nameSV = cms.string("sVIdx"), readBtag = cms.bool(False)) ak4onlygenAK4ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", - candidates = cms.InputTag("genJetsConstituents"), + candidates = cms.InputTag("ak4onlygenJetsConstituents"), jets = cms.InputTag("genJetsAK4Constituents"), # Note: The name has "Constituents" in it, but these are the jets name = cms.string("GenJetCands"), nameSV = cms.string("GenJetSVs"), @@ -138,7 +138,7 @@ idx_nameSV = cms.string("sVIdx"), readBtag = cms.bool(False)) ak4ak8genAK4ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", - candidates = cms.InputTag("genJetsConstituents"), + candidates = cms.InputTag("ak4ak8genJetsConstituents"), jets = cms.InputTag("genJetsAK4Constituents"), # Note: The name has "Constituents" in it, but these are the jets name = cms.string("GenJetCands"), nameSV = cms.string("GenJetSVs"), @@ -147,7 +147,7 @@ readBtag = cms.bool(False)) ak4ak8genAK8ConstituentsTable = cms.EDProducer("GenJetConstituentTableProducer", - candidates = cms.InputTag("genJetsConstituents"), + candidates = cms.InputTag("ak4ak8genJetsConstituents"), jets = cms.InputTag("genJetsAK8Constituents"), # Note: The name has "Constituents" in it, but these are the jets name = cms.string("GenFatJetCands"), nameSV = cms.string("GenFatJetSVs"), diff --git a/PhysicsTools/NanoAOD/python/custom_btv_cff.py b/PhysicsTools/NanoAOD/python/custom_btv_cff.py index 7903493116b88..323e3e458d20a 100644 --- a/PhysicsTools/NanoAOD/python/custom_btv_cff.py +++ b/PhysicsTools/NanoAOD/python/custom_btv_cff.py @@ -6,7 +6,7 @@ from PhysicsTools.PatAlgos.tools.helpers import addToProcessAndTask, getPatAlgosToolsTask from PhysicsTools.NanoAOD.common_cff import Var, CandVars from PhysicsTools.NanoAOD.simpleCandidateFlatTableProducer_cfi import simpleCandidateFlatTableProducer -from PhysicsTools.NanoAOD.btvMC_cff import * +from PhysicsTools.NanoAOD.btvMC_cff import allPFPFCandsMCSequence,ak4ak8PFCandsMCSequence,ak8onlyPFCandsMCSequence,ak4onlyPFCandsMCSequence ## Move PFNano (https://github.com/cms-jet/PFNano/) to NanoAOD ## From: https://github.com/cms-jet/PFNano/blob/13_0_7_from124MiniAOD/python/addBTV.py @@ -663,18 +663,16 @@ def addPFCands(process, allPF = False, addAK4=False, addAK8=False): def BTVCustomNanoAOD(process): addPFCands(process,btvNano_switch.btvNano_addallPF_switch,btvNano_switch.btvNano_addAK4_switch,btvNano_switch.btvNano_addAK8_switch) add_BTV(process, btvNano_switch.btvNano_addAK4_switch,btvNano_switch.btvNano_addAK8_switch,btvNano_switch.TaggerInput) + process.load("PhysicsTools.NanoAOD.btvMC_cff") ### for MC if btvNano_switch.btvNano_addallPF_switch: - #process.allPFPFCandsMCSequence = allPFPFCandsMCSequence process.nanoSequenceMC+=allPFPFCandsMCSequence else: if btvNano_switch.btvNano_addAK4_switch and btvNano_switch.btvNano_addAK8_switch : - #process.ak4ak8PFCandsMCSequence = ak4ak8PFCandsMCSequence process.nanoSequenceMC+=ak4ak8PFCandsMCSequence elif btvNano_switch.btvNano_addAK4_switch and not btvNano_switch.btvNano_addAK8_switch : - #process.ak4onlyPFCandsMCSequence = ak4onlyPFCandsMCSequence process.nanoSequenceMC+=ak4onlyPFCandsMCSequence elif not btvNano_switch.btvNano_addAK4_switch and btvNano_switch.btvNano_addAK8_switch: - #process.ak8onlyPFCandsMCSequence= ak8onlyPFCandsMCSequence process.nanoSequenceMC+=ak8onlyPFCandsMCSequence + return process diff --git a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py index 0037e673116c8..6634327de7b58 100644 --- a/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py +++ b/PhysicsTools/NanoAOD/python/nanoDQM_cfi.py @@ -423,6 +423,7 @@ Plot1D('btagPNetCvNotB', 'btagPNetCvNotB', 20, 0, 1, 'ParticleNet C vs notB'), Plot1D('btagPNetCvL', 'btagPNetCvL', 20, 0, 1, 'ParticleNet c vs. light (udsg) discriminator'), Plot1D('btagPNetCvB', 'btagPNetCvB', 20, 0, 1, 'ParticleNet c vs. b discriminator'), + Plot1D('btagPNetCvNotB', 'btagPNetCvNotB', 20, 0, 1, 'ParticleNet C vs notB discriminator'), Plot1D('btagPNetQvG', 'btagPNetQvG', 20, 0, 1, 'ParticleNet quark (udsbc) vs. gluon discriminator'), Plot1D('btagPNetTauVJet', 'btagPNetTauVJet', 20, 0, 1, 'ParticleNet tau vs. jet discriminator'), Plot1D('PNetRegPtRawCorr', 'PNetRegPtRawCorr', 20, 0, 2, 'ParticleNet visible pT regression, correction relative to raw pT'), From 12bde1f854a7d910a14d525462dbdb10ceb9bd5d Mon Sep 17 00:00:00 2001 From: Ming-Yan Lee Date: Wed, 3 Apr 2024 12:24:01 +0200 Subject: [PATCH 9/9] fix: reformat autonano --- .../PyReleaseValidation/python/relval_nano.py | 32 +++---------------- PhysicsTools/NanoAOD/python/autoNANO.py | 1 - 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/Configuration/PyReleaseValidation/python/relval_nano.py b/Configuration/PyReleaseValidation/python/relval_nano.py index 0312490aae3c7..a31c7fe3131ec 100644 --- a/Configuration/PyReleaseValidation/python/relval_nano.py +++ b/Configuration/PyReleaseValidation/python/relval_nano.py @@ -152,7 +152,6 @@ def subnext(self): steps['NANO_data13.0_prompt']=merge([{'--customise' : 'PhysicsTools/NanoAOD/nano_cff.nanoL1TrigObjCustomize', '-n' : '1000'}, steps['NANO_data13.0']]) - steps['muDPGNANO_data13.0']=merge([{'-s' : 'RAW2DIGI,NANO:@MUDPG', '--conditions':'auto:run3_data', '-n' : '100', @@ -187,10 +186,6 @@ def subnext(self): '-n' : '1000'}, steps['NANO_data13.0']]) -steps['BTVNANO_data13.0']=merge([{'-s' : 'NANO:@PHYS+@BTV', - '-n' : '1000'}, - steps['NANO_data13.0']]) - ###current release cycle workflows : 13.2 steps['TTBarMINIAOD13.2'] = {'INPUT':InputInfo(location='STD', dataSet='/RelValTTbar_14TeV/CMSSW_13_2_0-PU_131X_mcRun3_2023_realistic_v9-v1/MINIAODSIM')} @@ -199,34 +194,22 @@ def subnext(self): '--conditions':'auto:phase1_2022_realistic'}, _NANO_mc]) - steps['muPOGNANO_mc13.2']=merge([{'-s' : 'NANO:@MUPOG,DQM:@nanoAODDQM', '-n' : '1000'}, + steps['NANO_mc13.2']]) steps['EGMNano_mc13.2'] = merge([{'-s':'NANO:@EGM,DQM:@nanoAODDQM', '-n' : '1000'}, steps['NANO_mc13.2']]) - - -steps['jmeNANO_mc13.2']=merge([{'-s' : 'NANO:@JME ', '-n' : '1000'}, - steps['NANO_mc13.2']]) - -steps['lepTimeLifeNANO_mc13.2']=merge([{'-s' : 'NANO:@LepTimeLife,DQM:@nanoAODDQM', - '-n' : '1000'}, - steps['NANO_mc13.2']]) - steps['BTVNANO_mc13.2']=merge([{'-s' : 'NANO:@BTV', '-n' : '1000'}, steps['NANO_mc13.2']]) -steps['lepTimeLifeNANO_mc13.2']=merge([{'-s' : 'NANO:@LepTimeLife,DQM:@nanoAODDQM', '-n' : '1000'}, - steps['NANO_mc13.2']]) - steps['jmeNANO_mc13.2']=merge([{'-s' : 'NANO:@JME ', '-n' : '1000'}, - steps['NANO_mc13.2']]) + steps['NANO_mc13.2']]) steps['lepTimeLifeNANO_mc13.2']=merge([{'-s' : 'NANO:@LepTimeLife,DQM:@nanoAODDQM', '-n' : '1000'}, - steps['NANO_mc13.2']]) + steps['NANO_mc13.2']]) ##13.X INPUT steps['ScoutingPFRun32022DRAW13.X']={'INPUT':InputInfo(dataSet='/ScoutingPFRun3/Run2022D-v1/RAW',label='2022D',events=100000,location='STD', ls=Run2022D)} @@ -278,15 +261,11 @@ def subnext(self): workflows[_wfn()] = ['NANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'NANO_data13.0_prompt', 'HRV_NANO_data']] workflows[_wfn()] = ['muDPGNANO130Xrun3', ['ZMuSkim2023DRAWRECO13.0', 'muDPGNANO_data13.0']] workflows[_wfn()] = ['muDPGNANOBkg130Xrun3', ['ZeroBias2023DRAW13.0', 'muDPGNANOBkg_data13.0']] - - workflows[_wfn()] = ['muPOGNANO130Xrun3', ['MuonEG2023MINIAOD13.0', 'muPOGNANO_data13.0']] workflows[_wfn()] = ['EGMNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'EGMNano_data13.0']] workflows[_wfn()] = ['jmeNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'jmeNano_data13.0']] workflows[_wfn()] = ['lepTimeLifeNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'lepTimeLifeNANO_data13.0']] -workflows[_wfn()] = ['EGMNANOdata130Xrun3', ['MuonEG2023MINIAOD13.0', 'EGMNano_data13.0']] - -workflows[_wfn()] = ['BTVNANO_data13.0', ['MuonEG2023MINIAOD13.0', 'BTVNANO_data13.0']] +workflows[_wfn()] = ['BTVNANO_data130Xrun3', ['MuonEG2023MINIAOD13.0', 'BTVNANO_data13.0']] _wfn.next() ################ @@ -296,8 +275,7 @@ def subnext(self): workflows[_wfn()] = ['EGMNANOmc132X', ['TTBarMINIAOD13.2', 'EGMNano_mc13.2']] workflows[_wfn()] = ['jmeNANOmc132X', ['TTBarMINIAOD13.2', 'jmeNANO_mc13.2']] workflows[_wfn()] = ['lepTimeLifeNANOmc132X', ['TTBarMINIAOD13.2', 'lepTimeLifeNANO_mc13.2']] -workflows[_wfn()] = ['EGMNANOmc132X', ['TTBarMINIAOD13.2', 'EGMNano_mc13.2']] -workflows[_wfn()] = ['BTVNANO_mc13.2', ['TTBarMINIAOD13.2', 'BTVNANO_mc13.2']] +workflows[_wfn()] = ['BTVNANO_mc132X', ['TTBarMINIAOD13.2', 'BTVNANO_mc13.2']] _wfn.next() ################ diff --git a/PhysicsTools/NanoAOD/python/autoNANO.py b/PhysicsTools/NanoAOD/python/autoNANO.py index 0ed68007ab840..d995aff2b1fd9 100644 --- a/PhysicsTools/NanoAOD/python/autoNANO.py +++ b/PhysicsTools/NanoAOD/python/autoNANO.py @@ -36,7 +36,6 @@ def expandNanoMapping(seqList, mapping, key): # Muon POG flavours : add tables through customize, supposed to be combined with PHYS 'MUPOG' : { 'sequence': '@PHYS', 'customize' : '@PHYS+PhysicsTools/NanoAOD/custom_muon_cff.PrepMuonCustomNanoAOD'}, - # MUDPG flavours: use their own sequence 'MUDPG' : {'sequence': 'DPGAnalysis/MuonTools/muNtupleProducer_cff.muDPGNanoProducer', 'customize': 'DPGAnalysis/MuonTools/muNtupleProducer_cff.muDPGNanoCustomize'},