File indexing completed on 2021-02-14 13:33:38
0001
0002 #include "FWCore/Framework/interface/Frameworkfwd.h"
0003 #include "FWCore/Framework/interface/stream/EDProducer.h"
0004
0005 #include "FWCore/Framework/interface/Event.h"
0006 #include "FWCore/Framework/interface/MakerMacros.h"
0007
0008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0009 #include "FWCore/Utilities/interface/StreamID.h"
0010 #include "FWCore/Utilities/interface/ESGetToken.h"
0011
0012 #include "DataFormats/Candidate/interface/Candidate.h"
0013
0014 #include "DataFormats/PatCandidates/interface/Jet.h"
0015 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0016
0017 #include "DataFormats/BTauReco/interface/BoostedDoubleSVTagInfo.h"
0018
0019 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0020 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0021
0022 #include "DataFormats/BTauReco/interface/DeepDoubleXFeatures.h"
0023 #include "DataFormats/BTauReco/interface/DeepDoubleXTagInfo.h"
0024
0025 #include "RecoBTag/FeatureTools/interface/BoostedDoubleSVTagInfoConverter.h"
0026 #include "RecoBTag/FeatureTools/interface/NeutralCandidateConverter.h"
0027 #include "RecoBTag/FeatureTools/interface/ChargedCandidateConverter.h"
0028 #include "RecoBTag/FeatureTools/interface/JetConverter.h"
0029 #include "RecoBTag/FeatureTools/interface/SecondaryVertexConverter.h"
0030
0031 #include "RecoBTag/FeatureTools/interface/TrackInfoBuilder.h"
0032 #include "RecoBTag/FeatureTools/interface/sorting_modules.h"
0033
0034 #include "DataFormats/Candidate/interface/VertexCompositePtrCandidate.h"
0035 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0036
0037 #include "RecoBTag/FeatureTools/interface/deep_helpers.h"
0038
0039 class DeepDoubleXTagInfoProducer : public edm::stream::EDProducer<> {
0040 public:
0041 explicit DeepDoubleXTagInfoProducer(const edm::ParameterSet&);
0042 ~DeepDoubleXTagInfoProducer() override;
0043
0044 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0045
0046 private:
0047 typedef std::vector<reco::DeepDoubleXTagInfo> DeepDoubleXTagInfoCollection;
0048 typedef reco::VertexCompositePtrCandidateCollection SVCollection;
0049 typedef reco::VertexCollection VertexCollection;
0050 typedef edm::View<reco::BoostedDoubleSVTagInfo> BoostedDoubleSVTagInfoCollection;
0051
0052 void beginStream(edm::StreamID) override {}
0053 void produce(edm::Event&, const edm::EventSetup&) override;
0054 void endStream() override {}
0055
0056 const double jet_radius_;
0057 const double min_jet_pt_;
0058 const double min_candidate_pt_;
0059
0060 edm::EDGetTokenT<edm::View<reco::Jet>> jet_token_;
0061 edm::EDGetTokenT<VertexCollection> vtx_token_;
0062 edm::EDGetTokenT<SVCollection> sv_token_;
0063 edm::EDGetTokenT<BoostedDoubleSVTagInfoCollection> shallow_tag_info_token_;
0064 edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> track_builder_token_;
0065 };
0066
0067 DeepDoubleXTagInfoProducer::DeepDoubleXTagInfoProducer(const edm::ParameterSet& iConfig)
0068 : jet_radius_(iConfig.getParameter<double>("jet_radius")),
0069 min_jet_pt_(iConfig.getParameter<double>("min_jet_pt")),
0070 min_candidate_pt_(iConfig.getParameter<double>("min_candidate_pt")),
0071 jet_token_(consumes<edm::View<reco::Jet>>(iConfig.getParameter<edm::InputTag>("jets"))),
0072 vtx_token_(consumes<VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))),
0073 sv_token_(consumes<SVCollection>(iConfig.getParameter<edm::InputTag>("secondary_vertices"))),
0074 shallow_tag_info_token_(
0075 consumes<BoostedDoubleSVTagInfoCollection>(iConfig.getParameter<edm::InputTag>("shallow_tag_infos"))),
0076 track_builder_token_(
0077 esConsumes<TransientTrackBuilder, TransientTrackRecord>(edm::ESInputTag("", "TransientTrackBuilder"))) {
0078 produces<DeepDoubleXTagInfoCollection>();
0079 }
0080
0081 DeepDoubleXTagInfoProducer::~DeepDoubleXTagInfoProducer() {}
0082
0083 void DeepDoubleXTagInfoProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0084
0085 edm::ParameterSetDescription desc;
0086 desc.add<edm::InputTag>("shallow_tag_infos", edm::InputTag("pfBoostedDoubleSVAK8TagInfos"));
0087 desc.add<double>("jet_radius", 0.8);
0088 desc.add<double>("min_jet_pt", 150);
0089 desc.add<double>("min_candidate_pt", 0.95);
0090 desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
0091 desc.add<edm::InputTag>("secondary_vertices", edm::InputTag("inclusiveCandidateSecondaryVertices"));
0092 desc.add<edm::InputTag>("jets", edm::InputTag("ak8PFJetsPuppi"));
0093 descriptions.add("pfDeepDoubleXTagInfos", desc);
0094 }
0095
0096 void DeepDoubleXTagInfoProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0097 auto output_tag_infos = std::make_unique<DeepDoubleXTagInfoCollection>();
0098
0099 edm::Handle<edm::View<reco::Jet>> jets;
0100 iEvent.getByToken(jet_token_, jets);
0101
0102 edm::Handle<VertexCollection> vtxs;
0103 iEvent.getByToken(vtx_token_, vtxs);
0104 if (vtxs->empty()) {
0105
0106 iEvent.put(std::move(output_tag_infos));
0107 return;
0108 }
0109
0110 const auto& pv = vtxs->at(0);
0111
0112 edm::Handle<SVCollection> svs;
0113 iEvent.getByToken(sv_token_, svs);
0114
0115 edm::Handle<BoostedDoubleSVTagInfoCollection> shallow_tag_infos;
0116 iEvent.getByToken(shallow_tag_info_token_, shallow_tag_infos);
0117
0118 edm::ESHandle<TransientTrackBuilder> track_builder = iSetup.getHandle(track_builder_token_);
0119
0120 for (std::size_t jet_n = 0; jet_n < jets->size(); jet_n++) {
0121
0122 btagbtvdeep::DeepDoubleXFeatures features;
0123
0124
0125 const auto& jet = jets->at(jet_n);
0126 const auto* pf_jet = dynamic_cast<const reco::PFJet*>(&jet);
0127 const auto* pat_jet = dynamic_cast<const pat::Jet*>(&jet);
0128
0129 edm::RefToBase<reco::Jet> jet_ref(jets, jet_n);
0130 if (jet.pt() > min_jet_pt_) {
0131 features.filled();
0132
0133 const edm::View<reco::BoostedDoubleSVTagInfo>& taginfos = *shallow_tag_infos;
0134 edm::Ptr<reco::BoostedDoubleSVTagInfo> match;
0135
0136 if ((jet_n < taginfos.size()) && (taginfos[jet_n].jet() == jet_ref)) {
0137 match = taginfos.ptrAt(jet_n);
0138 } else {
0139
0140 for (auto itTI = taginfos.begin(), edTI = taginfos.end(); itTI != edTI; ++itTI) {
0141 if (itTI->jet() == jet_ref) {
0142 match = taginfos.ptrAt(itTI - taginfos.begin());
0143 break;
0144 }
0145 }
0146 }
0147 reco::BoostedDoubleSVTagInfo tag_info;
0148 if (match.isNonnull()) {
0149 tag_info = *match;
0150 }
0151
0152
0153 btagbtvdeep::JetConverter::jetToFeatures(jet, features.jet_features);
0154
0155
0156 features.npv = vtxs->size();
0157
0158
0159 const auto& tag_info_vars = tag_info.taggingVariables();
0160 btagbtvdeep::doubleBTagToFeatures(tag_info_vars, features.tag_info_features);
0161
0162
0163 auto svs_sorted = *svs;
0164
0165 std::sort(svs_sorted.begin(), svs_sorted.end(), [&pv](const auto& sva, const auto& svb) {
0166 return btagbtvdeep::sv_vertex_comparator(sva, svb, pv);
0167 });
0168
0169 for (const auto& sv : svs_sorted) {
0170 if (reco::deltaR(sv, jet) > jet_radius_)
0171 continue;
0172 else {
0173 features.sv_features.emplace_back();
0174
0175 auto& sv_features = features.sv_features.back();
0176 btagbtvdeep::svToFeatures(sv, pv, jet, sv_features);
0177 }
0178 }
0179
0180
0181 math::XYZVector jet_dir = jet.momentum().Unit();
0182 GlobalVector jet_ref_track_dir(jet.px(), jet.py(), jet.pz());
0183
0184 std::vector<btagbtvdeep::SortingClass<size_t>> c_sorted, n_sorted;
0185 std::vector<int> n_indexes;
0186
0187
0188 std::map<unsigned int, btagbtvdeep::TrackInfoBuilder> trackinfos;
0189
0190
0191 const auto& svs_unsorted = *svs;
0192
0193
0194 std::vector<const reco::Candidate*> daughters;
0195 for (unsigned int i = 0; i < jet.numberOfDaughters(); i++) {
0196 auto const* cand = jet.daughter(i);
0197 auto packed_cand = dynamic_cast<const pat::PackedCandidate*>(cand);
0198 auto reco_cand = dynamic_cast<const reco::PFCandidate*>(cand);
0199 if (packed_cand) {
0200 if (cand->numberOfDaughters() > 0) {
0201 for (unsigned int k = 0; k < cand->numberOfDaughters(); k++) {
0202 daughters.push_back(dynamic_cast<const pat::PackedCandidate*>(cand->daughter(k)));
0203 }
0204 } else {
0205 auto packed_cand = dynamic_cast<const pat::PackedCandidate*>(cand);
0206 daughters.push_back(packed_cand);
0207 }
0208 } else if (reco_cand) {
0209
0210
0211 daughters.push_back(reco_cand);
0212 }
0213 }
0214
0215 std::sort(daughters.begin(), daughters.end(), [](const auto& a, const auto& b) { return a->pt() > b->pt(); });
0216 for (unsigned int i = 0; i < daughters.size(); i++) {
0217 auto const* cand = daughters.at(i);
0218 if (cand) {
0219
0220
0221 if (cand->pt() < min_candidate_pt_)
0222 continue;
0223 if (cand->charge() != 0) {
0224 auto& trackinfo = trackinfos.emplace(i, track_builder).first->second;
0225 trackinfo.buildTrackInfo(cand, jet_dir, jet_ref_track_dir, pv);
0226 c_sorted.emplace_back(i,
0227 trackinfo.getTrackSip2dSig(),
0228 -btagbtvdeep::mindrsvpfcand(svs_unsorted, cand, jet_radius_),
0229 cand->pt() / jet.pt());
0230 } else {
0231 n_sorted.emplace_back(
0232 i, -1, -btagbtvdeep::mindrsvpfcand(svs_unsorted, cand, jet_radius_), cand->pt() / jet.pt());
0233 n_indexes.push_back(i);
0234 }
0235 }
0236 }
0237
0238
0239 std::sort(c_sorted.begin(), c_sorted.end(), btagbtvdeep::SortingClass<std::size_t>::compareByABCInv);
0240 std::sort(n_sorted.begin(), n_sorted.end(), btagbtvdeep::SortingClass<std::size_t>::compareByABCInv);
0241
0242 std::vector<size_t> c_sortedindices, n_sortedindices;
0243
0244
0245 c_sortedindices = btagbtvdeep::invertSortingVector(c_sorted);
0246 n_sortedindices = btagbtvdeep::invertSortingVector(n_sorted);
0247
0248
0249 features.c_pf_features.clear();
0250 features.c_pf_features.resize(c_sorted.size());
0251 features.n_pf_features.clear();
0252 features.n_pf_features.resize(n_sorted.size());
0253
0254 for (unsigned int i = 0; i < daughters.size(); i++) {
0255 auto const* cand = daughters.at(i);
0256 if (cand) {
0257
0258
0259 if (cand->pt() < min_candidate_pt_)
0260 continue;
0261 auto packed_cand = dynamic_cast<const pat::PackedCandidate*>(cand);
0262 auto reco_cand = dynamic_cast<const reco::PFCandidate*>(cand);
0263
0264
0265 reco::PFCandidatePtr reco_ptr;
0266 if (pf_jet) {
0267 reco_ptr = pf_jet->getPFConstituent(i);
0268 } else if (pat_jet && reco_cand) {
0269 reco_ptr = pat_jet->getPFConstituent(i);
0270 }
0271
0272 float puppiw = 1.0;
0273
0274 float drminpfcandsv = btagbtvdeep::mindrsvpfcand(svs_unsorted, cand, jet_radius_);
0275 if (cand->charge() != 0) {
0276
0277 auto entry = c_sortedindices.at(i);
0278
0279 auto& trackinfo = trackinfos.at(i);
0280
0281 auto& c_pf_features = features.c_pf_features.at(entry);
0282 if (packed_cand) {
0283 btagbtvdeep::packedCandidateToFeatures(
0284 packed_cand, *pat_jet, trackinfo, drminpfcandsv, static_cast<float>(jet_radius_), c_pf_features);
0285 } else if (reco_cand) {
0286
0287 int pv_ass_quality = 0;
0288
0289
0290 auto ctrack = reco_cand->bestTrack();
0291 int pvi = -1;
0292 float dist = 1e99;
0293 for (size_t ii = 0; ii < vtxs->size(); ii++) {
0294 float dz = (ctrack) ? std::abs(ctrack->dz(((*vtxs)[ii]).position())) : 0;
0295 if (dz < dist) {
0296 pvi = ii;
0297 dist = dz;
0298 }
0299 }
0300 auto pv = reco::VertexRef(vtxs, pvi);
0301 btagbtvdeep::recoCandidateToFeatures(reco_cand,
0302 jet,
0303 trackinfo,
0304 drminpfcandsv,
0305 static_cast<float>(jet_radius_),
0306 puppiw,
0307 pv_ass_quality,
0308 pv,
0309 c_pf_features);
0310 }
0311 } else {
0312
0313 auto entry = n_sortedindices.at(i);
0314
0315 auto& n_pf_features = features.n_pf_features.at(entry);
0316
0317 if (packed_cand) {
0318 btagbtvdeep::packedCandidateToFeatures(
0319 packed_cand, *pat_jet, drminpfcandsv, static_cast<float>(jet_radius_), n_pf_features);
0320 } else if (reco_cand) {
0321 btagbtvdeep::recoCandidateToFeatures(
0322 reco_cand, jet, drminpfcandsv, static_cast<float>(jet_radius_), puppiw, n_pf_features);
0323 }
0324 }
0325 }
0326 }
0327 }
0328 output_tag_infos->emplace_back(features, jet_ref);
0329 }
0330
0331 iEvent.put(std::move(output_tag_infos));
0332 }
0333
0334
0335 DEFINE_FWK_MODULE(DeepDoubleXTagInfoProducer);