CMS 3D CMS Logo

DeepDoubleXTagInfoProducer.cc
Go to the documentation of this file.
1 
4 
7 
10 
12 
15 
17 
20 
23 
29 
32 
35 
37 
39 {
40 
41 public:
43  ~DeepDoubleXTagInfoProducer() override;
44 
45  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
46 
47 private:
48  typedef std::vector<reco::DeepDoubleXTagInfo> DeepDoubleXTagInfoCollection;
53 
54  void beginStream(edm::StreamID) override
55  {
56  }
57  void produce(edm::Event&, const edm::EventSetup&) override;
58  void endStream() override
59  {
60  }
61 
62  const double jet_radius_;
63  const double min_jet_pt_;
64  const double min_candidate_pt_;
65 
70 };
71 
73  const edm::ParameterSet& iConfig)
74  : jet_radius_(iConfig.getParameter<double>("jet_radius"))
75  , min_jet_pt_(iConfig.getParameter<double>("min_jet_pt"))
76  , min_candidate_pt_(iConfig.getParameter<double>("min_candidate_pt"))
77  , jet_token_(consumes<edm::View<reco::Jet>>(
78  iConfig.getParameter<edm::InputTag>("jets")))
79  , vtx_token_(consumes<VertexCollection>(
80  iConfig.getParameter<edm::InputTag>("vertices")))
81  , sv_token_(consumes<SVCollection>(
82  iConfig.getParameter<edm::InputTag>("secondary_vertices")))
84  iConfig.getParameter<edm::InputTag>("shallow_tag_infos")))
85 {
86  produces<DeepDoubleXTagInfoCollection>();
87 }
88 
90 {
91 }
92 
94  edm::ConfigurationDescriptions& descriptions)
95 {
96  // pfDeepDoubleXTagInfos
98  desc.add<edm::InputTag>("shallow_tag_infos",
99  edm::InputTag("pfBoostedDoubleSVAK8TagInfos"));
100  desc.add<double>("jet_radius", 0.8);
101  desc.add<double>("min_jet_pt", 150);
102  desc.add<double>("min_candidate_pt", 0.95);
103  desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
104  desc.add<edm::InputTag>("secondary_vertices",
105  edm::InputTag("inclusiveCandidateSecondaryVertices"));
106  desc.add<edm::InputTag>("jets", edm::InputTag("ak8PFJetsCHS"));
107  descriptions.add("pfDeepDoubleXTagInfos", desc);
108 }
109 
111  const edm::EventSetup& iSetup)
112 {
113 
114  auto output_tag_infos = std::make_unique<DeepDoubleXTagInfoCollection>();
115 
117  iEvent.getByToken(jet_token_, jets);
118 
120  iEvent.getByToken(vtx_token_, vtxs);
121  if (vtxs->empty())
122  {
123  // produce empty TagInfos in case no primary vertex
124  iEvent.put(std::move(output_tag_infos));
125  return; // exit event
126  }
127  // reference to primary vertex
128  const auto& pv = vtxs->at(0);
129 
131  iEvent.getByToken(sv_token_, svs);
132 
134  iEvent.getByToken(shallow_tag_info_token_, shallow_tag_infos);
135 
137  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",
138  track_builder);
139 
140  for (std::size_t jet_n = 0; jet_n < jets->size(); jet_n++)
141  {
142 
143  // create data containing structure
145 
146  // reco jet reference (use as much as possible)
147  const auto& jet = jets->at(jet_n);
148  const auto* pf_jet = dynamic_cast<const reco::PFJet*>(&jet);
149  const auto* pat_jet = dynamic_cast<const pat::Jet*>(&jet);
150 
151  edm::RefToBase<reco::Jet> jet_ref(jets, jet_n);
152  if (jet.pt() > min_jet_pt_)
153  {
154  features.filled();
155  // TagInfoCollection not in an associative container so search for matchs
158  // Try first by 'same index'
159  if ((jet_n < taginfos.size()) && (taginfos[jet_n].jet() == jet_ref))
160  {
161  match = taginfos.ptrAt(jet_n);
162  }
163  else
164  {
165  // otherwise fall back to a simple search
166  for (auto itTI = taginfos.begin(), edTI = taginfos.end(); itTI != edTI;
167  ++itTI)
168  {
169  if (itTI->jet() == jet_ref)
170  {
171  match = taginfos.ptrAt(itTI - taginfos.begin());
172  break;
173  }
174  }
175  }
177  if (match.isNonnull())
178  {
179  tag_info = *match;
180  } // will be default values otherwise
181 
182  // fill basic jet features
184 
185  // fill number of pv
186  features.npv = vtxs->size();
187 
188  // fill features from BoostedDoubleSVTagInfo
189  const auto& tag_info_vars = tag_info.taggingVariables();
190  btagbtvdeep::doubleBTagToFeatures(tag_info_vars,
191  features.tag_info_features);
192 
193  // copy which will be sorted
194  auto svs_sorted = *svs;
195  // sort by dxy
196  std::sort(svs_sorted.begin(), svs_sorted.end(),
197  [&pv](const auto& sva, const auto& svb) {
198  return btagbtvdeep::sv_vertex_comparator(sva, svb, pv);
199  });
200  // fill features from secondary vertices
201  for (const auto& sv : svs_sorted)
202  {
203  if (reco::deltaR(sv, jet) > jet_radius_)
204  continue;
205  else
206  {
207  features.sv_features.emplace_back();
208  // in C++17 could just get from emplace_back output
209  auto& sv_features = features.sv_features.back();
210  btagbtvdeep::svToFeatures(sv, pv, jet, sv_features);
211  }
212  }
213 
214  // stuff required for dealing with pf candidates
215  math::XYZVector jet_dir = jet.momentum().Unit();
216  GlobalVector jet_ref_track_dir(jet.px(), jet.py(), jet.pz());
217 
218  std::vector<btagbtvdeep::SortingClass<size_t>> c_sorted, n_sorted;
219  std::vector<int> n_indexes;
220 
221  // to cache the TrackInfo
222  std::map<unsigned int, btagbtvdeep::TrackInfoBuilder> trackinfos;
223 
224  // unsorted reference to sv
225  const auto& svs_unsorted = *svs;
226  // fill collection, from DeepTNtuples plus some styling
227  // std::vector<const pat::PackedCandidate*> daughters;
228  std::vector<const reco::Candidate*> daughters;
229  for (unsigned int i = 0; i < jet.numberOfDaughters(); i++)
230  {
231  auto const* cand = jet.daughter(i);
232  auto packed_cand = dynamic_cast<const pat::PackedCandidate*>(cand);
233  auto reco_cand = dynamic_cast<const reco::PFCandidate*>(cand);
234  if (packed_cand)
235  {
236  if (cand->numberOfDaughters() > 0)
237  {
238  for (unsigned int k = 0; k < cand->numberOfDaughters(); k++)
239  {
240  daughters.push_back(
241  dynamic_cast<const pat::PackedCandidate*>(cand->daughter(k)));
242  }
243  }
244  else
245  {
246  auto packed_cand = dynamic_cast<const pat::PackedCandidate*>(cand);
247  daughters.push_back(packed_cand);
248  }
249  }
250  else if (reco_cand)
251  {
252  // need some edm::Ptr or edm::Ref if reco candidates
253  // dynamical casting to pointers, null if not possible
254  daughters.push_back(reco_cand);
255  }
256  }
257 
258  std::sort(daughters.begin(), daughters.end(), [](const auto& a, const auto& b) { return a->pt() > b->pt(); });
259  for (unsigned int i = 0; i < daughters.size(); i++)
260  {
261  auto const* cand = daughters.at(i);
262 
263  if (cand)
264  {
265  // candidates under 950MeV (configurable) are not considered
266  // might change if we use also white-listing
267  if (cand->pt() < min_candidate_pt_)
268  continue;
269  if (cand->charge() != 0)
270  {
271  auto& trackinfo = trackinfos.emplace(i, track_builder).first->second;
272  trackinfo.buildTrackInfo(cand, jet_dir, jet_ref_track_dir, pv);
273  c_sorted.emplace_back(
274  i, trackinfo.getTrackSip2dSig(),
276  cand->pt() / jet.pt());
277  } else {
278  n_sorted.emplace_back(i, -1, -btagbtvdeep::mindrsvpfcand(svs_unsorted, cand, jet_radius_), cand->pt() / jet.pt());
279  n_indexes.push_back(i);
280  }
281  }
282  }
283 
284  // sort collections in added order of priority
285  std::sort(c_sorted.begin(), c_sorted.end(), btagbtvdeep::SortingClass<std::size_t>::compareByABCInv);
286  std::sort(n_sorted.begin(), n_sorted.end(), btagbtvdeep::SortingClass<std::size_t>::compareByABCInv);
287 
288  std::vector<size_t> c_sortedindices, n_sortedindices;
289 
290  // this puts 0 everywhere and the right position in ind
291  c_sortedindices = btagbtvdeep::invertSortingVector(c_sorted);
292  n_sortedindices = btagbtvdeep::invertSortingVector(n_sorted);
293 
294  // set right size to vectors
295  features.c_pf_features.clear();
296  features.c_pf_features.resize(c_sorted.size());
297  features.n_pf_features.clear();
298  features.n_pf_features.resize(n_sorted.size());
299 
300  for (unsigned int i = 0; i < daughters.size(); i++)
301  {
302  auto const* cand = daughters.at(i);
303  if (cand)
304  {
305  // candidates under 950MeV are not considered
306  // might change if we use also white-listing
307  if (cand->pt() < min_candidate_pt_)
308  continue;
309 
310  auto packed_cand = dynamic_cast<const pat::PackedCandidate*>(cand);
311  auto reco_cand = dynamic_cast<const reco::PFCandidate*>(cand);
312 
313  // need some edm::Ptr or edm::Ref if reco candidates
314  reco::PFCandidatePtr reco_ptr;
315  if (pf_jet) {
316  reco_ptr = pf_jet->getPFConstituent(i);
317  } else if (pat_jet && reco_cand) {
318  reco_ptr = pat_jet->getPFConstituent(i);
319  }
320 
321  // get PUPPI weight from value map
322  float puppiw = 1.0; // fallback value
323 
324  float drminpfcandsv = btagbtvdeep::mindrsvpfcand(svs_unsorted, cand, jet_radius_);
325 
326  if (cand->charge() != 0) {
327  // is charged candidate
328  auto entry = c_sortedindices.at(i);
329  // get cached track info
330  auto& trackinfo = trackinfos.at(i);
331  // get_ref to vector element
332  auto& c_pf_features = features.c_pf_features.at(entry);
333  if (packed_cand)
334  {
336  packed_cand, *pat_jet, trackinfo, drminpfcandsv, static_cast<float>(jet_radius_), c_pf_features);
337  }
338  else if (reco_cand)
339  {
340  // get vertex association quality
341  int pv_ass_quality = 0; // fallback value
342  // getting the PV as PackedCandidatesProducer
343  // but using not the slimmed but original vertices
344  auto ctrack = reco_cand->bestTrack();
345  int pvi = -1;
346  float dist = 1e99;
347  for (size_t ii = 0; ii < vtxs->size(); ii++)
348  {
349  float dz = (ctrack) ? std::abs(ctrack->dz(((*vtxs)[ii]).position())) : 0;
350  if (dz < dist)
351  {
352  pvi = ii;
353  dist = dz;
354  }
355  }
356  auto pv = reco::VertexRef(vtxs, pvi);
358  reco_cand, jet, trackinfo, drminpfcandsv,
359  static_cast<float>(jet_radius_), puppiw, pv_ass_quality, pv,
360  c_pf_features);
361  }
362  } else {
363  // is neutral candidate
364  auto entry = n_sortedindices.at(i);
365  // get_ref to vector element
366  auto& n_pf_features = features.n_pf_features.at(entry);
367  // // fill feature structure
368  if (packed_cand) {
370  packed_cand, *pat_jet, drminpfcandsv, static_cast<float>(jet_radius_), n_pf_features);
371  } else if (reco_cand) {
373  reco_cand, jet, drminpfcandsv, static_cast<float>(jet_radius_), puppiw, n_pf_features);
374  }
375  }
376  }
377  }
378  }
379  output_tag_infos->emplace_back(features, jet_ref);
380  }
381 
382  iEvent.put(std::move(output_tag_infos));
383 }
384 
385 // define this as a plug-in
edm::EDGetTokenT< VertexCollection > vtx_token_
edm::View< reco::BoostedDoubleSVTagInfo > BoostedDoubleSVTagInfoCollection
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
Ptr< value_type > ptrAt(size_type i) const
size_type size() const
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
TaggingVariableList taggingVariables(void) const override
returns a description of the extended informations in a TaggingVariableList
void beginStream(edm::StreamID) override
Jets made from PFObjects.
Definition: PFJet.h:21
std::vector< VertexCompositePtrCandidate > VertexCompositePtrCandidateCollection
collection of Candidate objects
std::vector< reco::DeepDoubleXTagInfo > DeepDoubleXTagInfoCollection
float mindrsvpfcand(const std::vector< reco::VertexCompositePtrCandidate > &svs, const reco::Candidate *cand, float mindr=0.4)
Definition: deep_helpers.cc:73
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const_iterator begin() const
void doubleBTagToFeatures(const reco::TaggingVariableList &tag_info_vars, BoostedDoubleSVTagInfoFeatures &tag_info_features)
Definition: Jet.py:1
vector< PseudoJet > jets
def pv(vc)
Definition: MetAnalyzer.py:7
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
BoostedDoubleSVTagInfoFeatures tag_info_features
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::Ref< VertexCollection > VertexRef
persistent reference to a Vertex
Definition: VertexFwd.h:13
reco::VertexCollection VertexCollection
ii
Definition: cuy.py:590
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:168
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:28
int k[5][pyjets_maxn]
void packedCandidateToFeatures(const pat::PackedCandidate *c_pf, const pat::Jet &jet, const TrackInfoBuilder &track_info, const float drminpfcandsv, const float jetR, ChargedCandidateFeatures &c_pf_features, const bool flip=false)
DeepDoubleXTagInfoProducer(const edm::ParameterSet &)
edm::EDGetTokenT< SVCollection > sv_token_
bool sv_vertex_comparator(const SVType &sva, const SVType &svb, const PVType &pv)
Definition: deep_helpers.h:43
void recoCandidateToFeatures(const reco::PFCandidate *c_pf, const reco::Jet &jet, const TrackInfoBuilder &track_info, const float drminpfcandsv, const float jetR, const float puppiw, const int pv_ass_quality, const reco::VertexRef &pv, ChargedCandidateFeatures &c_pf_features, const bool flip=false)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
static void jetToFeatures(const reco::Jet &jet, JetFeatures &jet_features)
Definition: JetConverter.h:13
void produce(edm::Event &, const edm::EventSetup &) override
double b
Definition: hdecay.h:120
Analysis-level calorimeter jet class.
Definition: Jet.h:80
void add(std::string const &label, ParameterSetDescription const &psetDescription)
std::vector< std::size_t > invertSortingVector(const std::vector< SortingClass< std::size_t > > &in)
edm::EDGetTokenT< BoostedDoubleSVTagInfoCollection > shallow_tag_info_token_
void svToFeatures(const reco::VertexCompositePtrCandidate &sv, const reco::Vertex &pv, const reco::Jet &jet, SecondaryVertexFeatures &sv_features, const bool flip=false)
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
fixed size matrix
HLT enums.
double a
Definition: hdecay.h:121
T get() const
Definition: EventSetup.h:71
std::vector< ChargedCandidateFeatures > c_pf_features
const_iterator end() const
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
std::vector< NeutralCandidateFeatures > n_pf_features
std::vector< SecondaryVertexFeatures > sv_features
edm::EDGetTokenT< edm::View< reco::Jet > > jet_token_
reco::VertexCompositePtrCandidateCollection SVCollection
def move(src, dest)
Definition: eostools.py:511