CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TemplatedSecondaryVertexProducer.cc
Go to the documentation of this file.
1 #include <functional>
2 #include <algorithm>
3 #include <iterator>
4 #include <cstddef>
5 #include <string>
6 #include <vector>
7 #include <map>
8 #include <set>
9 
10 #include <boost/iterator/transform_iterator.hpp>
11 
23 
27 
32 
40 
45 
51 
53 
54 #include "fastjet/JetDefinition.hh"
55 #include "fastjet/ClusterSequence.hh"
56 #include "fastjet/PseudoJet.hh"
57 
58 //
59 // constants, enums and typedefs
60 //
61 typedef boost::shared_ptr<fastjet::ClusterSequence> ClusterSequencePtr;
62 typedef boost::shared_ptr<fastjet::JetDefinition> JetDefPtr;
63 
64 
65 using namespace reco;
66 
67 namespace {
68  class VertexInfo : public fastjet::PseudoJet::UserInfoBase{
69  public:
70  VertexInfo(const int vertexIndex) :
71  m_vertexIndex(vertexIndex) { }
72 
73  inline const int vertexIndex() const { return m_vertexIndex; }
74 
75  protected:
76  int m_vertexIndex;
77  };
78 
79  template<typename T>
80  struct RefToBaseLess : public std::binary_function<edm::RefToBase<T>,
81  edm::RefToBase<T>,
82  bool> {
83  inline bool operator()(const edm::RefToBase<T> &r1,
84  const edm::RefToBase<T> &r2) const
85  {
86  return r1.id() < r2.id() ||
87  (r1.id() == r2.id() && r1.key() < r2.key());
88  }
89  };
90 }
91 
93 return GlobalVector(sv.x() - pv.x(), sv.y() - pv.y(),sv.z() - pv.z());
94 }
96 return GlobalVector(sv.vertex().x() - pv.x(), sv.vertex().y() - pv.y(),sv.vertex().z() - pv.z());
97 }
99 {return sv.position();}
101 {return sv.vertex();}
102 
103 
104 template <class IPTI,class VTX>
106  public:
107  explicit TemplatedSecondaryVertexProducer(const edm::ParameterSet &params);
109  static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
110  typedef std::vector<TemplatedSecondaryVertexTagInfo<IPTI,VTX> > Product;
112  typedef typename IPTI::input_container input_container;
114  typedef typename std::vector<reco::btag::IndexedTrackData> TrackDataVector;
115  virtual void produce(edm::Event &event, const edm::EventSetup &es) override;
116 
117  private:
118  template<class CONTAINER>
119  void matchReclusteredJets(const edm::Handle<CONTAINER>& jets,
120  const std::vector<fastjet::PseudoJet>& matchedJets,
121  std::vector<int>& matchedIndices,
122  const std::string& jetType="");
123  void matchGroomedJets(const edm::Handle<edm::View<reco::Jet> >& jets,
124  const edm::Handle<edm::View<reco::Jet> >& matchedJets,
125  std::vector<int>& matchedIndices);
126  void matchSubjets(const std::vector<int>& groomedIndices,
127  const edm::Handle<edm::View<reco::Jet> >& groomedJets,
128  const edm::Handle<std::vector<IPTI> >& subjets,
129  std::vector<std::vector<int> >& matchedIndices);
130 
131  const reco::Jet * toJet(const reco::Jet & j) { return &j; }
132  const reco::Jet * toJet(const IPTI & j) { return &(*(j.jet())); }
133 
135  CONSTRAINT_NONE = 0,
140  CONSTRAINT_PV_PRIMARIES_IN_FIT
141  };
142  static ConstraintType getConstraintType(const std::string &name);
143 
162  double rParam;
163  double jetPtMin;
169 
172 
173  void markUsedTracks(TrackDataVector & trackData, const input_container & trackRefs, const SecondaryVertex & sv,size_t idx);
174 
175  struct SVBuilder :
176  public std::unary_function<const VTX&, SecondaryVertex> {
177 
179  const GlobalVector &direction,
180  bool withPVError,
181  double minTrackWeight) :
182  pv(pv), direction(direction),
183  withPVError(withPVError),
184  minTrackWeight(minTrackWeight) {}
185  SecondaryVertex operator () (const TransientVertex &sv) const;
186 
187  SecondaryVertex operator () (const VTX &sv) const
188  { return SecondaryVertex(pv, sv, direction, withPVError); }
189 
190 
191  const Vertex &pv;
195  };
196 
197  struct SVFilter :
198  public std::unary_function<const SecondaryVertex&, bool> {
199 
201  const GlobalVector &direction) :
202  filter(filter), pv(pv), direction(direction) {}
203 
204  inline bool operator () (const SecondaryVertex &sv) const
205  { return !filter(pv, sv, direction); }
206 
208  const Vertex &pv;
210  };
211 };
212 template <class IPTI,class VTX>
215 {
216  if (name == "None")
217  return CONSTRAINT_NONE;
218  else if (name == "BeamSpot")
219  return CONSTRAINT_BEAMSPOT;
220  else if (name == "BeamSpot+PVPosition")
221  return CONSTRAINT_PV_BEAMSPOT_SIZE;
222  else if (name == "BeamSpotZ+PVErrorScaledXY")
223  return CONSTRAINT_PV_BS_Z_ERRORS_SCALED;
224  else if (name == "PVErrorScaled")
225  return CONSTRAINT_PV_ERROR_SCALED;
226  else if (name == "BeamSpot+PVTracksInFit")
227  return CONSTRAINT_PV_PRIMARIES_IN_FIT;
228  else
229  throw cms::Exception("InvalidArgument")
230  << "TemplatedSecondaryVertexProducer: ``constraint'' parameter "
231  "value \"" << name << "\" not understood."
232  << std::endl;
233 }
234 
237 {
238  if (name == "AlwaysWithGhostTrack")
240  else if (name == "SingleTracksWithGhostTrack")
242  else if (name == "RefitGhostTrackWithVertices")
244  else
245  throw cms::Exception("InvalidArgument")
246  << "TemplatedSecondaryVertexProducer: ``fitType'' "
247  "parameter value \"" << name << "\" for "
248  "GhostTrackVertexFinder settings not "
249  "understood." << std::endl;
250 }
251 
252 template <class IPTI,class VTX>
254  const edm::ParameterSet &params) :
255  sortCriterium(TrackSorting::getCriterium(params.getParameter<std::string>("trackSort"))),
256  trackSelector(params.getParameter<edm::ParameterSet>("trackSelection")),
257  constraint(getConstraintType(params.getParameter<std::string>("constraint"))),
258  constraintScaling(1.0),
259  vtxRecoPSet(params.getParameter<edm::ParameterSet>("vertexReco")),
260  useGhostTrack(vtxRecoPSet.getParameter<std::string>("finder") == "gtvr"),
261  withPVError(params.getParameter<bool>("usePVError")),
262  minTrackWeight(params.getParameter<double>("minimumTrackWeight")),
263  vertexFilter(params.getParameter<edm::ParameterSet>("vertexCuts")),
264  vertexSorting(params.getParameter<edm::ParameterSet>("vertexSelection"))
265 {
266  token_trackIPTagInfo = consumes<std::vector<IPTI> >(params.getParameter<edm::InputTag>("trackIPTagInfos"));
269  constraintScaling = params.getParameter<double>("pvErrorScaling");
270 
275  token_BeamSpot = consumes<reco::BeamSpot>(params.getParameter<edm::InputTag>("beamSpotTag"));
276  useExternalSV = false;
277  if(params.existsAs<bool>("useExternalSV")) useExternalSV = params.getParameter<bool> ("useExternalSV");
278  if(useExternalSV) {
279  token_extSVCollection = consumes<edm::View<VTX> >(params.getParameter<edm::InputTag>("extSVCollection"));
280  extSVDeltaRToJet = params.getParameter<double>("extSVDeltaRToJet");
281  }
282  useSVClustering = ( params.existsAs<bool>("useSVClustering") ? params.getParameter<bool>("useSVClustering") : false );
283  useSVMomentum = ( params.existsAs<bool>("useSVMomentum") ? params.getParameter<bool>("useSVMomentum") : false );
284  useFatJets = ( useExternalSV && useSVClustering && params.exists("fatJets") && params.exists("groomedFatJets") );
285  if( useSVClustering )
286  {
287  jetAlgorithm = params.getParameter<std::string>("jetAlgorithm");
288  rParam = params.getParameter<double>("rParam");
289  jetPtMin = 0.; // hardcoded to 0. since we simply want to recluster all input jets which already had some PtMin applied
290  ghostRescaling = ( params.existsAs<double>("ghostRescaling") ? params.getParameter<double>("ghostRescaling") : 1e-18 );
291  relPtTolerance = ( params.existsAs<double>("relPtTolerance") ? params.getParameter<double>("relPtTolerance") : 1e-03); // 0.1% relative difference in Pt should be sufficient to detect possible misconfigurations
292 
293  // set jet algorithm
294  if (jetAlgorithm=="Kt")
295  fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::kt_algorithm, rParam) );
296  else if (jetAlgorithm=="CambridgeAachen")
297  fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::cambridge_algorithm, rParam) );
298  else if (jetAlgorithm=="AntiKt")
299  fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm, rParam) );
300  else
301  throw cms::Exception("InvalidJetAlgorithm") << "Jet clustering algorithm is invalid: " << jetAlgorithm << ", use CambridgeAachen | Kt | AntiKt" << std::endl;
302  }
303  if( useFatJets )
304  {
305  token_fatJets = consumes<edm::View<reco::Jet> >(params.getParameter<edm::InputTag>("fatJets"));
306  token_groomedFatJets = consumes<edm::View<reco::Jet> >(params.getParameter<edm::InputTag>("groomedFatJets"));
307  }
308 
309  produces<Product>();
310 }
311 template <class IPTI,class VTX>
313 {
314 }
315 
316 template <class IPTI,class VTX>
318  const edm::EventSetup &es)
319 {
320 // typedef std::map<TrackBaseRef, TransientTrack,
321 // RefToBaseLess<Track> > TransientTrackMap;
322  //How about good old pointers?
323  typedef std::map<const Track *, TransientTrack> TransientTrackMap;
324 
325 
327  es.get<TransientTrackRecord>().get("TransientTrackBuilder",
328  trackBuilder);
329 
331  event.getByToken(token_trackIPTagInfo, trackIPTagInfos);
332 
333  // External Sec Vertex collection (e.g. for IVF usage)
334  edm::Handle<edm::View<VTX> > extSecVertex;
335  if(useExternalSV) event.getByToken(token_extSVCollection,extSecVertex);
336 
337  edm::Handle<edm::View<reco::Jet> > fatJetsHandle;
338  edm::Handle<edm::View<reco::Jet> > groomedFatJetsHandle;
339  if( useFatJets )
340  {
341  event.getByToken(token_fatJets, fatJetsHandle);
342  event.getByToken(token_groomedFatJets, groomedFatJetsHandle);
343 
344  if( groomedFatJetsHandle->size() > fatJetsHandle->size() )
345  edm::LogError("TooManyGroomedJets") << "There are more groomed (" << groomedFatJetsHandle->size() << ") than original fat jets (" << fatJetsHandle->size() << "). Please check that the two jet collections belong to each other.";
346  }
347 
349  unsigned int bsCovSrc[7] = { 0, };
350  double sigmaZ = 0.0, beamWidth = 0.0;
351  switch(constraint) {
352  case CONSTRAINT_PV_BEAMSPOT_SIZE:
353  event.getByToken(token_BeamSpot,beamSpot);
354  bsCovSrc[3] = bsCovSrc[4] = bsCovSrc[5] = bsCovSrc[6] = 1;
355  sigmaZ = beamSpot->sigmaZ();
356  beamWidth = beamSpot->BeamWidthX();
357  break;
358 
359  case CONSTRAINT_PV_BS_Z_ERRORS_SCALED:
360  event.getByToken(token_BeamSpot,beamSpot);
361  bsCovSrc[0] = bsCovSrc[1] = 2;
362  bsCovSrc[3] = bsCovSrc[4] = bsCovSrc[5] = 1;
363  sigmaZ = beamSpot->sigmaZ();
364  break;
365 
366  case CONSTRAINT_PV_ERROR_SCALED:
367  bsCovSrc[0] = bsCovSrc[1] = bsCovSrc[2] = 2;
368  break;
369 
370  case CONSTRAINT_BEAMSPOT:
371  case CONSTRAINT_PV_PRIMARIES_IN_FIT:
372  event.getByToken(token_BeamSpot,beamSpot);
373  break;
374 
375  default:
376  /* nothing */;
377  }
378 
379  // ------------------------------------ SV clustering START --------------------------------------------
380  std::vector<std::vector<int> > clusteredSVs(trackIPTagInfos->size(),std::vector<int>());
381  if( useExternalSV && useSVClustering && trackIPTagInfos->size()>0 )
382  {
383  // vector of constituents for reclustering jets and "ghost" SVs
384  std::vector<fastjet::PseudoJet> fjInputs;
385  // loop over all input jets and collect all their constituents
386  if( useFatJets )
387  {
388  for(edm::View<reco::Jet>::const_iterator it = fatJetsHandle->begin(); it != fatJetsHandle->end(); ++it)
389  {
390  std::vector<edm::Ptr<reco::Candidate> > constituents = it->getJetConstituents();
391  std::vector<edm::Ptr<reco::Candidate> >::const_iterator m;
392  for( m = constituents.begin(); m != constituents.end(); ++m )
393  {
394  reco::CandidatePtr constit = *m;
395  if(constit->pt() == 0)
396  {
397  edm::LogWarning("NullTransverseMomentum") << "dropping input candidate with pt=0";
398  continue;
399  }
400  fjInputs.push_back(fastjet::PseudoJet(constit->px(),constit->py(),constit->pz(),constit->energy()));
401  }
402  }
403  }
404  else
405  {
406  for(typename std::vector<IPTI>::const_iterator it = trackIPTagInfos->begin(); it != trackIPTagInfos->end(); ++it)
407  {
408  std::vector<edm::Ptr<reco::Candidate> > constituents = it->jet()->getJetConstituents();
409  std::vector<edm::Ptr<reco::Candidate> >::const_iterator m;
410  for( m = constituents.begin(); m != constituents.end(); ++m )
411  {
412  reco::CandidatePtr constit = *m;
413  if(constit->pt() == 0)
414  {
415  edm::LogWarning("NullTransverseMomentum") << "dropping input candidate with pt=0";
416  continue;
417  }
418  fjInputs.push_back(fastjet::PseudoJet(constit->px(),constit->py(),constit->pz(),constit->energy()));
419  }
420  }
421  }
422  // insert "ghost" SVs in the vector of constituents
423  for(typename edm::View<VTX>::const_iterator it = extSecVertex->begin(); it != extSecVertex->end(); ++it)
424  {
425  const reco::Vertex &pv = *(trackIPTagInfos->front().primaryVertex());
426  GlobalVector dir = flightDirection(pv, *it);
427  dir = dir.unit();
428  fastjet::PseudoJet p(dir.x(),dir.y(),dir.z(),dir.mag()); // using SV flight direction so treating SV as massless
429  if( useSVMomentum )
430  p = fastjet::PseudoJet(it->p4().px(),it->p4().py(),it->p4().pz(),it->p4().energy());
431  p*=ghostRescaling; // rescale SV direction/momentum
432  p.set_user_info(new VertexInfo( it - extSecVertex->begin() ));
433  fjInputs.push_back(p);
434  }
435 
436  // define jet clustering sequence
437  fjClusterSeq = ClusterSequencePtr( new fastjet::ClusterSequence( fjInputs, *fjJetDefinition ) );
438  // recluster jet constituents and inserted "ghosts"
439  std::vector<fastjet::PseudoJet> inclusiveJets = fastjet::sorted_by_pt( fjClusterSeq->inclusive_jets(jetPtMin) );
440 
441  if( useFatJets )
442  {
443  if( inclusiveJets.size() < fatJetsHandle->size() )
444  edm::LogError("TooFewReclusteredJets") << "There are fewer reclustered (" << inclusiveJets.size() << ") than original fat jets (" << fatJetsHandle->size() << "). Please check that the jet algorithm and jet size match those used for the original jet collection.";
445 
446  // match reclustered and original fat jets
447  std::vector<int> reclusteredIndices;
448  matchReclusteredJets<edm::View<reco::Jet> >(fatJetsHandle,inclusiveJets,reclusteredIndices,"fat");
449 
450  // match groomed and original fat jets
451  std::vector<int> groomedIndices;
452  matchGroomedJets(fatJetsHandle,groomedFatJetsHandle,groomedIndices);
453 
454  // match subjets and original fat jets
455  std::vector<std::vector<int> > subjetIndices;
456  matchSubjets(groomedIndices,groomedFatJetsHandle,trackIPTagInfos,subjetIndices);
457 
458  // collect clustered SVs
459  for(size_t i=0; i<fatJetsHandle->size(); ++i)
460  {
461  if( reclusteredIndices.at(i) < 0 ) continue; // continue if matching reclustered to original jets failed
462 
463  if( fatJetsHandle->at(i).pt() == 0 ) // continue if the original jet has Pt=0
464  {
465  edm::LogWarning("NullTransverseMomentum") << "The original fat jet " << i << " has Pt=0. This is not expected so the jet will be skipped.";
466  continue;
467  }
468 
469  if( subjetIndices.at(i).size()==0 ) continue; // continue if the original jet does not have subjets assigned
470 
471  // since the "ghosts" are extremely soft, the configuration and ordering of the reclustered and original fat jets should in principle stay the same
472  if( ( std::abs( inclusiveJets.at(reclusteredIndices.at(i)).pt() - fatJetsHandle->at(i).pt() ) / fatJetsHandle->at(i).pt() ) > relPtTolerance )
473  {
474  if( fatJetsHandle->at(i).pt() < 10. ) // special handling for low-Pt jets (Pt<10 GeV)
475  edm::LogWarning("JetPtMismatchAtLowPt") << "The reclustered and original fat jet " << i << " have different Pt's (" << inclusiveJets.at(reclusteredIndices.at(i)).pt() << " vs " << fatJetsHandle->at(i).pt() << " GeV, respectively).\n"
476  << "Please check that the jet algorithm and jet size match those used for the original fat jet collection and also make sure the original fat jets are uncorrected. In addition, make sure you are not using CaloJets which are presently not supported.\n"
477  << "Since the mismatch is at low Pt, it is ignored and only a warning is issued.\n"
478  << "\nIn extremely rare instances the mismatch could be caused by a difference in the machine precision in which case make sure the original jet collection is produced and reclustering is performed in the same job.";
479  else
480  edm::LogError("JetPtMismatch") << "The reclustered and original fat jet " << i << " have different Pt's (" << inclusiveJets.at(reclusteredIndices.at(i)).pt() << " vs " << fatJetsHandle->at(i).pt() << " GeV, respectively).\n"
481  << "Please check that the jet algorithm and jet size match those used for the original fat jet collection and also make sure the original fat jets are uncorrected. In addition, make sure you are not using CaloJets which are presently not supported.\n"
482  << "\nIn extremely rare instances the mismatch could be caused by a difference in the machine precision in which case make sure the original jet collection is produced and reclustering is performed in the same job.";
483  }
484 
485  // get jet constituents
486  std::vector<fastjet::PseudoJet> constituents = inclusiveJets.at(reclusteredIndices.at(i)).constituents();
487 
488  std::vector<int> svIndices;
489  // loop over jet constituents and try to find "ghosts"
490  for(std::vector<fastjet::PseudoJet>::const_iterator it = constituents.begin(); it != constituents.end(); ++it)
491  {
492  if( !it->has_user_info() ) continue; // skip if not a "ghost"
493 
494  svIndices.push_back( it->user_info<VertexInfo>().vertexIndex() );
495  }
496 
497  // loop over clustered SVs and assign them to different subjets based on smallest dR
498  for(size_t sv=0; sv<svIndices.size(); ++sv)
499  {
500  const reco::Vertex &pv = *(trackIPTagInfos->front().primaryVertex());
501  const VTX &extSV = (*extSecVertex)[ svIndices.at(sv) ];
502  GlobalVector dir = flightDirection(pv, extSV);
503  dir = dir.unit();
504  fastjet::PseudoJet p(dir.x(),dir.y(),dir.z(),dir.mag()); // using SV flight direction so treating SV as massless
505  if( useSVMomentum )
506  p = fastjet::PseudoJet(extSV.p4().px(),extSV.p4().py(),extSV.p4().pz(),extSV.p4().energy());
507 
508  std::vector<double> dR2toSubjets;
509 
510  for(size_t sj=0; sj<subjetIndices.at(i).size(); ++sj)
511  dR2toSubjets.push_back( Geom::deltaR2( p.rapidity(), p.phi_std(), trackIPTagInfos->at(subjetIndices.at(i).at(sj)).jet()->rapidity(), trackIPTagInfos->at(subjetIndices.at(i).at(sj)).jet()->phi() ) );
512 
513  // find the closest subjet
514  int closestSubjetIdx = std::distance( dR2toSubjets.begin(), std::min_element(dR2toSubjets.begin(), dR2toSubjets.end()) );
515 
516  clusteredSVs.at(subjetIndices.at(i).at(closestSubjetIdx)).push_back( svIndices.at(sv) );
517  }
518  }
519  }
520  else
521  {
522  if( inclusiveJets.size() < trackIPTagInfos->size() )
523  edm::LogError("TooFewReclusteredJets") << "There are fewer reclustered (" << inclusiveJets.size() << ") than original jets (" << trackIPTagInfos->size() << "). Please check that the jet algorithm and jet size match those used for the original jet collection.";
524 
525  // match reclustered and original jets
526  std::vector<int> reclusteredIndices;
527  matchReclusteredJets<std::vector<IPTI> >(trackIPTagInfos,inclusiveJets,reclusteredIndices);
528 
529  // collect clustered SVs
530  for(size_t i=0; i<trackIPTagInfos->size(); ++i)
531  {
532  if( reclusteredIndices.at(i) < 0 ) continue; // continue if matching reclustered to original jets failed
533 
534  if( trackIPTagInfos->at(i).jet()->pt() == 0 ) // continue if the original jet has Pt=0
535  {
536  edm::LogWarning("NullTransverseMomentum") << "The original jet " << i << " has Pt=0. This is not expected so the jet will be skipped.";
537  continue;
538  }
539 
540  // since the "ghosts" are extremely soft, the configuration and ordering of the reclustered and original jets should in principle stay the same
541  if( ( std::abs( inclusiveJets.at(reclusteredIndices.at(i)).pt() - trackIPTagInfos->at(i).jet()->pt() ) / trackIPTagInfos->at(i).jet()->pt() ) > relPtTolerance )
542  {
543  if( trackIPTagInfos->at(i).jet()->pt() < 10. ) // special handling for low-Pt jets (Pt<10 GeV)
544  edm::LogWarning("JetPtMismatchAtLowPt") << "The reclustered and original jet " << i << " have different Pt's (" << inclusiveJets.at(reclusteredIndices.at(i)).pt() << " vs " << trackIPTagInfos->at(i).jet()->pt() << " GeV, respectively).\n"
545  << "Please check that the jet algorithm and jet size match those used for the original jet collection and also make sure the original jets are uncorrected. In addition, make sure you are not using CaloJets which are presently not supported.\n"
546  << "Since the mismatch is at low Pt, it is ignored and only a warning is issued.\n"
547  << "\nIn extremely rare instances the mismatch could be caused by a difference in the machine precision in which case make sure the original jet collection is produced and reclustering is performed in the same job.";
548  else
549  edm::LogError("JetPtMismatch") << "The reclustered and original jet " << i << " have different Pt's (" << inclusiveJets.at(reclusteredIndices.at(i)).pt() << " vs " << trackIPTagInfos->at(i).jet()->pt() << " GeV, respectively).\n"
550  << "Please check that the jet algorithm and jet size match those used for the original jet collection and also make sure the original jets are uncorrected. In addition, make sure you are not using CaloJets which are presently not supported.\n"
551  << "\nIn extremely rare instances the mismatch could be caused by a difference in the machine precision in which case make sure the original jet collection is produced and reclustering is performed in the same job.";
552  }
553 
554  // get jet constituents
555  std::vector<fastjet::PseudoJet> constituents = inclusiveJets.at(reclusteredIndices.at(i)).constituents();
556 
557  // loop over jet constituents and try to find "ghosts"
558  for(std::vector<fastjet::PseudoJet>::const_iterator it = constituents.begin(); it != constituents.end(); ++it)
559  {
560  if( !it->has_user_info() ) continue; // skip if not a "ghost"
561  // push back clustered SV indices
562  clusteredSVs.at(i).push_back( it->user_info<VertexInfo>().vertexIndex() );
563  }
564  }
565  }
566  }
567  // ------------------------------------ SV clustering END ----------------------------------------------
568 
569  std::auto_ptr<ConfigurableVertexReconstructor> vertexReco;
570  std::auto_ptr<GhostTrackVertexFinder> vertexRecoGT;
571  if (useGhostTrack)
572  vertexRecoGT.reset(new GhostTrackVertexFinder(
573  vtxRecoPSet.getParameter<double>("maxFitChi2"),
574  vtxRecoPSet.getParameter<double>("mergeThreshold"),
575  vtxRecoPSet.getParameter<double>("primcut"),
576  vtxRecoPSet.getParameter<double>("seccut"),
577  getGhostTrackFitType(vtxRecoPSet.getParameter<std::string>("fitType"))));
578  else
579  vertexReco.reset(
580  new ConfigurableVertexReconstructor(vtxRecoPSet));
581 
582  TransientTrackMap primariesMap;
583 
584  // result secondary vertices
585 
586  std::auto_ptr<Product> tagInfos(new Product);
587 
588  for(typename std::vector<IPTI>::const_iterator iterJets =
589  trackIPTagInfos->begin(); iterJets != trackIPTagInfos->end();
590  ++iterJets) {
591  TrackDataVector trackData;
592 // std::cout << "Jet " << iterJets-trackIPTagInfos->begin() << std::endl;
593 
594  const Vertex &pv = *iterJets->primaryVertex();
595 
596  std::set<TransientTrack> primaries;
597  if (constraint == CONSTRAINT_PV_PRIMARIES_IN_FIT) {
598  for(Vertex::trackRef_iterator iter = pv.tracks_begin();
599  iter != pv.tracks_end(); ++iter) {
600  TransientTrackMap::iterator pos =
601  primariesMap.lower_bound(iter->get());
602 
603  if (pos != primariesMap.end() &&
604  pos->first == iter->get())
605  primaries.insert(pos->second);
606  else {
607  TransientTrack track =
608  trackBuilder->build(
609  iter->castTo<TrackRef>());
610  primariesMap.insert(pos,
611  std::make_pair(iter->get(), track));
612  primaries.insert(track);
613  }
614  }
615  }
616 
617  edm::RefToBase<Jet> jetRef = iterJets->jet();
618 
619  GlobalVector jetDir(jetRef->momentum().x(),
620  jetRef->momentum().y(),
621  jetRef->momentum().z());
622 
623  std::vector<std::size_t> indices =
624  iterJets->sortedIndexes(sortCriterium);
625 
626  input_container trackRefs = iterJets->sortedTracks(indices);
627 
628  const std::vector<reco::btag::TrackIPData> &ipData =
629  iterJets->impactParameterData();
630 
631  // build transient tracks used for vertex reconstruction
632 
633  std::vector<TransientTrack> fitTracks;
634  std::vector<GhostTrackState> gtStates;
635  std::auto_ptr<GhostTrackPrediction> gtPred;
636  if (useGhostTrack)
637  gtPred.reset(new GhostTrackPrediction(
638  *iterJets->ghostTrack()));
639 
640  for(unsigned int i = 0; i < indices.size(); i++) {
642 
643  const input_item &trackRef = trackRefs[i];
644 
645  trackData.push_back(IndexedTrackData());
646  trackData.back().first = indices[i];
647 
648  // select tracks for SV finder
649 
650  if (!trackSelector(*reco::btag::toTrack(trackRef), ipData[indices[i]], *jetRef,
652  pv.position()))) {
653  trackData.back().second.svStatus =
655  continue;
656  }
657 
658  TransientTrackMap::const_iterator pos =
659  primariesMap.find(reco::btag::toTrack((trackRef)));
660  TransientTrack fitTrack;
661  if (pos != primariesMap.end()) {
662  primaries.erase(pos->second);
663  fitTrack = pos->second;
664  } else
665  fitTrack = trackBuilder->build(trackRef);
666  fitTracks.push_back(fitTrack);
667 
668  trackData.back().second.svStatus =
670 
671  if (useGhostTrack) {
672  GhostTrackState gtState(fitTrack);
673  GlobalPoint pos =
674  ipData[indices[i]].closestToGhostTrack;
675  gtState.linearize(*gtPred, true,
676  gtPred->lambda(pos));
677  gtState.setWeight(ipData[indices[i]].ghostTrackWeight);
678  gtStates.push_back(gtState);
679  }
680  }
681 
682  std::auto_ptr<GhostTrack> ghostTrack;
683  if (useGhostTrack)
684  ghostTrack.reset(new GhostTrack(
688  GlobalVector(
689  iterJets->ghostTrack()->px(),
690  iterJets->ghostTrack()->py(),
691  iterJets->ghostTrack()->pz()),
692  0.05),
693  *gtPred, gtStates,
694  iterJets->ghostTrack()->chi2(),
695  iterJets->ghostTrack()->ndof()));
696 
697  // perform actual vertex finding
698 
699 
700  std::vector<VTX> extAssoCollection;
701  std::vector<TransientVertex> fittedSVs;
702  std::vector<SecondaryVertex> SVs;
703  if(!useExternalSV){
704  switch(constraint) {
705  case CONSTRAINT_NONE:
706  if (useGhostTrack)
707  fittedSVs = vertexRecoGT->vertices(
708  pv, *ghostTrack);
709  else
710  fittedSVs = vertexReco->vertices(fitTracks);
711  break;
712 
713  case CONSTRAINT_BEAMSPOT:
714  if (useGhostTrack)
715  fittedSVs = vertexRecoGT->vertices(
716  pv, *beamSpot, *ghostTrack);
717  else
718  fittedSVs = vertexReco->vertices(fitTracks,
719  *beamSpot);
720  break;
721 
722  case CONSTRAINT_PV_BEAMSPOT_SIZE:
723  case CONSTRAINT_PV_BS_Z_ERRORS_SCALED:
724  case CONSTRAINT_PV_ERROR_SCALED: {
726  for(unsigned int i = 0; i < 7; i++) {
727  unsigned int covSrc = bsCovSrc[i];
728  for(unsigned int j = 0; j < 7; j++) {
729  double v=0.0;
730  if (!covSrc || bsCovSrc[j] != covSrc)
731  v = 0.0;
732  else if (covSrc == 1)
733  v = beamSpot->covariance(i, j);
734  else if (j<3 && i<3)
735  v = pv.covariance(i, j) *
736  constraintScaling;
737  cov(i, j) = v;
738  }
739  }
740 
741  BeamSpot bs(pv.position(), sigmaZ,
742  beamSpot.isValid() ? beamSpot->dxdz() : 0.,
743  beamSpot.isValid() ? beamSpot->dydz() : 0.,
744  beamWidth, cov, BeamSpot::Unknown);
745 
746  if (useGhostTrack)
747  fittedSVs = vertexRecoGT->vertices(
748  pv, bs, *ghostTrack);
749  else
750  fittedSVs = vertexReco->vertices(fitTracks, bs);
751  } break;
752 
753  case CONSTRAINT_PV_PRIMARIES_IN_FIT: {
754  std::vector<TransientTrack> primaries_(
755  primaries.begin(), primaries.end());
756  if (useGhostTrack)
757  fittedSVs = vertexRecoGT->vertices(
758  pv, *beamSpot, primaries_,
759  *ghostTrack);
760  else
761  fittedSVs = vertexReco->vertices(
762  primaries_, fitTracks,
763  *beamSpot);
764  } break;
765  }
766  // build combined SV information and filter
767  SVBuilder svBuilder(pv, jetDir, withPVError, minTrackWeight);
768  std::remove_copy_if(boost::make_transform_iterator(
769  fittedSVs.begin(), svBuilder),
770  boost::make_transform_iterator(
771  fittedSVs.end(), svBuilder),
772  std::back_inserter(SVs),
773  SVFilter(vertexFilter, pv, jetDir));
774 
775  }else{
776  if( !useSVClustering ) {
777  for(size_t iExtSv = 0; iExtSv < extSecVertex->size(); iExtSv++){
778  const VTX & extVertex = (*extSecVertex)[iExtSv];
779  if( Geom::deltaR2( ( position(extVertex) - pv.position() ), jetDir ) > extSVDeltaRToJet*extSVDeltaRToJet || extVertex.p4().M() < 0.3 )
780  continue;
781  extAssoCollection.push_back( extVertex );
782  }
783 
784  }
785  else {
786  size_t jetIdx = ( iterJets - trackIPTagInfos->begin() );
787 
788  for(size_t iExtSv = 0; iExtSv < clusteredSVs.at(jetIdx).size(); iExtSv++){
789  const VTX & extVertex = (*extSecVertex)[ clusteredSVs.at(jetIdx).at(iExtSv) ];
790  if( extVertex.p4().M() < 0.3 )
791  continue;
792  extAssoCollection.push_back( extVertex );
793  }
794  }
795  // build combined SV information and filter
796  SVBuilder svBuilder(pv, jetDir, withPVError, minTrackWeight);
797  std::remove_copy_if(boost::make_transform_iterator( extAssoCollection.begin(), svBuilder),
798  boost::make_transform_iterator(extAssoCollection.end(), svBuilder),
799  std::back_inserter(SVs),
800  SVFilter(vertexFilter, pv, jetDir));
801  }
802  // clean up now unneeded collections
803  gtPred.reset();
804  ghostTrack.reset();
805  gtStates.clear();
806  fitTracks.clear();
807  fittedSVs.clear();
808  extAssoCollection.clear();
809 
810  // sort SVs by importance
811 
812  std::vector<unsigned int> vtxIndices = vertexSorting(SVs);
813 
814  std::vector<typename TemplatedSecondaryVertexTagInfo<IPTI,VTX>::VertexData> svData;
815 
816  svData.resize(vtxIndices.size());
817  for(unsigned int idx = 0; idx < vtxIndices.size(); idx++) {
818  const SecondaryVertex &sv = SVs[vtxIndices[idx]];
819 
820  svData[idx].vertex = sv;
821  svData[idx].dist2d = sv.dist2d();
822  svData[idx].dist3d = sv.dist3d();
823  svData[idx].direction = flightDirection(pv,sv);
824  // mark tracks successfully used in vertex fit
825  markUsedTracks(trackData,trackRefs,sv,idx);
826  }
827 
828  // fill result into tag infos
829 
830  tagInfos->push_back(
832  trackData, svData, SVs.size(),
834  iterJets - trackIPTagInfos->begin())));
835  }
836 
837  event.put(tagInfos);
838 }
839 
840 //Need specialized template because reco::Vertex iterators are TrackBase and it is a mess to make general
841 template <>
843 {
844  for(Vertex::trackRef_iterator iter = sv.tracks_begin(); iter != sv.tracks_end(); ++iter) {
845  if (sv.trackWeight(*iter) < minTrackWeight)
846  continue;
847 
848  typename input_container::const_iterator pos =
849  std::find(trackRefs.begin(), trackRefs.end(),
850  iter->castTo<input_item>());
851 
852  if (pos == trackRefs.end() ) {
853  if(!useExternalSV)
854  throw cms::Exception("TrackNotFound")
855  << "Could not find track from secondary "
856  "vertex in original tracks."
857  << std::endl;
858  } else {
859  unsigned int index = pos - trackRefs.begin();
860  trackData[index].second.svStatus =
862  ((unsigned int)btag::TrackData::trackAssociatedToVertex + idx);
863  }
864  }
865 }
866 template <>
868 {
869  for(typename input_container::const_iterator iter = sv.daughterPtrVector().begin(); iter != sv.daughterPtrVector().end(); ++iter)
870  {
871  typename input_container::const_iterator pos =
872  std::find(trackRefs.begin(), trackRefs.end(), *iter);
873 
874  if (pos != trackRefs.end() )
875  {
876  unsigned int index = pos - trackRefs.begin();
877  trackData[index].second.svStatus =
879  ((unsigned int)btag::TrackData::trackAssociatedToVertex + idx);
880  }
881  }
882 }
883 
884 
885 template <>
888 {
889  if(sv.originalTracks().size()>0 && sv.originalTracks()[0].trackBaseRef().isNonnull())
890  return SecondaryVertex(pv, sv, direction, withPVError);
891  else
892  {
893  edm::LogError("UnexpectedInputs") << "Building from Candidates, should not happen!";
894  return SecondaryVertex(pv, sv, direction, withPVError);
895  }
896 }
897 
898 template <>
901 {
902  if(sv.originalTracks().size()>0 && sv.originalTracks()[0].trackBaseRef().isNonnull())
903  {
904  edm::LogError("UnexpectedInputs") << "Building from Tracks, should not happen!";
905  VertexCompositePtrCandidate vtxCompPtrCand;
906 
907  vtxCompPtrCand.setCovariance(sv.vertexState().error().matrix_new());
908  vtxCompPtrCand.setChi2AndNdof(sv.totalChiSquared(), sv.degreesOfFreedom());
909  vtxCompPtrCand.setVertex(Candidate::Point(sv.position().x(),sv.position().y(),sv.position().z()));
910 
911  return SecondaryVertex(pv, vtxCompPtrCand, direction, withPVError);
912  }
913  else
914  {
915  VertexCompositePtrCandidate vtxCompPtrCand;
916 
917  vtxCompPtrCand.setCovariance(sv.vertexState().error().matrix_new());
918  vtxCompPtrCand.setChi2AndNdof(sv.totalChiSquared(), sv.degreesOfFreedom());
919  vtxCompPtrCand.setVertex(Candidate::Point(sv.position().x(),sv.position().y(),sv.position().z()));
920 
922  for(std::vector<reco::TransientTrack>::const_iterator tt = sv.originalTracks().begin(); tt != sv.originalTracks().end(); ++tt)
923  {
924  if (sv.trackWeight(*tt) < minTrackWeight)
925  continue;
926 
927  const CandidatePtrTransientTrack* cptt = dynamic_cast<const CandidatePtrTransientTrack*>(tt->basicTransientTrack());
928  if ( cptt==0 )
929  edm::LogError("DynamicCastingFailed") << "Casting of TransientTrack to CandidatePtrTransientTrack failed!";
930  else
931  {
932  p4 += cptt->candidate()->p4();
933  vtxCompPtrCand.addDaughter(cptt->candidate());
934  }
935  }
936  vtxCompPtrCand.setP4(p4);
937 
938  return SecondaryVertex(pv, vtxCompPtrCand, direction, withPVError);
939  }
940 }
941 
942 // ------------ method that matches reclustered and original jets based on minimum dR ------------
943 template<class IPTI,class VTX>
944 template<class CONTAINER>
946  const std::vector<fastjet::PseudoJet>& reclusteredJets,
947  std::vector<int>& matchedIndices,
948  const std::string& jetType)
949 {
950  std::string type = ( jetType!="" ? jetType + " " : jetType );
951 
952  std::vector<bool> matchedLocks(reclusteredJets.size(),false);
953 
954  for(size_t j=0; j<jets->size(); ++j)
955  {
956  double matchedDR2 = 1e9;
957  int matchedIdx = -1;
958 
959  for(size_t rj=0; rj<reclusteredJets.size(); ++rj)
960  {
961  if( matchedLocks.at(rj) ) continue; // skip jets that have already been matched
962 
963  double tempDR2 = Geom::deltaR2( toJet(jets->at(j))->rapidity(), toJet(jets->at(j))->phi(), reclusteredJets.at(rj).rapidity(), reclusteredJets.at(rj).phi_std() );
964  if( tempDR2 < matchedDR2 )
965  {
966  matchedDR2 = tempDR2;
967  matchedIdx = rj;
968  }
969  }
970 
971  if( matchedIdx>=0 )
972  {
973  if ( matchedDR2 > rParam*rParam )
974  {
975  edm::LogError("JetMatchingFailed") << "Matched reclustered jet " << matchedIdx << " and original " << type << "jet " << j <<" are separated by dR=" << sqrt(matchedDR2) << " which is greater than the jet size R=" << rParam << ".\n"
976  << "This is not expected so please check that the jet algorithm and jet size match those used for the original " << type << "jet collection.";
977  }
978  else
979  matchedLocks.at(matchedIdx) = true;
980  }
981  else
982  edm::LogError("JetMatchingFailed") << "Matching reclustered to original " << type << "jets failed. Please check that the jet algorithm and jet size match those used for the original " << type << "jet collection.";
983 
984  matchedIndices.push_back(matchedIdx);
985  }
986 }
987 
988 // ------------ method that matches groomed and original jets based on minimum dR ------------
989 template<class IPTI,class VTX>
991  const edm::Handle<edm::View<reco::Jet> >& groomedJets,
992  std::vector<int>& matchedIndices)
993 {
994  std::vector<bool> jetLocks(jets->size(),false);
995  std::vector<int> jetIndices;
996 
997  for(size_t gj=0; gj<groomedJets->size(); ++gj)
998  {
999  double matchedDR2 = 1e9;
1000  int matchedIdx = -1;
1001 
1002  if( groomedJets->at(gj).pt()>0. ) // skip pathological cases of groomed jets with Pt=0
1003  {
1004  for(size_t j=0; j<jets->size(); ++j)
1005  {
1006  if( jetLocks.at(j) ) continue; // skip jets that have already been matched
1007 
1008  double tempDR2 = Geom::deltaR2( jets->at(j).rapidity(), jets->at(j).phi(), groomedJets->at(gj).rapidity(), groomedJets->at(gj).phi() );
1009  if( tempDR2 < matchedDR2 )
1010  {
1011  matchedDR2 = tempDR2;
1012  matchedIdx = j;
1013  }
1014  }
1015  }
1016 
1017  if( matchedIdx>=0 )
1018  {
1019  if ( matchedDR2 > rParam*rParam )
1020  {
1021  edm::LogWarning("MatchedJetsFarApart") << "Matched groomed jet " << gj << " and original jet " << matchedIdx <<" are separated by dR=" << sqrt(matchedDR2) << " which is greater than the jet size R=" << rParam << ".\n"
1022  << "This is not expected so the matching of these two jets has been discarded. Please check that the two jet collections belong to each other.";
1023  matchedIdx = -1;
1024  }
1025  else
1026  jetLocks.at(matchedIdx) = true;
1027  }
1028  jetIndices.push_back(matchedIdx);
1029  }
1030 
1031  for(size_t j=0; j<jets->size(); ++j)
1032  {
1033  std::vector<int>::iterator matchedIndex = std::find( jetIndices.begin(), jetIndices.end(), j );
1034 
1035  matchedIndices.push_back( matchedIndex != jetIndices.end() ? std::distance(jetIndices.begin(),matchedIndex) : -1 );
1036  }
1037 }
1038 
1039 // ------------ method that matches subjets and original fat jets ------------
1040 template<class IPTI,class VTX>
1041 void TemplatedSecondaryVertexProducer<IPTI,VTX>::matchSubjets(const std::vector<int>& groomedIndices,
1042  const edm::Handle<edm::View<reco::Jet> >& groomedJets,
1043  const edm::Handle<std::vector<IPTI> >& subjets,
1044  std::vector<std::vector<int> >& matchedIndices)
1045 {
1046  for(size_t g=0; g<groomedIndices.size(); ++g)
1047  {
1048  std::vector<int> subjetIndices;
1049 
1050  if( groomedIndices.at(g)>=0 )
1051  {
1052  for(size_t s=0; s<groomedJets->at(groomedIndices.at(g)).numberOfDaughters(); ++s)
1053  {
1054  const edm::Ptr<reco::Candidate> & subjet = groomedJets->at(groomedIndices.at(g)).daughterPtr(s);
1055 
1056  for(size_t sj=0; sj<subjets->size(); ++sj)
1057  {
1058  const edm::RefToBase<reco::Jet> &subjetRef = subjets->at(sj).jet();
1059  if( subjet == edm::Ptr<reco::Candidate>( subjetRef.id(), subjetRef.get(), subjetRef.key() ) )
1060  {
1061  subjetIndices.push_back(sj);
1062  break;
1063  }
1064  }
1065  }
1066 
1067  if( subjetIndices.size() == 0 )
1068  edm::LogError("SubjetMatchingFailed") << "Matching subjets to original fat jets failed. Please check that the groomed fat jet and subjet collections belong to each other.";
1069 
1070  matchedIndices.push_back(subjetIndices);
1071  }
1072  else
1073  matchedIndices.push_back(subjetIndices);
1074  }
1075 }
1076 
1077 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
1078 template<class IPTI,class VTX>
1080 
1082  desc.add<double>("extSVDeltaRToJet",0.3);
1083  desc.add<edm::InputTag>("beamSpotTag",edm::InputTag("offlineBeamSpot"));
1084  {
1086  vertexReco.add<double>("primcut",1.8);
1087  vertexReco.add<double>("seccut",6.0);
1088  vertexReco.add<std::string>("finder","avr");
1089  vertexReco.addOptionalNode( edm::ParameterDescription<double>("minweight",0.5, true) and
1090  edm::ParameterDescription<double>("weightthreshold",0.001, true) and
1091  edm::ParameterDescription<bool>("smoothing",false, true), true );
1092  vertexReco.addOptionalNode( edm::ParameterDescription<double>("maxFitChi2",10.0, true) and
1093  edm::ParameterDescription<double>("mergeThreshold",3.0, true) and
1094  edm::ParameterDescription<std::string>("fitType","RefitGhostTrackWithVertices", true), true );
1095  desc.add<edm::ParameterSetDescription>("vertexReco",vertexReco);
1096  }
1097  {
1099  vertexSelection.add<std::string>("sortCriterium","dist3dError");
1100  desc.add<edm::ParameterSetDescription>("vertexSelection",vertexSelection);
1101  }
1102  desc.add<std::string>("constraint","BeamSpot");
1103  desc.add<edm::InputTag>("trackIPTagInfos",edm::InputTag("impactParameterTagInfos"));
1104  {
1106  vertexCuts.add<double>("distSig3dMax",99999.9);
1107  vertexCuts.add<double>("fracPV",0.65);
1108  vertexCuts.add<double>("distVal2dMax",2.5);
1109  vertexCuts.add<bool>("useTrackWeights",true);
1110  vertexCuts.add<double>("maxDeltaRToJetAxis",0.4);
1111  {
1113  v0Filter.add<double>("k0sMassWindow",0.05);
1114  vertexCuts.add<edm::ParameterSetDescription>("v0Filter",v0Filter);
1115  }
1116  vertexCuts.add<double>("distSig2dMin",3.0);
1117  vertexCuts.add<unsigned int>("multiplicityMin",2);
1118  vertexCuts.add<double>("distVal2dMin",0.01);
1119  vertexCuts.add<double>("distSig2dMax",99999.9);
1120  vertexCuts.add<double>("distVal3dMax",99999.9);
1121  vertexCuts.add<double>("minimumTrackWeight",0.5);
1122  vertexCuts.add<double>("distVal3dMin",-99999.9);
1123  vertexCuts.add<double>("massMax",6.5);
1124  vertexCuts.add<double>("distSig3dMin",-99999.9);
1125  desc.add<edm::ParameterSetDescription>("vertexCuts",vertexCuts);
1126  }
1127  desc.add<bool>("useExternalSV",false);
1128  desc.add<double>("minimumTrackWeight",0.5);
1129  desc.add<bool>("usePVError",true);
1130  {
1132  trackSelection.add<double>("b_pT",0.3684);
1133  trackSelection.add<double>("max_pT",500);
1134  trackSelection.add<bool>("useVariableJTA",false);
1135  trackSelection.add<double>("maxDecayLen",99999.9);
1136  trackSelection.add<double>("sip3dValMin",-99999.9);
1137  trackSelection.add<double>("max_pT_dRcut",0.1);
1138  trackSelection.add<double>("a_pT",0.005263);
1139  trackSelection.add<unsigned int>("totalHitsMin",8);
1140  trackSelection.add<double>("jetDeltaRMax",0.3);
1141  trackSelection.add<double>("a_dR",-0.001053);
1142  trackSelection.add<double>("maxDistToAxis",0.2);
1143  trackSelection.add<double>("ptMin",1.0);
1144  trackSelection.add<std::string>("qualityClass","any");
1145  trackSelection.add<unsigned int>("pixelHitsMin",2);
1146  trackSelection.add<double>("sip2dValMax",99999.9);
1147  trackSelection.add<double>("max_pT_trackPTcut",3);
1148  trackSelection.add<double>("sip2dValMin",-99999.9);
1149  trackSelection.add<double>("normChi2Max",99999.9);
1150  trackSelection.add<double>("sip3dValMax",99999.9);
1151  trackSelection.add<double>("sip3dSigMin",-99999.9);
1152  trackSelection.add<double>("min_pT",120);
1153  trackSelection.add<double>("min_pT_dRcut",0.5);
1154  trackSelection.add<double>("sip2dSigMax",99999.9);
1155  trackSelection.add<double>("sip3dSigMax",99999.9);
1156  trackSelection.add<double>("sip2dSigMin",-99999.9);
1157  trackSelection.add<double>("b_dR",0.6263);
1158  desc.add<edm::ParameterSetDescription>("trackSelection",trackSelection);
1159  }
1160  desc.add<std::string>("trackSort","sip3dSig");
1161  desc.add<edm::InputTag>("extSVCollection",edm::InputTag("secondaryVertices"));
1162  desc.addOptionalNode( edm::ParameterDescription<bool>("useSVClustering",false, true) and
1163  edm::ParameterDescription<std::string>("jetAlgorithm", true) and
1164  edm::ParameterDescription<double>("rParam", true), true );
1165  desc.addOptional<bool>("useSVMomentum",false);
1166  desc.addOptional<double>("ghostRescaling",1e-18);
1167  desc.addOptional<double>("relPtTolerance",1e-03);
1168  desc.addOptional<edm::InputTag>("fatJets");
1169  desc.addOptional<edm::InputTag>("groomedFatJets");
1170  descriptions.addDefault(desc);
1171 }
1172 
1173 //define this as a plug-in
1176 
1179 
type
Definition: HCALResponse.h:21
math::Error< dimension >::type CovarianceMatrix
Definition: BeamSpot.h:31
reco::Vertex::Point convertPos(const GlobalPoint &p)
value_type const * get() const
Definition: RefToBase.h:225
T getParameter(std::string const &) const
edm::EDGetTokenT< edm::View< reco::Jet > > token_fatJets
boost::shared_ptr< fastjet::JetDefinition > JetDefPtr
int i
Definition: DBlmapReader.cc:9
reco::btag::SortCriteria getCriterium(const std::string &name)
Definition: TrackSorting.cc:11
TemplatedSecondaryVertex< reco::Vertex > SecondaryVertex
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
trackRef_iterator tracks_end() const
last iterator over tracks
Definition: Vertex.cc:44
TemplatedSecondaryVertexProducer(const edm::ParameterSet &params)
virtual void produce(edm::Event &event, const edm::EventSetup &es) override
virtual const Point & vertex() const
vertex position (overwritten by PF...)
boost::shared_ptr< fastjet::ClusterSequence > ClusterSequencePtr
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
edm::EDGetTokenT< reco::BeamSpot > token_BeamSpot
double y() const
y coordinate
Definition: Vertex.h:110
Base class for all types of Jets.
Definition: Jet.h:20
float totalChiSquared() const
reco::Vertex::Error convertError(const GlobalError &ge)
Definition: ConvertError.h:8
virtual Vector momentum() const
spatial momentum vector
T y() const
Definition: PV3DBase.h:63
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual void setP4(const LorentzVector &p4)
set 4-momentum
void setWeight(double weight)
SVFilter(const VertexFilter &filter, const Vertex &pv, const GlobalVector &direction)
double covariance(int i, int j) const
(i, j)-th element of error matrix, i, j = 0, ... 2
Definition: Vertex.h:123
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
const reco::Track * toTrack(const reco::TrackBaseRef &t)
Definition: IPTagInfo.h:24
const Point & position() const
position
Definition: Vertex.h:106
ProductID id() const
Definition: RefToBase.h:233
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
TemplatedSecondaryVertexProducer< TrackIPTagInfo, reco::Vertex > SecondaryVertexProducer
const AlgebraicSymMatrix33 & matrix_new() const
static GhostTrackVertexFinder::FitType getGhostTrackFitType(const std::string &name)
void matchReclusteredJets(const edm::Handle< CONTAINER > &jets, const std::vector< fastjet::PseudoJet > &matchedJets, std::vector< int > &matchedIndices, const std::string &jetType="")
edm::EDGetTokenT< std::vector< IPTI > > token_trackIPTagInfo
IPTI::input_container::value_type input_item
T mag() const
Definition: PV3DBase.h:67
void addDefault(ParameterSetDescription const &psetDescription)
GlobalVector flightDirection(const reco::Vertex &pv, const reco::Vertex &sv)
std::vector< reco::TransientTrack > const & originalTracks() const
float degreesOfFreedom() const
size_t key() const
Definition: RefToBase.h:241
T sqrt(T t)
Definition: SSEVec.h:48
double p4[4]
Definition: TauolaWrapper.h:92
GlobalPoint position() const
vector< PseudoJet > jets
T z() const
Definition: PV3DBase.h:64
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
double z() const
y coordinate
Definition: Vertex.h:112
ParameterDescriptionNode * addOptionalNode(ParameterDescriptionNode const &node, bool writeToCfi)
double deltaR2(const T1 &t1, const T2 &t2)
Definition: deltaR.h:36
VertexSorting< SecondaryVertex > vertexSorting
static ConstraintType getConstraintType(const std::string &name)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool isValid() const
Definition: HandleBase.h:75
Container::value_type value_type
float trackWeight(const reco::TransientTrack &track) const
virtual void setVertex(const Point &vertex)
set vertex
void matchGroomedJets(const edm::Handle< edm::View< reco::Jet > > &jets, const edm::Handle< edm::View< reco::Jet > > &matchedJets, std::vector< int > &matchedIndices)
void matchSubjets(const std::vector< int > &groomedIndices, const edm::Handle< edm::View< reco::Jet > > &groomedJets, const edm::Handle< std::vector< IPTI > > &subjets, std::vector< std::vector< int > > &matchedIndices)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void markUsedTracks(TrackDataVector &trackData, const input_container &trackRefs, const SecondaryVertex &sv, size_t idx)
edm::EDGetTokenT< edm::View< VTX > > token_extSVCollection
Vector3DBase unit() const
Definition: Vector3DBase.h:57
SVBuilder(const reco::Vertex &pv, const GlobalVector &direction, bool withPVError, double minTrackWeight)
double x() const
x coordinate
Definition: Vertex.h:108
TemplatedSecondaryVertex< VTX > SecondaryVertex
edm::EDGetTokenT< edm::View< reco::Jet > > token_groomedFatJets
bool linearize(const GhostTrackPrediction &pred, bool initial=false, double lambda=0.)
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
const T & get() const
Definition: EventSetup.h:55
SecondaryVertex operator()(const TransientVertex &sv) const
Error error() const
return SMatrix
Definition: Vertex.h:129
TemplatedSecondaryVertexProducer< CandIPTagInfo, reco::VertexCompositePtrCandidate > CandSecondaryVertexProducer
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
std::vector< reco::btag::IndexedTrackData > TrackDataVector
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:85
static int position[264][3]
Definition: ReadPGInfo.cc:509
std::vector< TemplatedSecondaryVertexTagInfo< IPTI, VTX > > Product
void setCovariance(const CovarianceMatrix &m)
set covariance matrix
std::vector< TrackBaseRef >::const_iterator trackRef_iterator
The iteratator for the vector&lt;TrackRef&gt;
Definition: Vertex.h:37
void addDaughter(const CandidatePtr &)
add a daughter via a reference
math::XYZPoint Point
point in the space
Definition: Candidate.h:41
GlobalError error() const
Definition: VertexState.h:55
dbl *** dir
Definition: mlp_gen.cc:35
volatile std::atomic< bool > shutdown_flag false
void setChi2AndNdof(double chi2, double ndof)
set chi2 and ndof
trackRef_iterator tracks_begin() const
first iterator over tracks
Definition: Vertex.cc:39
VertexState const & vertexState() const
T x() const
Definition: PV3DBase.h:62
const reco::Jet * toJet(const reco::Jet &j)
std::pair< unsigned int, TrackData > IndexedTrackData
Global3DVector GlobalVector
Definition: GlobalVector.h:10
tuple trackSelector
Tracks selection.
Definition: valSkim_cff.py:4