diff --git a/DataFormats/BTauReco/interface/ChargedCandidateFeatures.h b/DataFormats/BTauReco/interface/ChargedCandidateFeatures.h index 82e02f7759bb3..66724bce0b636 100644 --- a/DataFormats/BTauReco/interface/ChargedCandidateFeatures.h +++ b/DataFormats/BTauReco/interface/ChargedCandidateFeatures.h @@ -6,6 +6,9 @@ namespace btagbtvdeep { class ChargedCandidateFeatures { public: float ptrel; + float ptrel_noclip; + float erel; + float etarel; float puppiw; float vtx_ass; @@ -22,6 +25,14 @@ namespace btagbtvdeep { float btagPf_trackJetDistVal; + float drsubjet1; + float drsubjet2; + float dxy; + float dxysig; + float dz; + float dzsig; + float deltaR; + float chi2; float quality; diff --git a/DataFormats/BTauReco/interface/DeepDoubleXFeatures.h b/DataFormats/BTauReco/interface/DeepDoubleXFeatures.h index df962ef0c7220..e07b9a2bc06d3 100644 --- a/DataFormats/BTauReco/interface/DeepDoubleXFeatures.h +++ b/DataFormats/BTauReco/interface/DeepDoubleXFeatures.h @@ -7,6 +7,7 @@ #include "DataFormats/BTauReco/interface/SecondaryVertexFeatures.h" #include "DataFormats/BTauReco/interface/BoostedDoubleSVTagInfoFeatures.h" #include "DataFormats/BTauReco/interface/ChargedCandidateFeatures.h" +#include "DataFormats/BTauReco/interface/NeutralCandidateFeatures.h" namespace btagbtvdeep { @@ -19,10 +20,12 @@ namespace btagbtvdeep { JetFeatures jet_features; BoostedDoubleSVTagInfoFeatures tag_info_features; - std::vector sv_features; - std::vector c_pf_features; + std::vector n_pf_features; + + std::vector sv_features; + std::size_t npv; // used by deep flavour private: diff --git a/DataFormats/BTauReco/interface/NeutralCandidateFeatures.h b/DataFormats/BTauReco/interface/NeutralCandidateFeatures.h index 67041ecbda831..afeb6e6751180 100644 --- a/DataFormats/BTauReco/interface/NeutralCandidateFeatures.h +++ b/DataFormats/BTauReco/interface/NeutralCandidateFeatures.h @@ -6,9 +6,15 @@ namespace btagbtvdeep { class NeutralCandidateFeatures { public: float ptrel; + float ptrel_noclip; + float erel; + + float drsubjet1; + float drsubjet2; float puppiw; float deltaR; + float deltaR_noclip; float isGamma; float hadFrac; diff --git a/DataFormats/BTauReco/interface/SecondaryVertexFeatures.h b/DataFormats/BTauReco/interface/SecondaryVertexFeatures.h index ff07070888ac7..655b7d1fa0e1b 100644 --- a/DataFormats/BTauReco/interface/SecondaryVertexFeatures.h +++ b/DataFormats/BTauReco/interface/SecondaryVertexFeatures.h @@ -6,6 +6,7 @@ namespace btagbtvdeep { class SecondaryVertexFeatures { public: float pt; + float ptrel; float mass; float deltaR; diff --git a/DataFormats/BTauReco/src/classes_def.xml b/DataFormats/BTauReco/src/classes_def.xml index 962cc282cb695..69836a6d308a9 100644 --- a/DataFormats/BTauReco/src/classes_def.xml +++ b/DataFormats/BTauReco/src/classes_def.xml @@ -409,16 +409,19 @@ - + + - + + - + + @@ -432,7 +435,8 @@ - + + diff --git a/PhysicsTools/PatAlgos/python/recoLayer0/bTagging_cff.py b/PhysicsTools/PatAlgos/python/recoLayer0/bTagging_cff.py index 71f4bec0cdc71..f15f2d168ea34 100644 --- a/PhysicsTools/PatAlgos/python/recoLayer0/bTagging_cff.py +++ b/PhysicsTools/PatAlgos/python/recoLayer0/bTagging_cff.py @@ -206,6 +206,12 @@ , 'pfMassIndependentDeepDoubleCvLJetTags:probHcc' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] , 'pfMassIndependentDeepDoubleCvBJetTags:probHbb' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] , 'pfMassIndependentDeepDoubleCvBJetTags:probHcc' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] + , 'pfMassIndependentDeepDoubleBvLV2JetTags:probQCD' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] + , 'pfMassIndependentDeepDoubleBvLV2JetTags:probHbb' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] + , 'pfMassIndependentDeepDoubleCvLV2JetTags:probQCD' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] + , 'pfMassIndependentDeepDoubleCvLV2JetTags:probHcc' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] + , 'pfMassIndependentDeepDoubleCvBV2JetTags:probHbb' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] + , 'pfMassIndependentDeepDoubleCvBV2JetTags:probHcc' : [["pfDeepDoubleXTagInfos"], ['pfBoostedDoubleSVAK8TagInfos', "pfImpactParameterAK8TagInfos", 'pfInclusiveSecondaryVertexFinderAK8TagInfos']] } # meta-taggers are simple arithmetic on top of other taggers, they are stored here diff --git a/RecoBTag/FeatureTools/interface/ChargedCandidateConverter.h b/RecoBTag/FeatureTools/interface/ChargedCandidateConverter.h index 6c3ad093271e8..93447c3ef9aac 100644 --- a/RecoBTag/FeatureTools/interface/ChargedCandidateConverter.h +++ b/RecoBTag/FeatureTools/interface/ChargedCandidateConverter.h @@ -30,7 +30,12 @@ namespace btagbtvdeep { trackSip3dVal = -trackSip3dVal; } + c_pf_features.deltaR = reco::deltaR(*c_pf, jet); c_pf_features.ptrel = catch_infs_and_bound(c_pf->pt() / jet.pt(), 0, -1, 0, -1); + c_pf_features.ptrel_noclip = c_pf->pt() / jet.pt(); + c_pf_features.erel = c_pf->energy() / jet.energy(); + const float etasign = jet.eta() > 0 ? 1 : -1; + c_pf_features.etarel = etasign * (c_pf->eta() - jet.eta()); c_pf_features.btagPf_trackEtaRel = catch_infs_and_bound(track_info.getTrackEtaRel(), 0, -5, 15); c_pf_features.btagPf_trackPtRel = catch_infs_and_bound(track_info.getTrackPtRel(), 0, -1, 4); @@ -45,6 +50,26 @@ namespace btagbtvdeep { c_pf_features.btagPf_trackJetDistVal = catch_infs_and_bound(track_info.getTrackJetDistVal(), 0, -20, 1); c_pf_features.drminsv = catch_infs_and_bound(drminpfcandsv, 0, -1. * jetR, 0, -1. * jetR); + + // subjet related + const auto* patJet = dynamic_cast(&jet); + if (!patJet) { + throw edm::Exception(edm::errors::InvalidReference) << "Input is not a pat::Jet."; + } + + if (patJet->nSubjetCollections() > 0) { + auto subjets = patJet->subjets(); + // sort by pt + std::sort(subjets.begin(), subjets.end(), [](const edm::Ptr& p1, const edm::Ptr& p2) { + return p1->pt() > p2->pt(); + }); + c_pf_features.drsubjet1 = !subjets.empty() ? reco::deltaR(*c_pf, *subjets.at(0)) : -1; + c_pf_features.drsubjet2 = subjets.size() > 1 ? reco::deltaR(*c_pf, *subjets.at(1)) : -1; + } else { + // AK4 jets don't have subjets + c_pf_features.drsubjet1 = -1; + c_pf_features.drsubjet2 = -1; + } } void packedCandidateToFeatures(const pat::PackedCandidate* c_pf, diff --git a/RecoBTag/FeatureTools/interface/NeutralCandidateConverter.h b/RecoBTag/FeatureTools/interface/NeutralCandidateConverter.h index 4bbb7649a974b..2055b72dbd385 100644 --- a/RecoBTag/FeatureTools/interface/NeutralCandidateConverter.h +++ b/RecoBTag/FeatureTools/interface/NeutralCandidateConverter.h @@ -30,8 +30,31 @@ namespace btagbtvdeep { const float& drminpfcandsv, const float& jetR, NeutralCandidateFeatures& n_pf_features) { + const auto* patJet = dynamic_cast(&jet); + + if (!patJet) { + throw edm::Exception(edm::errors::InvalidReference) << "Input is not a pat::Jet."; + } + // Do Subjets + if (patJet->nSubjetCollections() > 0) { + auto subjets = patJet->subjets(); + // sort by pt + std::sort(subjets.begin(), subjets.end(), [](const edm::Ptr& p1, const edm::Ptr& p2) { + return p1->pt() > p2->pt(); + }); + n_pf_features.drsubjet1 = !subjets.empty() ? reco::deltaR(*n_pf, *subjets.at(0)) : -1; + n_pf_features.drsubjet2 = subjets.size() > 1 ? reco::deltaR(*n_pf, *subjets.at(1)) : -1; + } else { + n_pf_features.drsubjet1 = -1; + n_pf_features.drsubjet2 = -1; + } + + // Jet relative vars n_pf_features.ptrel = catch_infs_and_bound(n_pf->pt() / jet.pt(), 0, -1, 0, -1); + n_pf_features.ptrel_noclip = n_pf->pt() / jet.pt(); n_pf_features.deltaR = catch_infs_and_bound(reco::deltaR(*n_pf, jet), 0, -0.6, 0, -0.6); + n_pf_features.deltaR_noclip = reco::deltaR(*n_pf, jet); + n_pf_features.erel = n_pf->energy() / jet.energy(); n_pf_features.isGamma = 0; if (std::abs(n_pf->pdgId()) == 22) n_pf_features.isGamma = 1; diff --git a/RecoBTag/FeatureTools/plugins/DeepDoubleXTagInfoProducer.cc b/RecoBTag/FeatureTools/plugins/DeepDoubleXTagInfoProducer.cc index 83342dbcd67f0..ebf3654fd8a3c 100644 --- a/RecoBTag/FeatureTools/plugins/DeepDoubleXTagInfoProducer.cc +++ b/RecoBTag/FeatureTools/plugins/DeepDoubleXTagInfoProducer.cc @@ -22,6 +22,7 @@ #include "DataFormats/BTauReco/interface/DeepDoubleXTagInfo.h" #include "RecoBTag/FeatureTools/interface/BoostedDoubleSVTagInfoConverter.h" +#include "RecoBTag/FeatureTools/interface/NeutralCandidateConverter.h" #include "RecoBTag/FeatureTools/interface/ChargedCandidateConverter.h" #include "RecoBTag/FeatureTools/interface/JetConverter.h" #include "RecoBTag/FeatureTools/interface/SecondaryVertexConverter.h" @@ -119,6 +120,8 @@ void DeepDoubleXTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet // reco jet reference (use as much as possible) const auto& jet = jets->at(jet_n); + const auto* pf_jet = dynamic_cast(&jet); + const auto* pat_jet = dynamic_cast(&jet); edm::RefToBase jet_ref(jets, jet_n); if (jet.pt() > min_jet_pt_) { @@ -175,7 +178,8 @@ void DeepDoubleXTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet math::XYZVector jet_dir = jet.momentum().Unit(); GlobalVector jet_ref_track_dir(jet.px(), jet.py(), jet.pz()); - std::vector> c_sorted; + std::vector> c_sorted, n_sorted; + std::vector n_indexes; // to cache the TrackInfo std::map trackinfos; @@ -205,9 +209,9 @@ void DeepDoubleXTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet } } + std::sort(daughters.begin(), daughters.end(), [](const auto& a, const auto& b) { return a->pt() > b->pt(); }); for (unsigned int i = 0; i < daughters.size(); i++) { auto const* cand = daughters.at(i); - if (cand) { // candidates under 950MeV (configurable) are not considered // might change if we use also white-listing @@ -220,35 +224,51 @@ void DeepDoubleXTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet trackinfo.getTrackSip2dSig(), -btagbtvdeep::mindrsvpfcand(svs_unsorted, cand, jet_radius_), cand->pt() / jet.pt()); + } else { + n_sorted.emplace_back( + i, -1, -btagbtvdeep::mindrsvpfcand(svs_unsorted, cand, jet_radius_), cand->pt() / jet.pt()); + n_indexes.push_back(i); } } } - // sort collections (open the black-box if you please) + // sort collections in added order of priority std::sort(c_sorted.begin(), c_sorted.end(), btagbtvdeep::SortingClass::compareByABCInv); + std::sort(n_sorted.begin(), n_sorted.end(), btagbtvdeep::SortingClass::compareByABCInv); - std::vector c_sortedindices; + std::vector c_sortedindices, n_sortedindices; // this puts 0 everywhere and the right position in ind c_sortedindices = btagbtvdeep::invertSortingVector(c_sorted); + n_sortedindices = btagbtvdeep::invertSortingVector(n_sorted); // set right size to vectors features.c_pf_features.clear(); features.c_pf_features.resize(c_sorted.size()); + features.n_pf_features.clear(); + features.n_pf_features.resize(n_sorted.size()); for (unsigned int i = 0; i < daughters.size(); i++) { auto const* cand = daughters.at(i); if (cand) { // candidates under 950MeV are not considered // might change if we use also white-listing - if (cand->pt() < 0.95) + if (cand->pt() < min_candidate_pt_) continue; + auto packed_cand = dynamic_cast(cand); + auto reco_cand = dynamic_cast(cand); + + // need some edm::Ptr or edm::Ref if reco candidates + reco::PFCandidatePtr reco_ptr; + if (pf_jet) { + reco_ptr = pf_jet->getPFConstituent(i); + } else if (pat_jet && reco_cand) { + reco_ptr = pat_jet->getPFConstituent(i); + } - // get PUPPI weight from value map float puppiw = 1.0; // fallback value float drminpfcandsv = btagbtvdeep::mindrsvpfcand(svs_unsorted, cand, jet_radius_); - if (cand->charge() != 0) { // is charged candidate auto entry = c_sortedindices.at(i); @@ -256,12 +276,9 @@ void DeepDoubleXTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet auto& trackinfo = trackinfos.at(i); // get_ref to vector element auto& c_pf_features = features.c_pf_features.at(entry); - // fill feature structure - auto packed_cand = dynamic_cast(cand); - auto reco_cand = dynamic_cast(cand); if (packed_cand) { btagbtvdeep::packedCandidateToFeatures( - packed_cand, jet, trackinfo, drminpfcandsv, static_cast(jet_radius_), c_pf_features); + packed_cand, *pat_jet, trackinfo, drminpfcandsv, static_cast(jet_radius_), c_pf_features); } else if (reco_cand) { // get vertex association quality int pv_ass_quality = 0; // fallback value @@ -288,6 +305,19 @@ void DeepDoubleXTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet pv, c_pf_features); } + } else { + // is neutral candidate + auto entry = n_sortedindices.at(i); + // get_ref to vector element + auto& n_pf_features = features.n_pf_features.at(entry); + // // fill feature structure + if (packed_cand) { + btagbtvdeep::packedCandidateToFeatures( + packed_cand, *pat_jet, drminpfcandsv, static_cast(jet_radius_), n_pf_features); + } else if (reco_cand) { + btagbtvdeep::recoCandidateToFeatures( + reco_cand, jet, drminpfcandsv, static_cast(jet_radius_), puppiw, n_pf_features); + } } } } diff --git a/RecoBTag/FeatureTools/src/ChargedCandidateConverter.cc b/RecoBTag/FeatureTools/src/ChargedCandidateConverter.cc index 03139972cc5c0..c05455d398c08 100644 --- a/RecoBTag/FeatureTools/src/ChargedCandidateConverter.cc +++ b/RecoBTag/FeatureTools/src/ChargedCandidateConverter.cc @@ -27,6 +27,11 @@ namespace btagbtvdeep { c_pf_features.chi2 = catch_infs_and_bound(-1, 300, -1, 300); c_pf_features.quality = (1 << reco::TrackBase::loose); } + + c_pf_features.dxy = catch_infs(c_pf->dxy()); + c_pf_features.dz = catch_infs(c_pf->dz()); + c_pf_features.dxysig = c_pf->bestTrack() ? catch_infs(c_pf->dxy() / c_pf->dxyError()) : 0; + c_pf_features.dzsig = c_pf->bestTrack() ? catch_infs(c_pf->dz() / c_pf->dzError()) : 0; } void recoCandidateToFeatures(const reco::PFCandidate* c_pf, @@ -47,6 +52,16 @@ namespace btagbtvdeep { const auto& pseudo_track = (c_pf->bestTrack()) ? *c_pf->bestTrack() : reco::Track(); c_pf_features.chi2 = catch_infs_and_bound(std::floor(pseudo_track.normalizedChi2()), 300, -1, 300); c_pf_features.quality = quality_from_pfcand(*c_pf); + + // To be implemented if FatJet tag becomes RECO compatible + // const auto *trk = + // float dz = + // float dxy = + + // c_pf_features.dxy = + // c_pf_features.dz = + // c_pf_features.dxysig = + // c_pf_features.dzsig = } } // namespace btagbtvdeep diff --git a/RecoBTag/FeatureTools/src/SecondaryVertexConverter.cc b/RecoBTag/FeatureTools/src/SecondaryVertexConverter.cc index 7395279faf5f3..78b346840ae0f 100644 --- a/RecoBTag/FeatureTools/src/SecondaryVertexConverter.cc +++ b/RecoBTag/FeatureTools/src/SecondaryVertexConverter.cc @@ -16,6 +16,7 @@ namespace btagbtvdeep { const bool flip) { math::XYZVector jet_dir = jet.momentum().Unit(); sv_features.pt = sv.pt(); + sv_features.ptrel = sv.pt() / jet.pt(); sv_features.deltaR = catch_infs_and_bound(std::fabs(reco::deltaR(sv, jet_dir)) - 0.5, 0, -2, 0); sv_features.mass = sv.mass(); sv_features.ntracks = sv.numberOfDaughters(); diff --git a/RecoBTag/ONNXRuntime/plugins/DeepDoubleXONNXJetTagsProducer.cc b/RecoBTag/ONNXRuntime/plugins/DeepDoubleXONNXJetTagsProducer.cc index f7c5176b199c9..a0c897312bcdb 100644 --- a/RecoBTag/ONNXRuntime/plugins/DeepDoubleXONNXJetTagsProducer.cc +++ b/RecoBTag/ONNXRuntime/plugins/DeepDoubleXONNXJetTagsProducer.cc @@ -16,6 +16,8 @@ #include "PhysicsTools/ONNXRuntime/interface/ONNXRuntime.h" #include +#include +#include using namespace cms::Ort; @@ -41,49 +43,76 @@ class DeepDoubleXONNXJetTagsProducer : public edm::stream::EDProducer flav_names_; std::vector input_names_; std::vector output_names_; + std::string version_; - enum InputIndexes { kGlobal = 0, kChargedCandidates = 1, kVertices = 2 }; - constexpr static unsigned n_features_global_ = 27; - constexpr static unsigned n_cpf_ = 60; - constexpr static unsigned n_features_cpf_ = 8; - constexpr static unsigned n_sv_ = 5; - constexpr static unsigned n_features_sv_ = 2; - const static std::vector input_sizes_; + unsigned n_features_global_; + unsigned n_npf_, n_features_npf_; + unsigned n_cpf_, n_features_cpf_; + unsigned n_sv_, n_features_sv_; + unsigned kGlobal, kNeutralCandidates, kChargedCandidates, kVertices; + std::vector input_sizes_; // hold the input data FloatArrays data_; -}; -const std::vector DeepDoubleXONNXJetTagsProducer::input_sizes_{ - n_features_global_, n_cpf_* n_features_cpf_, n_sv_* n_features_sv_}; + bool debug_ = false; +}; DeepDoubleXONNXJetTagsProducer::DeepDoubleXONNXJetTagsProducer(const edm::ParameterSet& iConfig, const ONNXRuntime* cache) : src_(consumes(iConfig.getParameter("src"))), flav_names_(iConfig.getParameter>("flav_names")), input_names_(iConfig.getParameter>("input_names")), - output_names_(iConfig.getParameter>("output_names")) { + output_names_(iConfig.getParameter>("output_names")), + version_(iConfig.getParameter("version")), + debug_(iConfig.getUntrackedParameter("debugMode", false)) { // get output names from flav_names for (const auto& flav_name : flav_names_) { produces(flav_name); } + if (version_ == "V2") { + n_features_global_ = 5; + n_npf_ = 60; + n_features_npf_ = 8; + n_cpf_ = 40; + n_features_cpf_ = 21; + n_sv_ = 5; + n_features_sv_ = 7; + input_sizes_ = {n_features_global_, n_npf_ * n_features_npf_, n_cpf_ * n_features_cpf_, n_sv_ * n_features_sv_}; + kGlobal = 0; + kNeutralCandidates = 1; + kChargedCandidates = 2; + kVertices = 3; + } else { + n_features_global_ = 27; + n_cpf_ = 60; + n_features_cpf_ = 8; + n_sv_ = 5; + n_features_sv_ = 2; + input_sizes_ = {n_features_global_, n_cpf_ * n_features_cpf_, n_sv_ * n_features_sv_}; + kGlobal = 0; + kChargedCandidates = 1; + kVertices = 2; + } + assert(input_names_.size() == input_sizes_.size()); } DeepDoubleXONNXJetTagsProducer::~DeepDoubleXONNXJetTagsProducer() {} void DeepDoubleXONNXJetTagsProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) { - // pfDeepDoubleBvLJetTags edm::ParameterSetDescription desc; desc.add("src", edm::InputTag("pfDeepDoubleXTagInfos")); desc.add>("input_names", {"input_1", "input_2", "input_3"}); desc.add>("output_names", {}); + desc.add("version", "V1"); using FIP = edm::FileInPath; using PDFIP = edm::ParameterDescription; using PDPSD = edm::ParameterDescription>; using PDCases = edm::ParameterDescriptionCases; + using PDVersion = edm::ParameterDescription; auto flavorCases = [&]() { return "BvL" >> (PDPSD("flav_names", std::vector{"probQCD", "probHbb"}, true) and PDFIP("model_path", FIP("RecoBTag/Combined/data/DeepDoubleX/94X/V01/DDB.onnx"), true)) or @@ -128,6 +157,7 @@ void DeepDoubleXONNXJetTagsProducer::produce(edm::Event& iEvent, const edm::Even auto batch_size = std::count_if( tag_infos->begin(), tag_infos->end(), [](const auto& taginfo) { return !taginfo.features().empty(); }); + std::vector etas_debug; std::vector outputs; if (batch_size > 0) { // init data storage @@ -141,12 +171,40 @@ void DeepDoubleXONNXJetTagsProducer::produce(edm::Event& iEvent, const edm::Even for (const auto& taginfo : *tag_infos) { if (!taginfo.features().empty()) { make_inputs(idx, taginfo); + if (debug_) { + etas_debug.push_back(taginfo.jet()->eta()); + } ++idx; } } + std::sort(input_names_.begin(), input_names_.end()); // input_names order on input is not preserved // run prediction outputs = globalCache()->run(input_names_, data_, output_names_, batch_size)[0]; + + if (debug_) { + // Dump inputs to file + std::ofstream outfile; + outfile.open("test.txt", std::ios_base::app); + outfile << iEvent.id().event() << std::endl; + outfile << batch_size << std::endl; + for (float x : etas_debug) + outfile << x << ' '; + outfile << std::endl; + int _i = 0; + for (const std::vector& v : data_) { + outfile << "input_" << _i << std::endl; + for (float x : v) + outfile << x << ' '; + outfile << std::endl; + _i = _i + 1; + } + outfile << "outputs" << std::endl; + for (float x : outputs) + outfile << x << ' '; + outfile << std::endl; + } + assert(outputs.size() == flav_names_.size() * batch_size); } @@ -189,34 +247,38 @@ void DeepDoubleXONNXJetTagsProducer::make_inputs(unsigned i_jet, const reco::Dee start = ptr; const auto& tag_info_features = features.tag_info_features; *ptr = tag_info_features.jetNTracks; - *(++ptr) = tag_info_features.jetNSecondaryVertices; + if (version_ == "V1") { + *(++ptr) = tag_info_features.jetNSecondaryVertices; + } *(++ptr) = tag_info_features.tau1_trackEtaRel_0; *(++ptr) = tag_info_features.tau1_trackEtaRel_1; - *(++ptr) = tag_info_features.tau1_trackEtaRel_2; - *(++ptr) = tag_info_features.tau2_trackEtaRel_0; - *(++ptr) = tag_info_features.tau2_trackEtaRel_1; - *(++ptr) = tag_info_features.tau2_trackEtaRel_2; - *(++ptr) = tag_info_features.tau1_flightDistance2dSig; - *(++ptr) = tag_info_features.tau2_flightDistance2dSig; + if (version_ == "V1") { + *(++ptr) = tag_info_features.tau1_trackEtaRel_2; + *(++ptr) = tag_info_features.tau2_trackEtaRel_0; + *(++ptr) = tag_info_features.tau2_trackEtaRel_1; + *(++ptr) = tag_info_features.tau2_trackEtaRel_2; + *(++ptr) = tag_info_features.tau1_flightDistance2dSig; + *(++ptr) = tag_info_features.tau2_flightDistance2dSig; + } *(++ptr) = tag_info_features.tau1_vertexDeltaR; - // Note: this variable is not used in the 27-input BDT - // *(++ptr) = tag_info_features.tau2_vertexDeltaR; *(++ptr) = tag_info_features.tau1_vertexEnergyRatio; - *(++ptr) = tag_info_features.tau2_vertexEnergyRatio; - *(++ptr) = tag_info_features.tau1_vertexMass; - *(++ptr) = tag_info_features.tau2_vertexMass; - *(++ptr) = tag_info_features.trackSip2dSigAboveBottom_0; - *(++ptr) = tag_info_features.trackSip2dSigAboveBottom_1; - *(++ptr) = tag_info_features.trackSip2dSigAboveCharm; - *(++ptr) = tag_info_features.trackSip3dSig_0; - *(++ptr) = tag_info_features.tau1_trackSip3dSig_0; - *(++ptr) = tag_info_features.tau1_trackSip3dSig_1; - *(++ptr) = tag_info_features.trackSip3dSig_1; - *(++ptr) = tag_info_features.tau2_trackSip3dSig_0; - *(++ptr) = tag_info_features.tau2_trackSip3dSig_1; - *(++ptr) = tag_info_features.trackSip3dSig_2; - *(++ptr) = tag_info_features.trackSip3dSig_3; - *(++ptr) = tag_info_features.z_ratio; + if (version_ == "V1") { + *(++ptr) = tag_info_features.tau2_vertexEnergyRatio; + *(++ptr) = tag_info_features.tau1_vertexMass; + *(++ptr) = tag_info_features.tau2_vertexMass; + *(++ptr) = tag_info_features.trackSip2dSigAboveBottom_0; + *(++ptr) = tag_info_features.trackSip2dSigAboveBottom_1; + *(++ptr) = tag_info_features.trackSip2dSigAboveCharm; + *(++ptr) = tag_info_features.trackSip3dSig_0; + *(++ptr) = tag_info_features.tau1_trackSip3dSig_0; + *(++ptr) = tag_info_features.tau1_trackSip3dSig_1; + *(++ptr) = tag_info_features.trackSip3dSig_1; + *(++ptr) = tag_info_features.tau2_trackSip3dSig_0; + *(++ptr) = tag_info_features.tau2_trackSip3dSig_1; + *(++ptr) = tag_info_features.trackSip3dSig_2; + *(++ptr) = tag_info_features.trackSip3dSig_3; + *(++ptr) = tag_info_features.z_ratio; + } assert(start + n_features_global_ - 1 == ptr); // c_pf candidates @@ -227,16 +289,60 @@ void DeepDoubleXONNXJetTagsProducer::make_inputs(unsigned i_jet, const reco::Dee ptr = &data_[kChargedCandidates][offset + c_pf_n * n_features_cpf_]; start = ptr; *ptr = c_pf_features.btagPf_trackEtaRel; - *(++ptr) = c_pf_features.btagPf_trackPtRatio; - *(++ptr) = c_pf_features.btagPf_trackPParRatio; - *(++ptr) = c_pf_features.btagPf_trackSip2dVal; - *(++ptr) = c_pf_features.btagPf_trackSip2dSig; - *(++ptr) = c_pf_features.btagPf_trackSip3dVal; - *(++ptr) = c_pf_features.btagPf_trackSip3dSig; - *(++ptr) = c_pf_features.btagPf_trackJetDistVal; + if (version_ == "V1") { + *(++ptr) = c_pf_features.btagPf_trackPtRatio; + *(++ptr) = c_pf_features.btagPf_trackPParRatio; + *(++ptr) = c_pf_features.btagPf_trackSip2dVal; + *(++ptr) = c_pf_features.btagPf_trackSip2dSig; + *(++ptr) = c_pf_features.btagPf_trackSip3dVal; + *(++ptr) = c_pf_features.btagPf_trackSip3dSig; + *(++ptr) = c_pf_features.btagPf_trackJetDistVal; + } else { + *(++ptr) = c_pf_features.btagPf_trackJetDistVal; + *(++ptr) = c_pf_features.btagPf_trackPParRatio; + *(++ptr) = c_pf_features.btagPf_trackPtRatio; + *(++ptr) = c_pf_features.btagPf_trackSip2dSig; + *(++ptr) = c_pf_features.btagPf_trackSip2dVal; + *(++ptr) = c_pf_features.btagPf_trackSip3dSig; + *(++ptr) = c_pf_features.btagPf_trackSip3dVal; + *(++ptr) = c_pf_features.deltaR; + *(++ptr) = c_pf_features.drminsv; + *(++ptr) = c_pf_features.drsubjet1; + *(++ptr) = c_pf_features.drsubjet2; + *(++ptr) = c_pf_features.dxy; + *(++ptr) = c_pf_features.dxysig; + *(++ptr) = c_pf_features.dz; + *(++ptr) = c_pf_features.dzsig; + *(++ptr) = c_pf_features.erel; + *(++ptr) = c_pf_features.etarel; + *(++ptr) = c_pf_features.chi2; + *(++ptr) = c_pf_features.ptrel_noclip; + *(++ptr) = c_pf_features.quality; + } + assert(start + n_features_cpf_ - 1 == ptr); } + if (version_ == "V2") { + // n_pf candidates + auto max_n_pf_n = std::min(features.n_pf_features.size(), (std::size_t)n_cpf_); + offset = i_jet * input_sizes_[kNeutralCandidates]; + 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); + ptr = &data_[kNeutralCandidates][offset + n_pf_n * n_features_npf_]; + start = ptr; + *ptr = n_pf_features.deltaR_noclip; + *(++ptr) = n_pf_features.drminsv; + *(++ptr) = n_pf_features.drsubjet1; + *(++ptr) = n_pf_features.drsubjet2; + *(++ptr) = n_pf_features.erel; + *(++ptr) = n_pf_features.hadFrac; + *(++ptr) = n_pf_features.ptrel_noclip; + *(++ptr) = n_pf_features.puppiw; + assert(start + n_features_npf_ - 1 == ptr); + } + } + // sv candidates auto max_sv_n = std::min(features.sv_features.size(), (std::size_t)n_sv_); offset = i_jet * input_sizes_[kVertices]; @@ -244,8 +350,18 @@ void DeepDoubleXONNXJetTagsProducer::make_inputs(unsigned i_jet, const reco::Dee const auto& sv_features = features.sv_features.at(sv_n); ptr = &data_[kVertices][offset + sv_n * n_features_sv_]; start = ptr; - *ptr = sv_features.d3d; - *(++ptr) = sv_features.d3dsig; + if (version_ == "V1") { + *ptr = sv_features.d3d; + *(++ptr) = sv_features.d3dsig; + } else { + *ptr = sv_features.costhetasvpv; + *(++ptr) = sv_features.deltaR; + *(++ptr) = sv_features.dxysig; + *(++ptr) = sv_features.mass; + *(++ptr) = sv_features.ntracks; + *(++ptr) = sv_features.pt; + *(++ptr) = sv_features.ptrel; + } assert(start + n_features_sv_ - 1 == ptr); } } diff --git a/RecoBTag/ONNXRuntime/python/pfDeepDoubleX_cff.py b/RecoBTag/ONNXRuntime/python/pfDeepDoubleX_cff.py index 4c8ea8d8b67d1..ce57423637da1 100644 --- a/RecoBTag/ONNXRuntime/python/pfDeepDoubleX_cff.py +++ b/RecoBTag/ONNXRuntime/python/pfDeepDoubleX_cff.py @@ -4,3 +4,5 @@ from RecoBTag.ONNXRuntime.pfMassIndependentDeepDoubleXJetTags_cff import * +from RecoBTag.ONNXRuntime.pfMassIndependentDeepDoubleXV2JetTags_cff import * + diff --git a/RecoBTag/ONNXRuntime/python/pfMassIndependentDeepDoubleXJetTags_cff.py b/RecoBTag/ONNXRuntime/python/pfMassIndependentDeepDoubleXJetTags_cff.py index d2e9d544b018b..7563a491a4bb0 100644 --- a/RecoBTag/ONNXRuntime/python/pfMassIndependentDeepDoubleXJetTags_cff.py +++ b/RecoBTag/ONNXRuntime/python/pfMassIndependentDeepDoubleXJetTags_cff.py @@ -5,8 +5,8 @@ from .pfDeepDoubleCvBJetTags_cfi import pfDeepDoubleCvBJetTags pfMassIndependentDeepDoubleBvLJetTags = pfDeepDoubleBvLJetTags.clone( - model_path = 'RecoBTag/Combined/data/DeepDoubleX/94X/V01/DDB_mass_independent.onnx') + model_path = "RecoBTag/Combined/data/DeepDoubleX/94X/V01/DDB_mass_independent.onnx") pfMassIndependentDeepDoubleCvLJetTags = pfDeepDoubleCvLJetTags.clone( - model_path = 'RecoBTag/Combined/data/DeepDoubleX/94X/V01/DDC_mass_independent.onnx') + model_path = "RecoBTag/Combined/data/DeepDoubleX/94X/V01/DDC_mass_independent.onnx") pfMassIndependentDeepDoubleCvBJetTags = pfDeepDoubleCvBJetTags.clone( - model_path = 'RecoBTag/Combined/data/DeepDoubleX/94X/V01/DDCvB_mass_independent.onnx') + model_path = "RecoBTag/Combined/data/DeepDoubleX/94X/V01/DDCvB_mass_independent.onnx") diff --git a/RecoBTag/ONNXRuntime/python/pfMassIndependentDeepDoubleXV2JetTags_cff.py b/RecoBTag/ONNXRuntime/python/pfMassIndependentDeepDoubleXV2JetTags_cff.py new file mode 100644 index 0000000000000..86f2373abc481 --- /dev/null +++ b/RecoBTag/ONNXRuntime/python/pfMassIndependentDeepDoubleXV2JetTags_cff.py @@ -0,0 +1,23 @@ +from __future__ import absolute_import +import FWCore.ParameterSet.Config as cms +from .pfDeepDoubleBvLJetTags_cfi import pfDeepDoubleBvLJetTags +from .pfDeepDoubleCvLJetTags_cfi import pfDeepDoubleCvLJetTags +from .pfDeepDoubleCvBJetTags_cfi import pfDeepDoubleCvBJetTags + +pfMassIndependentDeepDoubleBvLV2JetTags = pfDeepDoubleBvLJetTags.clone( + model_path="RecoBTag/Combined/data/DeepDoubleX/102X/V02/BvL.onnx", + input_names={"input_1", "input_2", "input_3", "input_4"}, + version="V2", +) + +pfMassIndependentDeepDoubleCvLV2JetTags = pfDeepDoubleCvLJetTags.clone( + model_path="RecoBTag/Combined/data/DeepDoubleX/102X/V02/CvL.onnx", + input_names={"input_1", "input_2", "input_3", "input_4"}, + version="V2", +) + +pfMassIndependentDeepDoubleCvBV2JetTags = pfDeepDoubleCvBJetTags.clone( + model_path="RecoBTag/Combined/data/DeepDoubleX/102X/V02/CvB.onnx", + input_names={"input_1", "input_2", "input_3", "input_4"}, + version="V2", +) diff --git a/RecoBTag/ONNXRuntime/test/README.md b/RecoBTag/ONNXRuntime/test/README.md new file mode 100644 index 0000000000000..ff838b5ab335c --- /dev/null +++ b/RecoBTag/ONNXRuntime/test/README.md @@ -0,0 +1,11 @@ +### Editing will most likely require + +``` +git cms-addpkg RecoBTag/ONNXRuntime +git cms-addpkg RecoBTag/FeatureTools +git cms-addpkg RecoBTag/Combined +git cms-addpkg DataFormats/BTauReco + +# And to check out the models +git clone https://github.com/cms-data/RecoBTag-Combined.git RecoBTag/Combined/data +``` diff --git a/RecoBTag/ONNXRuntime/test/plotDDX.py b/RecoBTag/ONNXRuntime/test/plotDDX.py index acc86108c48d6..4ce6ba9d8720c 100644 --- a/RecoBTag/ONNXRuntime/test/plotDDX.py +++ b/RecoBTag/ONNXRuntime/test/plotDDX.py @@ -1,10 +1,12 @@ from __future__ import print_function import ROOT from DataFormats.FWLite import Handle, Events +import numpy as np +import pickle events_c = Events('output_test_DDX.root') -handleJ = Handle ("std::vector") +handleJ = Handle("std::vector") labelJ = ("selectedUpdatedPatJets","","PATtest") h_probQ_ddb = ROOT.TH1F('h_probQ_ddb', ';prob Q;', 40, 0., 1.) @@ -13,25 +15,45 @@ h_probQ_ddc = ROOT.TH1F('h_probQ_ddc', ';prob Q;', 40, 0., 1.) h_probH_ddc = ROOT.TH1F('h_probH_ddc', ';prob H;', 40, 0., 1.) -for iev,event in enumerate(events_c): +info = {} +info['pt'] = [] +info['eta'] = [] +info['mass'] = [] +info['BvL'] = [] +info['CvL'] = [] +info['CvB'] = [] + + +for iev, event in enumerate(events_c): event.getByLabel (labelJ, handleJ) jets = handleJ.product() - for jet in jets : - if jet.pt() < 300 or jet.pt() > 2000: continue - if jet.mass() < 40 or jet.mass() > 200: continue + print(iev) + for jet in jets: + #if jet.pt() < 300 or jet.pt() > 2000: continue + #if jet.mass() < 40 or jet.mass() > 200: continue - print(jet.pt(), jet.mass()) + print(jet.pt(), jet.mass(), jet.eta()) print("DDB", jet.bDiscriminator("pfDeepDoubleBvLJetTags:probQCD"), jet.bDiscriminator("pfDeepDoubleBvLJetTags:probHbb")) - print("DDB", jet.bDiscriminator("pfMassIndependentDeepDoubleBvLJetTags:probQCD"), jet.bDiscriminator("pfMassIndependentDeepDoubleBvLJetTags:probHbb")) + # print("DDB", jet.bDiscriminator("pfMassIndependentDeepDoubleBvLJetTags:probQCD"), jet.bDiscriminator("pfMassIndependentDeepDoubleBvLJetTags:probHbb")) print("DDCvL", jet.bDiscriminator("pfDeepDoubleCvLJetTags:probQCD"), jet.bDiscriminator("pfDeepDoubleCvLJetTags:probHcc")) - print("DDCvL", jet.bDiscriminator("pfMassIndependentDeepDoubleCvLJetTags:probQCD"), jet.bDiscriminator("pfMassIndependentDeepDoubleCvLJetTags:probHcc")) + # print("DDCvL", jet.bDiscriminator("pfMassIndependentDeepDoubleCvLJetTags:probQCD"), jet.bDiscriminator("pfMassIndependentDeepDoubleCvLJetTags:probHcc")) print("DDCvB", jet.bDiscriminator("pfDeepDoubleCvBJetTags:probHbb"), jet.bDiscriminator("pfDeepDoubleCvBJetTags:probHcc") ) - print("DDCvB", jet.bDiscriminator("pfMassIndependentDeepDoubleCvBJetTags:probHbb"), jet.bDiscriminator("pfMassIndependentDeepDoubleCvBJetTags:probHcc")) + # print("DDCvB", jet.bDiscriminator("pfMassIndependentDeepDoubleCvBJetTags:probHbb"), jet.bDiscriminator("pfMassIndependentDeepDoubleCvBJetTags:probHcc")) h_probQ_ddb.Fill(jet.bDiscriminator("pfDeepDoubleBvLJetTags:probQCD")) h_probH_ddb.Fill(jet.bDiscriminator("pfDeepDoubleBvLJetTags:probHbb")) h_probQ_ddc.Fill(jet.bDiscriminator("pfDeepDoubleCvLJetTags:probQCD")) h_probH_ddc.Fill(jet.bDiscriminator("pfDeepDoubleCvLJetTags:probHcc")) + info['mass'].append(jet.mass()) + info['pt'].append(jet.pt()) + info['eta'].append(jet.eta()) + info['BvL'].append(jet.bDiscriminator("pfDeepDoubleBvLJetTags:probHbb")) + info['CvL'].append(jet.bDiscriminator("pfDeepDoubleCvLJetTags:probHcc")) + info['CvB'].append(jet.bDiscriminator("pfDeepDoubleCvBJetTags:probHcc")) + +with open('outputs.pkl', 'wb') as handle: + pickle.dump(info, handle) + c1a = ROOT.TCanvas() h_probH_ddb.Draw("HISTO") h_probH_ddb.SetLineColor(632) diff --git a/RecoBTag/ONNXRuntime/test/test_deep_doublex_cfg.py b/RecoBTag/ONNXRuntime/test/test_deep_doublex_cfg.py index fd25123598981..6e402977fc8dd 100644 --- a/RecoBTag/ONNXRuntime/test/test_deep_doublex_cfg.py +++ b/RecoBTag/ONNXRuntime/test/test_deep_doublex_cfg.py @@ -1,4 +1,3 @@ - import FWCore.ParameterSet.Config as cms from PhysicsTools.PatAlgos.tools.helpers import getPatAlgosToolsTask @@ -6,18 +5,24 @@ ## MessageLogger process.load("FWCore.MessageLogger.MessageLogger_cfi") -process.MessageLogger.cerr.FwkReport.reportEvery = 1000 +process.MessageLogger.cerr.FwkReport.reportEvery = 1 ## Options and Output Report -process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True) ) +process.options = cms.untracked.PSet( wantSummary = cms.untracked.bool(True), +SkipEvent = cms.untracked.vstring('ProductNotFound')) ## Source process.source = cms.Source("PoolSource", - fileNames = cms.untracked.vstring() + fileNames = cms.untracked.vstring(), + #skipEvents=cms.untracked.uint32(250) ) + +#process.source.eventsToProcess = cms.untracked.VEventRange("1:3127296-1:3127297") + ## Maximal Number of Events -process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1) ) +#process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(-1) ) +process.maxEvents = cms.untracked.PSet( input = cms.untracked.int32(1000) ) ## Geometry and Detector Conditions (needed for a few patTuple production steps) process.load("Configuration.Geometry.GeometryRecoDB_cff") @@ -52,31 +57,34 @@ jetCorrections = ('AK8PFchs', cms.vstring(['L2Relative', 'L3Absolute']), 'None'), btagDiscriminators = [ 'pfBoostedDoubleSecondaryVertexAK8BJetTags', - 'pfDeepDoubleBvLJetTags:probQCD', - 'pfDeepDoubleBvLJetTags:probHbb', - 'pfDeepDoubleCvLJetTags:probQCD', - 'pfDeepDoubleCvLJetTags:probHcc', - 'pfDeepDoubleCvBJetTags:probHbb', - 'pfDeepDoubleCvBJetTags:probHcc', 'pfMassIndependentDeepDoubleBvLJetTags:probQCD', 'pfMassIndependentDeepDoubleBvLJetTags:probHbb', 'pfMassIndependentDeepDoubleCvLJetTags:probQCD', 'pfMassIndependentDeepDoubleCvLJetTags:probHcc', 'pfMassIndependentDeepDoubleCvBJetTags:probHbb', 'pfMassIndependentDeepDoubleCvBJetTags:probHcc', + 'pfMassIndependentDeepDoubleBvLV2JetTags:probQCD', + 'pfMassIndependentDeepDoubleBvLV2JetTags:probHbb', + 'pfMassIndependentDeepDoubleCvLV2JetTags:probQCD', + 'pfMassIndependentDeepDoubleCvLV2JetTags:probHcc', + 'pfMassIndependentDeepDoubleCvBV2JetTags:probHbb', + 'pfMassIndependentDeepDoubleCvBV2JetTags:probHcc', + ] ) + from PhysicsTools.PatAlgos.patInputFiles_cff import filesRelValTTbarPileUpMINIAODSIM process.source.fileNames = filesRelValTTbarPileUpMINIAODSIM process.source.fileNames = cms.untracked.vstring( -'/store/relval/CMSSW_10_3_0_pre2/RelValTTbar_13/MINIAODSIM/PU25ns_103X_upgrade2018_realistic_v2-v1/20000/85820ACA-657B-BC44-AC74-AACD6D54B348.root' +#'/store/relval/CMSSW_10_3_0_pre2/RelValTTbar_13/MINIAODSIM/PU25ns_103X_upgrade2018_realistic_v2-v1/20000/85820ACA-657B-BC44-AC74-AACD6D54B348.root' #'/store/mc/RunIIFall17MiniAOD/GluGluHToBB_M125_13TeV_powheg_pythia8/MINIAODSIM/94X_mc2017_realistic_v10-v1/20000/C8932584-5006-E811-9840-141877410512.root', #'/store/mc/RunIIFall17MiniAODv2/GluGluHToCC_M125_13TeV_powheg_pythia8/MINIAODSIM/PU2017_12Apr2018_94X_mc2017_realistic_v14-v2/30000/72164088-CB67-E811-9D0D-008CFA197AC4.root', +'file:72164088-CB67-E811-9D0D-008CFA197AC4.root', #'/store/mc/RunIIFall17MiniAOD/QCD_HT700to1000_TuneCP5_13TeV-madgraph-pythia8/MINIAODSIM/94X_mc2017_realistic_v10-v1/20000/C0F304A4-23FA-E711-942E-E0071B6CAD20.root' ) -process.maxEvents.input = 1000 +#process.maxEvents.input = 1000 from Configuration.EventContent.EventContent_cff import MINIAODSIMEventContent process.out.outputCommands.append('keep *_slimmedJetsAK8*_*_*')