CMS 3D CMS Logo

DeepFlavourTagInfoProducer.cc
Go to the documentation of this file.
1 
4 
7 
10 
13 
15 
18 
21 
27 
30 
33 
35 
39 
45 
50 #include <typeinfo>
57 
59 
60  public:
62  ~DeepFlavourTagInfoProducer() override;
63 
64  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
65 
66  private:
67  typedef std::vector<reco::DeepFlavourTagInfo> DeepFlavourTagInfoCollection;
71 
72  void beginStream(edm::StreamID) override {}
73  void produce(edm::Event&, const edm::EventSetup&) override;
74  void endStream() override {}
75 
76 
77  const double jet_radius_;
78  const double min_candidate_pt_;
79  const bool flip_;
80 
89 
92 
95 
97 
98  //TrackProbability
99  void checkEventSetup(const edm::EventSetup& iSetup);
100  std::unique_ptr<HistogramProbabilityEstimator> probabilityEstimator_;
102  unsigned long long calibrationCacheId2D_;
103  unsigned long long calibrationCacheId3D_;
104 
105  const double min_jet_pt_;
106  const double max_jet_eta_;
107 
108 
109 };
110 
112  jet_radius_(iConfig.getParameter<double>("jet_radius")),
113  min_candidate_pt_(iConfig.getParameter<double>("min_candidate_pt")),
114  flip_(iConfig.getParameter<bool>("flip")),
115  jet_token_(consumes<edm::View<reco::Jet> >(iConfig.getParameter<edm::InputTag>("jets"))),
116  vtx_token_(consumes<VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"))),
117  sv_token_(consumes<SVCollection>(iConfig.getParameter<edm::InputTag>("secondary_vertices"))),
118  shallow_tag_info_token_(consumes<ShallowTagInfoCollection>(iConfig.getParameter<edm::InputTag>("shallow_tag_infos"))),
119  candidateToken_(consumes<edm::View<reco::Candidate>>(iConfig.getParameter<edm::InputTag>("candidates"))),
122  fallback_puppi_weight_(iConfig.getParameter<bool>("fallback_puppi_weight")),
123  fallback_vertex_association_(iConfig.getParameter<bool>("fallback_vertex_association")),
124  run_deepVertex_(iConfig.getParameter<bool>("run_deepVertex")),
125  compute_probabilities_(iConfig.getParameter<bool>("compute_probabilities")),
126  min_jet_pt_(iConfig.getParameter<double>("min_jet_pt")),
127  max_jet_eta_(iConfig.getParameter<double>("max_jet_eta"))
128 {
129  produces<DeepFlavourTagInfoCollection>();
130 
131  const auto & puppi_value_map_tag = iConfig.getParameter<edm::InputTag>("puppi_value_map");
132  if (!puppi_value_map_tag.label().empty()) {
133  puppi_value_map_token_ = consumes<edm::ValueMap<float>>(puppi_value_map_tag);
134  use_puppi_value_map_ = true;
135  }
136 
137  const auto & pvas_tag = iConfig.getParameter<edm::InputTag>("vertex_associator");
138  if (!pvas_tag.label().empty()) {
139  pvasq_value_map_token_ = consumes<edm::ValueMap<int>>(pvas_tag);
140  pvas_token_ = consumes<edm::Association<VertexCollection>>(pvas_tag);
141  use_pvasq_value_map_ = true;
142  }
143 
144 }
145 
146 
148 {
149 }
150 
152 {
153  // pfDeepFlavourTagInfos
155  desc.add<edm::InputTag>("shallow_tag_infos", edm::InputTag("pfDeepCSVTagInfos"));
156  desc.add<double>("jet_radius", 0.4);
157  desc.add<double>("min_candidate_pt", 0.95);
158  desc.add<bool>("flip", false);
159  desc.add<edm::InputTag>("vertices", edm::InputTag("offlinePrimaryVertices"));
160  desc.add<edm::InputTag>("puppi_value_map", edm::InputTag("puppi"));
161  desc.add<edm::InputTag>("secondary_vertices", edm::InputTag("inclusiveCandidateSecondaryVertices"));
162  desc.add<edm::InputTag>("jets", edm::InputTag("ak4PFJetsCHS"));
163  desc.add<edm::InputTag>("candidates", edm::InputTag("packedPFCandidates"));
164  desc.add<edm::InputTag>("vertex_associator", edm::InputTag("primaryVertexAssociation","original"));
165  desc.add<bool>("fallback_puppi_weight", false);
166  desc.add<bool>("fallback_vertex_association", false);
167  desc.add<bool>("run_deepVertex", false);
168  desc.add<bool>("compute_probabilities", false);
169  desc.add<double>("min_jet_pt", 15.0);
170  desc.add<double>("max_jet_eta", 2.5);
171  descriptions.add("pfDeepFlavourTagInfos", desc);
172 }
173 
175 {
176 
177  auto output_tag_infos = std::make_unique<DeepFlavourTagInfoCollection>();
179 
181  iEvent.getByToken(jet_token_, jets);
182 
184  iEvent.getByToken(vtx_token_, vtxs);
185  if (vtxs->empty()) {
186  // produce empty TagInfos in case no primary vertex
187  iEvent.put(std::move(output_tag_infos));
188  return; // exit event
189  }
190  // reference to primary vertex
191  const auto & pv = vtxs->at(0);
192 
194  iEvent.getByToken(candidateToken_, tracks);
195 
197  iEvent.getByToken(sv_token_, svs);
198 
200  iEvent.getByToken(shallow_tag_info_token_, shallow_tag_infos);
201  double negative_cut = 0;//used only with flip_
202  if (flip_){//FIXME: Check if can do even less often than once per event
203  const edm::Provenance *prov = shallow_tag_infos.provenance();
204  const edm::ParameterSet& psetFromProvenance = edm::parameterSet(*prov);
205  negative_cut = ( ( psetFromProvenance.getParameter<edm::ParameterSet>("computer")
206  ).getParameter<edm::ParameterSet>("trackSelection")
207  ).getParameter<double>("sip3dSigMax");
208  }
209 
210 
211  edm::Handle<edm::ValueMap<float>> puppi_value_map;
212  if (use_puppi_value_map_) {
213  iEvent.getByToken(puppi_value_map_token_, puppi_value_map);
214  }
215 
216  edm::Handle<edm::ValueMap<int>> pvasq_value_map;
218  if (use_pvasq_value_map_) {
219  iEvent.getByToken(pvasq_value_map_token_, pvasq_value_map);
220  iEvent.getByToken(pvas_token_, pvas);
221  }
222 
224  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", track_builder);
225 
226  std::vector<reco::TransientTrack> selectedTracks;
227  std::vector<float> masses;
228 
229  if (run_deepVertex_) //make a collection of selected transient tracks for deepvertex outside of the jet loop
230  {
231  for(typename edm::View<reco::Candidate>::const_iterator track = tracks->begin(); track != tracks->end(); ++track) {
232  unsigned int k = track - tracks->begin();
233  if(track->bestTrack() != nullptr && track->pt()>0.5) {
234  if (std::fabs(track->vz()-pv.z())<0.5) {
235  selectedTracks.push_back(track_builder->build(tracks->ptrAt(k)));
236  masses.push_back(track->mass()); }
237  }
238  }
239  }
240 
241  for (std::size_t jet_n = 0; jet_n < jets->size(); jet_n++) {
242 
243  // create data containing structure
245 
246  // reco jet reference (use as much as possible)
247  const auto & jet = jets->at(jet_n);
248  // dynamical casting to pointers, null if not possible
249  const auto * pf_jet = dynamic_cast<const reco::PFJet *>(&jet);
250  const auto * pat_jet = dynamic_cast<const pat::Jet *>(&jet);
251  edm::RefToBase<reco::Jet> jet_ref(jets, jet_n);
252  // TagInfoCollection not in an associative container so search for matchs
255  // Try first by 'same index'
256  if ((jet_n < taginfos.size()) && (taginfos[jet_n].jet() == jet_ref)) {
257  match = taginfos.ptrAt(jet_n);
258  } else {
259  // otherwise fail back to a simple search
260  for (auto itTI = taginfos.begin(), edTI = taginfos.end(); itTI != edTI; ++itTI) {
261  if (itTI->jet() == jet_ref) { match = taginfos.ptrAt( itTI - taginfos.begin() ); break; }
262  }
263  }
264  reco::ShallowTagInfo tag_info;
265  if (match.isNonnull()) {
266  tag_info = *match;
267  } // will be default values otherwise
268 
269  // fill basic jet features
271 
272  // fill number of pv
273  features.npv = vtxs->size();
274  math::XYZVector jet_dir = jet.momentum().Unit();
275  GlobalVector jet_ref_track_dir(jet.px(),
276  jet.py(),
277  jet.pz());
278 
279  // fill features from ShallowTagInfo
280  const auto & tag_info_vars = tag_info.taggingVariables();
281  btagbtvdeep::bTagToFeatures(tag_info_vars, features.tag_info_features);
282 
283  // copy which will be sorted
284  auto svs_sorted = *svs;
285  // sort by dxy
286  std::sort(svs_sorted.begin(), svs_sorted.end(),
287  [&pv](const auto & sva, const auto &svb)
288  { return btagbtvdeep::sv_vertex_comparator(sva, svb, pv); });
289  // fill features from secondary vertices
290  for (const auto & sv : svs_sorted) {
291  if (reco::deltaR2(sv, jet_dir) > (jet_radius_*jet_radius_)) continue;
292  else {
293  features.sv_features.emplace_back();
294  // in C++17 could just get from emplace_back output
295  auto & sv_features = features.sv_features.back();
296  btagbtvdeep::svToFeatures(sv, pv, jet, sv_features, flip_);
297  }
298  }
299 
300  // stuff required for dealing with pf candidates
301 
302  std::vector<btagbtvdeep::SortingClass<size_t> > c_sorted, n_sorted;
303 
304  // to cache the TrackInfo
305  std::map<unsigned int, btagbtvdeep::TrackInfoBuilder> trackinfos;
306 
307  // unsorted reference to sv
308  const auto & svs_unsorted = *svs;
309  // fill collection, from DeepTNtuples plus some styling
310  for (unsigned int i = 0; i < jet.numberOfDaughters(); i++){
311  auto cand = jet.daughter(i);
312  if(cand){
313  // candidates under 950MeV (configurable) are not considered
314  // might change if we use also white-listing
315  if (cand->pt()< min_candidate_pt_) continue;
316  if (cand->charge() != 0) {
317  auto & trackinfo = trackinfos.emplace(i,track_builder).first->second;
318  trackinfo.buildTrackInfo(cand,jet_dir,jet_ref_track_dir,pv);
319  c_sorted.emplace_back(i, trackinfo.getTrackSip2dSig(),
320  -btagbtvdeep::mindrsvpfcand(svs_unsorted,cand), cand->pt()/jet.pt());
321  } else {
322  n_sorted.emplace_back(i, -1,
323  -btagbtvdeep::mindrsvpfcand(svs_unsorted,cand), cand->pt()/jet.pt());
324  }
325  }
326  }
327 
328  // sort collections (open the black-box if you please)
329  std::sort(c_sorted.begin(),c_sorted.end(),
331  std::sort(n_sorted.begin(),n_sorted.end(),
333 
334  std::vector<size_t> c_sortedindices,n_sortedindices;
335 
336  // this puts 0 everywhere and the right position in ind
337  c_sortedindices=btagbtvdeep::invertSortingVector(c_sorted);
338  n_sortedindices=btagbtvdeep::invertSortingVector(n_sorted);
339 
340  // set right size to vectors
341  features.c_pf_features.clear();
342  features.c_pf_features.resize(c_sorted.size());
343  features.n_pf_features.clear();
344  features.n_pf_features.resize(n_sorted.size());
345 
346 
347  for (unsigned int i = 0; i < jet.numberOfDaughters(); i++){
348 
349  // get pointer and check that is correct
350  auto cand = dynamic_cast<const reco::Candidate *>(jet.daughter(i));
351  if(!cand) continue;
352  // candidates under 950MeV are not considered
353  // might change if we use also white-listing
354  if (cand->pt()<0.95) continue;
355 
356  auto packed_cand = dynamic_cast<const pat::PackedCandidate *>(cand);
357  auto reco_cand = dynamic_cast<const reco::PFCandidate *>(cand);
358 
359  // need some edm::Ptr or edm::Ref if reco candidates
360  reco::PFCandidatePtr reco_ptr;
361  if (pf_jet) {
362  reco_ptr = pf_jet->getPFConstituent(i);
363  } else if (pat_jet && reco_cand) {
364  reco_ptr = pat_jet->getPFConstituent(i);
365  }
366  // get PUPPI weight from value map
367  float puppiw = 1.0; // fallback value
368  if (reco_cand && use_puppi_value_map_) {
369  puppiw = (*puppi_value_map)[reco_ptr];
370  } else if (reco_cand && !fallback_puppi_weight_) {
371  throw edm::Exception(edm::errors::InvalidReference, "PUPPI value map missing") <<
372  "use fallback_puppi_weight option to use " << puppiw << "as default";
373  }
374 
375  float drminpfcandsv = btagbtvdeep::mindrsvpfcand(svs_unsorted, cand);
376 
377  if (cand->charge() != 0) {
378  // is charged candidate
379  auto entry = c_sortedindices.at(i);
380  // get cached track info
381  auto & trackinfo = trackinfos.at(i);
382  if(flip_ && (trackinfo.getTrackSip3dSig() > negative_cut)){continue;}
383  // get_ref to vector element
384  auto & c_pf_features = features.c_pf_features.at(entry);
385  // fill feature structure
386  if (packed_cand) {
388  drminpfcandsv, static_cast<float> (jet_radius_), c_pf_features, flip_);
389  } else if (reco_cand) {
390  // get vertex association quality
391  int pv_ass_quality = 0; // fallback value
392  if (use_pvasq_value_map_) {
393  pv_ass_quality = (*pvasq_value_map)[reco_ptr];
394  } else if (!fallback_vertex_association_) {
395  throw edm::Exception(edm::errors::InvalidReference, "vertex association missing") <<
396  "use fallback_vertex_association option to use" << pv_ass_quality <<
397  "as default quality and closest dz PV as criteria";
398  }
399  // getting the PV as PackedCandidatesProducer
400  // but using not the slimmed but original vertices
401  auto ctrack = reco_cand->bestTrack();
402  int pvi=-1;
403  float dist=1e99;
404  for(size_t ii=0;ii<vtxs->size();ii++){
405  float dz = (ctrack) ? std::abs(ctrack->dz(((*vtxs)[ii]).position())) : 0;
406  if(dz<dist) {pvi=ii;dist=dz; }
407  }
408  auto PV = reco::VertexRef(vtxs, pvi);
409  if (use_pvasq_value_map_) {
410  const reco::VertexRef & PV_orig = (*pvas)[reco_ptr];
411  if(PV_orig.isNonnull()) PV = reco::VertexRef(vtxs, PV_orig.key());
412  }
414  drminpfcandsv, static_cast<float> (jet_radius_), puppiw,
415  pv_ass_quality, PV, c_pf_features, flip_);
416  }
417  } else {
418  // is neutral candidate
419  auto entry = n_sortedindices.at(i);
420  // get_ref to vector element
421  auto & n_pf_features = features.n_pf_features.at(entry);
422  // fill feature structure
423  if (packed_cand) {
424  btagbtvdeep::packedCandidateToFeatures(packed_cand, jet, drminpfcandsv, static_cast<float> (jet_radius_),
425  n_pf_features);
426  } else if (reco_cand) {
427  btagbtvdeep::recoCandidateToFeatures(reco_cand, jet, drminpfcandsv, static_cast<float> (jet_radius_), puppiw,
428  n_pf_features);
429  }
430  }
431 
432 
433  }
434 
435  if (run_deepVertex_)
436  {
437  if (jet.pt()>min_jet_pt_ && std::fabs(jet.eta())<max_jet_eta_) //jet thresholds
439  }
440 
441  output_tag_infos->emplace_back(features, jet_ref);
442 
443  }
444 
445  iEvent.put(std::move(output_tag_infos));
446 
447 }
448 
449 
451  using namespace edm;
452  using namespace edm::eventsetup;
453 
454  const EventSetupRecord & re2D= iSetup.get<BTagTrackProbability2DRcd>();
455  const EventSetupRecord & re3D= iSetup.get<BTagTrackProbability3DRcd>();
456  unsigned long long cacheId2D= re2D.cacheIdentifier();
457  unsigned long long cacheId3D= re3D.cacheIdentifier();
458  if(cacheId2D!=calibrationCacheId2D_ || cacheId3D!=calibrationCacheId3D_ ) //Calibration changed
459  {
461  iSetup.get<BTagTrackProbability2DRcd>().get(calib2DHandle);
463  iSetup.get<BTagTrackProbability3DRcd>().get(calib3DHandle);
464  probabilityEstimator_.reset(new HistogramProbabilityEstimator(calib3DHandle.product(),calib2DHandle.product()));
465 
466  }
467 
468  calibrationCacheId3D_=cacheId3D;
469  calibrationCacheId2D_=cacheId2D;
470 
471 }
472 
473 //define this as a plug-in
T getParameter(std::string const &) const
unsigned long long cacheIdentifier() const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
reco::VertexCompositePtrCandidateCollection SVCollection
reco::VertexCollection VertexCollection
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:251
ShallowTagInfoFeatures tag_info_features
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
Ptr< value_type > ptrAt(size_type i) const
edm::View< reco::ShallowTagInfo > ShallowTagInfoCollection
std::vector< NeutralCandidateFeatures > n_pf_features
void produce(edm::Event &, const edm::EventSetup &) override
std::vector< SecondaryVertexFeatures > sv_features
reco::TransientTrack build(const reco::Track *p) const
size_type size() const
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
std::vector< ChargedCandidateFeatures > c_pf_features
key_type key() const
Accessor for product key.
Definition: Ref.h:263
Jets made from PFObjects.
Definition: PFJet.h:21
std::vector< VertexCompositePtrCandidate > VertexCompositePtrCandidateCollection
collection of Candidate objects
void checkEventSetup(const edm::EventSetup &iSetup)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
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
std::unique_ptr< HistogramProbabilityEstimator > probabilityEstimator_
Definition: Jet.py:1
vector< PseudoJet > jets
edm::EDGetTokenT< edm::ValueMap< float > > puppi_value_map_token_
def pv(vc)
Definition: MetAnalyzer.py:7
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::Ref< VertexCollection > VertexRef
persistent reference to a Vertex
Definition: VertexFwd.h:13
edm::EDGetTokenT< ShallowTagInfoCollection > shallow_tag_info_token_
edm::EDGetTokenT< SVCollection > sv_token_
TaggingVariableList taggingVariables(void) const override
returns a description of the extended informations in a TaggingVariableList
void beginStream(edm::StreamID) override
ii
Definition: cuy.py:590
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:168
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)
edm::EDGetTokenT< edm::View< reco::Candidate > > candidateToken_
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
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
edm::EDGetTokenT< edm::View< reco::Jet > > jet_token_
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)
DeepFlavourTagInfoProducer(const edm::ParameterSet &)
void seedingTracksToFeatures(const std::vector< reco::TransientTrack > &selectedTracks, const std::vector< float > &masses, const reco::Jet &jet, const reco::Vertex &pv, HistogramProbabilityEstimator *probabilityEstimator, bool computeProbabilities, std::vector< btagbtvdeep::SeedingTrackFeatures > &seedingT_features_vector)
void svToFeatures(const reco::VertexCompositePtrCandidate &sv, const reco::Vertex &pv, const reco::Jet &jet, SecondaryVertexFeatures &sv_features, const bool flip=false)
edm::EDGetTokenT< edm::Association< VertexCollection > > pvas_token_
edm::EDGetTokenT< edm::ValueMap< int > > pvasq_value_map_token_
edm::EDGetTokenT< VertexCollection > vtx_token_
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:40
fixed size matrix
HLT enums.
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:86
T get() const
Definition: EventSetup.h:71
std::vector< reco::DeepFlavourTagInfo > DeepFlavourTagInfoCollection
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
void bTagToFeatures(const reco::TaggingVariableList &tag_info_vars, ShallowTagInfoFeatures &tag_info_features)
std::vector< SeedingTrackFeatures > seed_features
T const * product() const
Definition: ESHandle.h:86
ParameterSet const & parameterSet(Provenance const &provenance)
Definition: Provenance.cc:11
def move(src, dest)
Definition: eostools.py:511
Provenance const * provenance() const
Definition: HandleBase.h:83