From 16f9c2b59ad680ed4bf044f59f1033ddbc89f88c Mon Sep 17 00:00:00 2001 From: Emil Bols Date: Mon, 4 Jun 2018 12:10:24 +0200 Subject: [PATCH 1/4] Add DeepFlavour Negative Tagger --- .../PatAlgos/python/tools/jetTools.py | 2 +- .../interface/ChargedCandidateConverter.h | 29 ++++++++++++++----- .../interface/SecondaryVertexConverter.h | 3 +- .../plugins/DeepFlavourTagInfoProducer.cc | 27 +++++++++++------ .../pfNegativeDeepFlavourTagInfos_cfi.py | 6 ++-- .../src/ChargedCandidateConverter.cc | 10 ++++--- .../src/SecondaryVertexConverter.cc | 13 ++++++--- 7 files changed, 62 insertions(+), 28 deletions(-) diff --git a/PhysicsTools/PatAlgos/python/tools/jetTools.py b/PhysicsTools/PatAlgos/python/tools/jetTools.py index 24f33ec16b858..6e01f81f45b6b 100644 --- a/PhysicsTools/PatAlgos/python/tools/jetTools.py +++ b/PhysicsTools/PatAlgos/python/tools/jetTools.py @@ -617,7 +617,7 @@ def setupBTagging(process, jetSource, pfCandidates, explicitJTA, pvSource, svSou shallow_tag_infos = cms.InputTag(btagPrefix+deep_csv_tag_infos+labelName+postfix), puppi_value_map = puppi_value_map, vertex_associator = vertex_associator, - ), + flip = flip), process, task) if btagInfo == 'pfDeepDoubleBTagInfos': diff --git a/RecoBTag/TensorFlow/interface/ChargedCandidateConverter.h b/RecoBTag/TensorFlow/interface/ChargedCandidateConverter.h index 66c726400d499..c4b24254f5cf0 100644 --- a/RecoBTag/TensorFlow/interface/ChargedCandidateConverter.h +++ b/RecoBTag/TensorFlow/interface/ChargedCandidateConverter.h @@ -16,8 +16,21 @@ namespace btagbtvdeep { const reco::Jet & jet, const TrackInfoBuilder & track_info, const float & drminpfcandsv, const float & jetR, - ChargedCandidateFeatures & c_pf_features) { + ChargedCandidateFeatures & c_pf_features, + const bool flip = false) { + + float trackSip2dVal = track_info.getTrackSip2dVal(); + float trackSip2dSig = track_info.getTrackSip2dSig(); + float trackSip3dVal = track_info.getTrackSip3dVal(); + float trackSip3dSig = track_info.getTrackSip3dSig(); + if(flip == true){ + trackSip2dVal = -trackSip2dVal; + trackSip2dSig = -trackSip2dSig; + trackSip3dSig = -trackSip3dSig; + trackSip3dVal = -trackSip3dVal; + } + c_pf_features.ptrel = catch_infs_and_bound(c_pf->pt()/jet.pt(), 0,-1,0,-1); @@ -27,10 +40,10 @@ namespace btagbtvdeep { c_pf_features.btagPf_trackDeltaR =catch_infs_and_bound(track_info.getTrackDeltaR(), 0,-5,5 ); c_pf_features.btagPf_trackPtRatio =catch_infs_and_bound(track_info.getTrackPtRatio(), 0,-1,10); c_pf_features.btagPf_trackPParRatio =catch_infs_and_bound(track_info.getTrackPParRatio(),0,-10,100); - c_pf_features.btagPf_trackSip3dVal =catch_infs_and_bound(track_info.getTrackSip3dVal(), 0, -1,1e5 ); - c_pf_features.btagPf_trackSip3dSig =catch_infs_and_bound(track_info.getTrackSip3dSig(), 0, -1,4e4 ); - c_pf_features.btagPf_trackSip2dVal =catch_infs_and_bound(track_info.getTrackSip2dVal(), 0, -1,70 ); - c_pf_features.btagPf_trackSip2dSig =catch_infs_and_bound(track_info.getTrackSip2dSig(), 0, -1,4e4 ); + c_pf_features.btagPf_trackSip3dVal =catch_infs_and_bound(trackSip3dVal, 0, -1,1e5 ); + c_pf_features.btagPf_trackSip3dSig =catch_infs_and_bound(trackSip3dSig, 0, -1,4e4 ); + c_pf_features.btagPf_trackSip2dVal =catch_infs_and_bound(trackSip2dVal, 0, -1,70 ); + c_pf_features.btagPf_trackSip2dSig =catch_infs_and_bound(trackSip2dSig, 0, -1,4e4 ); 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); @@ -41,7 +54,8 @@ namespace btagbtvdeep { const pat::Jet & jet, const TrackInfoBuilder & track_info, const float drminpfcandsv, const float jetR, - ChargedCandidateFeatures & c_pf_features) ; + ChargedCandidateFeatures & c_pf_features, + const bool flip = false) ; void recoCandidateToFeatures(const reco::PFCandidate * c_pf, @@ -50,7 +64,8 @@ namespace btagbtvdeep { const float drminpfcandsv, const float jetR, const float puppiw, const int pv_ass_quality, const reco::VertexRef & pv, - ChargedCandidateFeatures & c_pf_features) ; + ChargedCandidateFeatures & c_pf_features, + const bool flip = false) ; } diff --git a/RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h b/RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h index 0abc2b7018fc7..eb12325fe7799 100644 --- a/RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h +++ b/RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h @@ -13,7 +13,8 @@ namespace btagbtvdeep { void svToFeatures( const reco::VertexCompositePtrCandidate & sv, const reco::Vertex & pv, const reco::Jet & jet, - SecondaryVertexFeatures & sv_features) ; + SecondaryVertexFeatures & sv_features, + const bool flip_ = false) ; } diff --git a/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc b/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc index b096d076247a6..bc88f2c44e13c 100644 --- a/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc +++ b/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc @@ -33,7 +33,9 @@ #include "RecoBTag/TensorFlow/interface/deep_helpers.h" - +#include "FWCore/ParameterSet/interface/Registry.h" +#include "FWCore/Common/interface/Provenance.h" +#include "DataFormats/Provenance/interface/ProductProvenance.h" class DeepFlavourTagInfoProducer : public edm::stream::EDProducer<> { @@ -56,6 +58,7 @@ class DeepFlavourTagInfoProducer : public edm::stream::EDProducer<> { const double jet_radius_; const double min_candidate_pt_; + const bool flip_; edm::EDGetTokenT> jet_token_; edm::EDGetTokenT vtx_token_; @@ -76,6 +79,7 @@ class DeepFlavourTagInfoProducer : public edm::stream::EDProducer<> { DeepFlavourTagInfoProducer::DeepFlavourTagInfoProducer(const edm::ParameterSet& iConfig) : jet_radius_(iConfig.getParameter("jet_radius")), min_candidate_pt_(iConfig.getParameter("min_candidate_pt")), + flip_(iConfig.getParameter("flip")), jet_token_(consumes >(iConfig.getParameter("jets"))), vtx_token_(consumes(iConfig.getParameter("vertices"))), sv_token_(consumes(iConfig.getParameter("secondary_vertices"))), @@ -114,6 +118,7 @@ void DeepFlavourTagInfoProducer::fillDescriptions(edm::ConfigurationDescriptions desc.add("shallow_tag_infos", edm::InputTag("pfDeepCSVTagInfos")); desc.add("jet_radius", 0.4); desc.add("min_candidate_pt", 0.95); + desc.add("flip", false); desc.add("vertices", edm::InputTag("offlinePrimaryVertices")); desc.add("puppi_value_map", edm::InputTag("puppi")); desc.add("secondary_vertices", edm::InputTag("inclusiveCandidateSecondaryVertices")); @@ -196,6 +201,10 @@ void DeepFlavourTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet // fill number of pv features.npv = vtxs->size(); + math::XYZVector jet_dir = jet.momentum().Unit(); + GlobalVector jet_ref_track_dir(jet.px(), + jet.py(), + jet.pz()); // fill features from ShallowTagInfo const auto & tag_info_vars = tag_info.taggingVariables(); @@ -209,20 +218,16 @@ void DeepFlavourTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet { return btagbtvdeep::sv_vertex_comparator(sva, svb, pv); }); // fill features from secondary vertices for (const auto & sv : svs_sorted) { - if (reco::deltaR(sv, jet) > jet_radius_) continue; + if (Geom::deltaR(sv.position() - pv.position(), flip_ ? -jet_dir : jet_dir) > jet_radius_) continue; else { features.sv_features.emplace_back(); // in C++17 could just get from emplace_back output auto & sv_features = features.sv_features.back(); - btagbtvdeep::svToFeatures(sv, pv, jet, sv_features); + btagbtvdeep::svToFeatures(sv, pv, jet, sv_features, flip_); } } // stuff required for dealing with pf candidates - math::XYZVector jet_dir = jet.momentum().Unit(); - GlobalVector jet_ref_track_dir(jet.px(), - jet.py(), - jet.pz()); std::vector > c_sorted, n_sorted; @@ -269,6 +274,9 @@ void DeepFlavourTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet features.n_pf_features.resize(n_sorted.size()); + const edm::Provenance *prov = shallow_tag_infos.provenance(); + edm::ParameterSet psetFromProvenance = edm::parameterSet(*prov); + double negative_cut = (( psetFromProvenance.getParameter("computer") ).getParameter("trackSelection")).getParameter("sip3dSigMax"); for (unsigned int i = 0; i < jet.numberOfDaughters(); i++){ @@ -305,12 +313,13 @@ void DeepFlavourTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet auto entry = c_sortedindices.at(i); // get cached track info auto & trackinfo = trackinfos.at(i); + if(flip_ && (trackinfo.getTrackSip3dSig() > negative_cut)){continue;} // get_ref to vector element auto & c_pf_features = features.c_pf_features.at(entry); // fill feature structure if (packed_cand) { btagbtvdeep::packedCandidateToFeatures(packed_cand, jet, trackinfo, - drminpfcandsv, static_cast (jet_radius_), c_pf_features); + drminpfcandsv, static_cast (jet_radius_), c_pf_features, flip_); } else if (reco_cand) { // get vertex association quality int pv_ass_quality = 0; // fallback value @@ -337,7 +346,7 @@ void DeepFlavourTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet } btagbtvdeep::recoCandidateToFeatures(reco_cand, jet, trackinfo, drminpfcandsv, static_cast (jet_radius_), puppiw, - pv_ass_quality, PV, c_pf_features); + pv_ass_quality, PV, c_pf_features, flip_); } } else { // is neutral candidate diff --git a/RecoBTag/TensorFlow/python/pfNegativeDeepFlavourTagInfos_cfi.py b/RecoBTag/TensorFlow/python/pfNegativeDeepFlavourTagInfos_cfi.py index 8e1d6983c2a55..7758126cbf1fb 100644 --- a/RecoBTag/TensorFlow/python/pfNegativeDeepFlavourTagInfos_cfi.py +++ b/RecoBTag/TensorFlow/python/pfNegativeDeepFlavourTagInfos_cfi.py @@ -3,5 +3,7 @@ from RecoBTag.TensorFlow.pfDeepFlavourTagInfos_cfi import pfDeepFlavourTagInfos pfNegativeDeepFlavourTagInfos = pfDeepFlavourTagInfos.clone( - shallow_tag_infos = cms.InputTag('pfDeepCSVNegativeTagInfos') - ) + shallow_tag_infos = cms.InputTag('pfDeepCSVNegativeTagInfos'), + secondary_vertices = cms.InputTag('inclusiveCandidateNegativeSecondaryVertices'), + flip = cms.bool(True) + ) diff --git a/RecoBTag/TensorFlow/src/ChargedCandidateConverter.cc b/RecoBTag/TensorFlow/src/ChargedCandidateConverter.cc index 1a611a93aad2c..2f35d08513b64 100644 --- a/RecoBTag/TensorFlow/src/ChargedCandidateConverter.cc +++ b/RecoBTag/TensorFlow/src/ChargedCandidateConverter.cc @@ -21,9 +21,10 @@ namespace btagbtvdeep { const pat::Jet & jet, const TrackInfoBuilder & track_info, const float drminpfcandsv, const float jetR, - ChargedCandidateFeatures & c_pf_features) { + ChargedCandidateFeatures & c_pf_features, + const bool flip) { - commonCandidateToFeatures(c_pf, jet, track_info, drminpfcandsv, jetR, c_pf_features); + commonCandidateToFeatures(c_pf, jet, track_info, drminpfcandsv, jetR, c_pf_features, flip); c_pf_features.vtx_ass = c_pf->pvAssociationQuality(); @@ -50,9 +51,10 @@ namespace btagbtvdeep { const float drminpfcandsv, const float jetR, const float puppiw, const int pv_ass_quality, const reco::VertexRef & pv, - ChargedCandidateFeatures & c_pf_features) { + ChargedCandidateFeatures & c_pf_features, + const bool flip) { - commonCandidateToFeatures(c_pf, jet, track_info, drminpfcandsv, jetR, c_pf_features); + commonCandidateToFeatures(c_pf, jet, track_info, drminpfcandsv, jetR, c_pf_features, flip); c_pf_features.vtx_ass = (float) pat::PackedCandidate::PVAssociationQuality(qualityMap[pv_ass_quality]); if (c_pf->trackRef().isNonnull() && diff --git a/RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc b/RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc index e6369760232cf..b4e757b32c819 100644 --- a/RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc +++ b/RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc @@ -12,11 +12,12 @@ namespace btagbtvdeep { void svToFeatures( const reco::VertexCompositePtrCandidate & sv, const reco::Vertex & pv, const reco::Jet & jet, - SecondaryVertexFeatures & sv_features) { + SecondaryVertexFeatures & sv_features, + const bool flip) { + math::XYZVector jet_dir = jet.momentum().Unit(); sv_features.pt = sv.pt(); - sv_features.deltaR = catch_infs_and_bound( - std::fabs(reco::deltaR(sv,jet))-0.5, + sv_features.deltaR = catch_infs_and_bound(std::fabs(Geom::deltaR(sv.position() - pv.position(), flip ? -jet_dir : jet_dir))-0.5, 0,-2,0); sv_features.mass = sv.mass(); sv_features.ntracks = sv.numberOfDaughters(); @@ -31,7 +32,11 @@ namespace btagbtvdeep { sv_features.d3d = d3d_meas.value(); sv_features.d3dsig = catch_infs_and_bound(d3d_meas.value()/d3d_meas.error(), 0,-1,800); - sv_features.costhetasvpv = vertexDdotP(sv,pv); + float costhetasvpv = vertexDdotP(sv,pv); + if(flip){ + costhetasvpv = -costhetasvpv; + } + sv_features.costhetasvpv = costhetasvpv; sv_features.enratio = sv.energy()/jet.energy(); } From b9323299e6c6a3e278b885ad5a5a97f4c62686c1 Mon Sep 17 00:00:00 2001 From: Emil Bols Date: Mon, 4 Jun 2018 12:11:15 +0200 Subject: [PATCH 2/4] Add new DeepFlavour training --- RecoBTag/TensorFlow/plugins/DeepFlavourTFJetTagsProducer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RecoBTag/TensorFlow/plugins/DeepFlavourTFJetTagsProducer.cc b/RecoBTag/TensorFlow/plugins/DeepFlavourTFJetTagsProducer.cc index 9ee2585a1e785..d6327992f38ac 100644 --- a/RecoBTag/TensorFlow/plugins/DeepFlavourTFJetTagsProducer.cc +++ b/RecoBTag/TensorFlow/plugins/DeepFlavourTFJetTagsProducer.cc @@ -136,9 +136,9 @@ void DeepFlavourTFJetTagsProducer::fillDescriptions(edm::ConfigurationDescriptio desc.add>("input_names", { "input_1", "input_2", "input_3", "input_4", "input_5" }); desc.add("graph_path", - edm::FileInPath("RecoBTag/Combined/data/DeepFlavourV01_GraphDef_PtCut/constant_graph.pb")); + edm::FileInPath("RecoBTag/Combined/data/DeepFlavourV03_10X_training/constant_graph.pb")); desc.add>("lp_names", - { "globals_input_batchnorm/keras_learning_phase" }); + { "cpf_input_batchnorm/keras_learning_phase" }); desc.add>("output_names", { "ID_pred/Softmax", "regression_pred/BiasAdd" }); { From 1cbf72abcc2790fc8c87894475f6ef2716a5925f Mon Sep 17 00:00:00 2001 From: Emil Bols Date: Mon, 4 Jun 2018 19:25:17 +0200 Subject: [PATCH 3/4] Code check --- RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc b/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc index bc88f2c44e13c..17068364213e0 100644 --- a/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc +++ b/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc @@ -275,7 +275,7 @@ void DeepFlavourTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet const edm::Provenance *prov = shallow_tag_infos.provenance(); - edm::ParameterSet psetFromProvenance = edm::parameterSet(*prov); + const edm::ParameterSet& psetFromProvenance = edm::parameterSet(*prov); double negative_cut = (( psetFromProvenance.getParameter("computer") ).getParameter("trackSelection")).getParameter("sip3dSigMax"); for (unsigned int i = 0; i < jet.numberOfDaughters(); i++){ From b62675266e3129ca3f77a62f2d7b29a8546d6f84 Mon Sep 17 00:00:00 2001 From: Emil Bols Date: Fri, 8 Jun 2018 11:20:53 +0200 Subject: [PATCH 4/4] switch to reco::deltaR and remove type specifications --- RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h | 2 +- RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc | 6 ++++-- .../python/pfNegativeDeepFlavourTagInfos_cfi.py | 6 +++--- RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc | 8 ++------ 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h b/RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h index eb12325fe7799..cd5eda1fecd12 100644 --- a/RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h +++ b/RecoBTag/TensorFlow/interface/SecondaryVertexConverter.h @@ -14,7 +14,7 @@ namespace btagbtvdeep { void svToFeatures( const reco::VertexCompositePtrCandidate & sv, const reco::Vertex & pv, const reco::Jet & jet, SecondaryVertexFeatures & sv_features, - const bool flip_ = false) ; + const bool flip = false) ; } diff --git a/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc b/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc index 17068364213e0..eee80348b943f 100644 --- a/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc +++ b/RecoBTag/TensorFlow/plugins/DeepFlavourTagInfoProducer.cc @@ -218,7 +218,7 @@ void DeepFlavourTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet { return btagbtvdeep::sv_vertex_comparator(sva, svb, pv); }); // fill features from secondary vertices for (const auto & sv : svs_sorted) { - if (Geom::deltaR(sv.position() - pv.position(), flip_ ? -jet_dir : jet_dir) > jet_radius_) continue; + if (reco::deltaR2(sv.position() - pv.position(), flip_ ? -jet_dir : jet_dir) > (jet_radius_*jet_radius_)) continue; else { features.sv_features.emplace_back(); // in C++17 could just get from emplace_back output @@ -276,7 +276,9 @@ void DeepFlavourTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSet const edm::Provenance *prov = shallow_tag_infos.provenance(); const edm::ParameterSet& psetFromProvenance = edm::parameterSet(*prov); - double negative_cut = (( psetFromProvenance.getParameter("computer") ).getParameter("trackSelection")).getParameter("sip3dSigMax"); + double negative_cut = ( ( psetFromProvenance.getParameter("computer") + ).getParameter("trackSelection") + ).getParameter("sip3dSigMax"); for (unsigned int i = 0; i < jet.numberOfDaughters(); i++){ diff --git a/RecoBTag/TensorFlow/python/pfNegativeDeepFlavourTagInfos_cfi.py b/RecoBTag/TensorFlow/python/pfNegativeDeepFlavourTagInfos_cfi.py index 7758126cbf1fb..cdda7a5720050 100644 --- a/RecoBTag/TensorFlow/python/pfNegativeDeepFlavourTagInfos_cfi.py +++ b/RecoBTag/TensorFlow/python/pfNegativeDeepFlavourTagInfos_cfi.py @@ -3,7 +3,7 @@ from RecoBTag.TensorFlow.pfDeepFlavourTagInfos_cfi import pfDeepFlavourTagInfos pfNegativeDeepFlavourTagInfos = pfDeepFlavourTagInfos.clone( - shallow_tag_infos = cms.InputTag('pfDeepCSVNegativeTagInfos'), - secondary_vertices = cms.InputTag('inclusiveCandidateNegativeSecondaryVertices'), - flip = cms.bool(True) + shallow_tag_infos = 'pfDeepCSVNegativeTagInfos', + secondary_vertices = 'inclusiveCandidateNegativeSecondaryVertices', + flip = True ) diff --git a/RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc b/RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc index b4e757b32c819..01bab93f452e9 100644 --- a/RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc +++ b/RecoBTag/TensorFlow/src/SecondaryVertexConverter.cc @@ -17,7 +17,7 @@ namespace btagbtvdeep { math::XYZVector jet_dir = jet.momentum().Unit(); sv_features.pt = sv.pt(); - sv_features.deltaR = catch_infs_and_bound(std::fabs(Geom::deltaR(sv.position() - pv.position(), flip ? -jet_dir : jet_dir))-0.5, + sv_features.deltaR = catch_infs_and_bound(std::fabs(reco::deltaR(sv.position() - pv.position(), flip ? -jet_dir : jet_dir))-0.5, 0,-2,0); sv_features.mass = sv.mass(); sv_features.ntracks = sv.numberOfDaughters(); @@ -32,11 +32,7 @@ namespace btagbtvdeep { sv_features.d3d = d3d_meas.value(); sv_features.d3dsig = catch_infs_and_bound(d3d_meas.value()/d3d_meas.error(), 0,-1,800); - float costhetasvpv = vertexDdotP(sv,pv); - if(flip){ - costhetasvpv = -costhetasvpv; - } - sv_features.costhetasvpv = costhetasvpv; + sv_features.costhetasvpv = (flip ? -1.f : 1.f)* vertexDdotP(sv,pv); sv_features.enratio = sv.energy()/jet.energy(); }