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 
20 
24 
29 
37 
42 
48 
50 
51 #include "fastjet/JetDefinition.hh"
52 #include "fastjet/ClusterSequence.hh"
53 #include "fastjet/PseudoJet.hh"
54 
55 //
56 // constants, enums and typedefs
57 //
58 typedef boost::shared_ptr<fastjet::ClusterSequence> ClusterSequencePtr;
59 typedef boost::shared_ptr<fastjet::JetDefinition> JetDefPtr;
60 
61 
62 using namespace reco;
63 
64 namespace {
65  class VertexInfo : public fastjet::PseudoJet::UserInfoBase{
66  public:
67  VertexInfo(const int vertexIndex) :
68  m_vertexIndex(vertexIndex) { }
69 
70  inline const int vertexIndex() const { return m_vertexIndex; }
71 
72  protected:
73  int m_vertexIndex;
74  };
75 
76  template<typename T>
77  struct RefToBaseLess : public std::binary_function<edm::RefToBase<T>,
78  edm::RefToBase<T>,
79  bool> {
80  inline bool operator()(const edm::RefToBase<T> &r1,
81  const edm::RefToBase<T> &r2) const
82  {
83  return r1.id() < r2.id() ||
84  (r1.id() == r2.id() && r1.key() < r2.key());
85  }
86  };
87 }
88 
90 return GlobalVector(sv.x() - pv.x(), sv.y() - pv.y(),sv.z() - pv.z());
91 }
93 return GlobalVector(sv.vertex().x() - pv.x(), sv.vertex().y() - pv.y(),sv.vertex().z() - pv.z());
94 }
96 {return sv.position();}
98 {return sv.vertex();}
99 
100 
101 template <class IPTI,class VTX>
103  public:
104  explicit TemplatedSecondaryVertexProducer(const edm::ParameterSet &params);
106  typedef std::vector<TemplatedSecondaryVertexTagInfo<IPTI,VTX> > Product;
108  typedef typename IPTI::input_container input_container;
110  typedef typename std::vector<reco::btag::IndexedTrackData> TrackDataVector;
111  virtual void produce(edm::Event &event, const edm::EventSetup &es) override;
112 
113  private:
114  template<class CONTAINER>
115  void matchReclusteredJets(const edm::Handle<CONTAINER>& jets,
116  const std::vector<fastjet::PseudoJet>& matchedJets,
117  std::vector<int>& matchedIndices,
118  const std::string& jetType="");
119  void matchGroomedJets(const edm::Handle<edm::View<reco::Jet> >& jets,
120  const edm::Handle<edm::View<reco::Jet> >& matchedJets,
121  std::vector<int>& matchedIndices);
122  void matchSubjets(const std::vector<int>& groomedIndices,
123  const edm::Handle<edm::View<reco::Jet> >& groomedJets,
124  const edm::Handle<std::vector<IPTI> >& subjets,
125  std::vector<std::vector<int> >& matchedIndices);
126 
127  const reco::Jet * toJet(const reco::Jet & j) { return &j; }
128  const reco::Jet * toJet(const IPTI & j) { return &(*(j.jet())); }
129 
131  CONSTRAINT_NONE = 0,
136  CONSTRAINT_PV_PRIMARIES_IN_FIT
137  };
138  static ConstraintType getConstraintType(const std::string &name);
139 
158  double rParam;
159  double jetPtMin;
165 
168 
169  void markUsedTracks(TrackDataVector & trackData, const input_container & trackRefs, const SecondaryVertex & sv,size_t idx);
170 
171  struct SVBuilder :
172  public std::unary_function<const VTX&, SecondaryVertex> {
173 
175  const GlobalVector &direction,
176  bool withPVError,
177  double minTrackWeight) :
178  pv(pv), direction(direction),
179  withPVError(withPVError),
180  minTrackWeight(minTrackWeight) {}
181  SecondaryVertex operator () (const TransientVertex &sv) const;
182 
183  SecondaryVertex operator () (const VTX &sv) const
184  { return SecondaryVertex(pv, sv, direction, withPVError); }
185 
186 
187  const Vertex &pv;
191  };
192 
193  struct SVFilter :
194  public std::unary_function<const SecondaryVertex&, bool> {
195 
197  const GlobalVector &direction) :
198  filter(filter), pv(pv), direction(direction) {}
199 
200  inline bool operator () (const SecondaryVertex &sv) const
201  { return !filter(pv, sv, direction); }
202 
204  const Vertex &pv;
206  };
207 };
208 template <class IPTI,class VTX>
211 {
212  if (name == "None")
213  return CONSTRAINT_NONE;
214  else if (name == "BeamSpot")
215  return CONSTRAINT_BEAMSPOT;
216  else if (name == "BeamSpot+PVPosition")
217  return CONSTRAINT_PV_BEAMSPOT_SIZE;
218  else if (name == "BeamSpotZ+PVErrorScaledXY")
219  return CONSTRAINT_PV_BS_Z_ERRORS_SCALED;
220  else if (name == "PVErrorScaled")
221  return CONSTRAINT_PV_ERROR_SCALED;
222  else if (name == "BeamSpot+PVTracksInFit")
223  return CONSTRAINT_PV_PRIMARIES_IN_FIT;
224  else
225  throw cms::Exception("InvalidArgument")
226  << "TemplatedSecondaryVertexProducer: ``constraint'' parameter "
227  "value \"" << name << "\" not understood."
228  << std::endl;
229 }
230 
233 {
234  if (name == "AlwaysWithGhostTrack")
236  else if (name == "SingleTracksWithGhostTrack")
238  else if (name == "RefitGhostTrackWithVertices")
240  else
241  throw cms::Exception("InvalidArgument")
242  << "TemplatedSecondaryVertexProducer: ``fitType'' "
243  "parameter value \"" << name << "\" for "
244  "GhostTrackVertexFinder settings not "
245  "understood." << std::endl;
246 }
247 
248 template <class IPTI,class VTX>
250  const edm::ParameterSet &params) :
251  sortCriterium(TrackSorting::getCriterium(params.getParameter<std::string>("trackSort"))),
252  trackSelector(params.getParameter<edm::ParameterSet>("trackSelection")),
253  constraint(getConstraintType(params.getParameter<std::string>("constraint"))),
254  constraintScaling(1.0),
255  vtxRecoPSet(params.getParameter<edm::ParameterSet>("vertexReco")),
256  useGhostTrack(vtxRecoPSet.getParameter<std::string>("finder") == "gtvr"),
257  withPVError(params.getParameter<bool>("usePVError")),
258  minTrackWeight(params.getParameter<double>("minimumTrackWeight")),
259  vertexFilter(params.getParameter<edm::ParameterSet>("vertexCuts")),
260  vertexSorting(params.getParameter<edm::ParameterSet>("vertexSelection"))
261 {
262  token_trackIPTagInfo = consumes<std::vector<IPTI> >(params.getParameter<edm::InputTag>("trackIPTagInfos"));
265  constraintScaling = params.getParameter<double>("pvErrorScaling");
266 
271  token_BeamSpot = consumes<reco::BeamSpot>(params.getParameter<edm::InputTag>("beamSpotTag"));
272  useExternalSV = false;
273  if(params.existsAs<bool>("useExternalSV")) useExternalSV = params.getParameter<bool> ("useExternalSV");
274  if(useExternalSV) {
275  token_extSVCollection = consumes<edm::View<VTX> >(params.getParameter<edm::InputTag>("extSVCollection"));
276  extSVDeltaRToJet = params.getParameter<double>("extSVDeltaRToJet");
277  }
278  useSVClustering = ( params.existsAs<bool>("useSVClustering") ? params.getParameter<bool>("useSVClustering") : false );
279  useSVMomentum = ( params.existsAs<bool>("useSVMomentum") ? params.getParameter<bool>("useSVMomentum") : false );
280  useFatJets = ( useExternalSV && useSVClustering && params.exists("fatJets") && params.exists("groomedFatJets") );
281  if( useSVClustering )
282  {
283  jetAlgorithm = params.getParameter<std::string>("jetAlgorithm");
284  rParam = params.getParameter<double>("rParam");
285  jetPtMin = 0.; // hardcoded to 0. since we simply want to recluster all input jets which already had some PtMin applied
286  ghostRescaling = ( params.existsAs<double>("ghostRescaling") ? params.getParameter<double>("ghostRescaling") : 1e-18 );
287  relPtTolerance = ( params.existsAs<double>("relPtTolerance") ? params.getParameter<double>("relPtTolerance") : 1e-03); // 0.1% relative difference in Pt should be sufficient to detect possible misconfigurations
288 
289  // set jet algorithm
290  if (jetAlgorithm=="Kt")
291  fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::kt_algorithm, rParam) );
292  else if (jetAlgorithm=="CambridgeAachen")
293  fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::cambridge_algorithm, rParam) );
294  else if (jetAlgorithm=="AntiKt")
295  fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm, rParam) );
296  else
297  throw cms::Exception("InvalidJetAlgorithm") << "Jet clustering algorithm is invalid: " << jetAlgorithm << ", use CambridgeAachen | Kt | AntiKt" << std::endl;
298  }
299  if( useFatJets )
300  {
301  token_fatJets = consumes<edm::View<reco::Jet> >(params.getParameter<edm::InputTag>("fatJets"));
302  token_groomedFatJets = consumes<edm::View<reco::Jet> >(params.getParameter<edm::InputTag>("groomedFatJets"));
303  }
304 
305  produces<Product>();
306 }
307 template <class IPTI,class VTX>
309 {
310 }
311 
312 template <class IPTI,class VTX>
314  const edm::EventSetup &es)
315 {
316 // typedef std::map<TrackBaseRef, TransientTrack,
317 // RefToBaseLess<Track> > TransientTrackMap;
318  //How about good old pointers?
319  typedef std::map<const Track *, TransientTrack> TransientTrackMap;
320 
321 
323  es.get<TransientTrackRecord>().get("TransientTrackBuilder",
324  trackBuilder);
325 
326  edm::Handle<std::vector<IPTI> > trackIPTagInfos;
327  event.getByToken(token_trackIPTagInfo, trackIPTagInfos);
328 
329  // External Sec Vertex collection (e.g. for IVF usage)
330  edm::Handle<edm::View<VTX> > extSecVertex;
331  if(useExternalSV) event.getByToken(token_extSVCollection,extSecVertex);
332 
333  edm::Handle<edm::View<reco::Jet> > fatJetsHandle;
334  edm::Handle<edm::View<reco::Jet> > groomedFatJetsHandle;
335  if( useFatJets )
336  {
337  event.getByToken(token_fatJets, fatJetsHandle);
338  event.getByToken(token_groomedFatJets, groomedFatJetsHandle);
339 
340  if( groomedFatJetsHandle->size() > fatJetsHandle->size() )
341  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.";
342  }
343 
345  unsigned int bsCovSrc[7] = { 0, };
346  double sigmaZ = 0.0, beamWidth = 0.0;
347  switch(constraint) {
348  case CONSTRAINT_PV_BEAMSPOT_SIZE:
349  event.getByToken(token_BeamSpot,beamSpot);
350  bsCovSrc[3] = bsCovSrc[4] = bsCovSrc[5] = bsCovSrc[6] = 1;
351  sigmaZ = beamSpot->sigmaZ();
352  beamWidth = beamSpot->BeamWidthX();
353  break;
354 
355  case CONSTRAINT_PV_BS_Z_ERRORS_SCALED:
356  event.getByToken(token_BeamSpot,beamSpot);
357  bsCovSrc[0] = bsCovSrc[1] = 2;
358  bsCovSrc[3] = bsCovSrc[4] = bsCovSrc[5] = 1;
359  sigmaZ = beamSpot->sigmaZ();
360  break;
361 
362  case CONSTRAINT_PV_ERROR_SCALED:
363  bsCovSrc[0] = bsCovSrc[1] = bsCovSrc[2] = 2;
364  break;
365 
366  case CONSTRAINT_BEAMSPOT:
367  case CONSTRAINT_PV_PRIMARIES_IN_FIT:
368  event.getByToken(token_BeamSpot,beamSpot);
369  break;
370 
371  default:
372  /* nothing */;
373  }
374 
375  // ------------------------------------ SV clustering START --------------------------------------------
376  std::vector<std::vector<int> > clusteredSVs(trackIPTagInfos->size(),std::vector<int>());
377  if( useExternalSV && useSVClustering && trackIPTagInfos->size()>0 )
378  {
379  // vector of constituents for reclustering jets and "ghost" SVs
380  std::vector<fastjet::PseudoJet> fjInputs;
381  // loop over all input jets and collect all their constituents
382  if( useFatJets )
383  {
384  for(edm::View<reco::Jet>::const_iterator it = fatJetsHandle->begin(); it != fatJetsHandle->end(); ++it)
385  {
386  std::vector<edm::Ptr<reco::Candidate> > constituents = it->getJetConstituents();
387  std::vector<edm::Ptr<reco::Candidate> >::const_iterator m;
388  for( m = constituents.begin(); m != constituents.end(); ++m )
389  {
390  reco::CandidatePtr constit = *m;
391  if(constit->pt() == 0)
392  {
393  edm::LogWarning("NullTransverseMomentum") << "dropping input candidate with pt=0";
394  continue;
395  }
396  fjInputs.push_back(fastjet::PseudoJet(constit->px(),constit->py(),constit->pz(),constit->energy()));
397  }
398  }
399  }
400  else
401  {
402  for(typename std::vector<IPTI>::const_iterator it = trackIPTagInfos->begin(); it != trackIPTagInfos->end(); ++it)
403  {
404  std::vector<edm::Ptr<reco::Candidate> > constituents = it->jet()->getJetConstituents();
405  std::vector<edm::Ptr<reco::Candidate> >::const_iterator m;
406  for( m = constituents.begin(); m != constituents.end(); ++m )
407  {
408  reco::CandidatePtr constit = *m;
409  if(constit->pt() == 0)
410  {
411  edm::LogWarning("NullTransverseMomentum") << "dropping input candidate with pt=0";
412  continue;
413  }
414  fjInputs.push_back(fastjet::PseudoJet(constit->px(),constit->py(),constit->pz(),constit->energy()));
415  }
416  }
417  }
418  // insert "ghost" SVs in the vector of constituents
419  for(typename edm::View<VTX>::const_iterator it = extSecVertex->begin(); it != extSecVertex->end(); ++it)
420  {
421  const reco::Vertex &pv = *(trackIPTagInfos->front().primaryVertex());
422  GlobalVector dir = flightDirection(pv, *it);
423  dir = dir.unit();
424  fastjet::PseudoJet p(dir.x(),dir.y(),dir.z(),dir.mag()); // using SV flight direction so treating SV as massless
425  if( useSVMomentum )
426  p = fastjet::PseudoJet(it->p4().px(),it->p4().py(),it->p4().pz(),it->p4().energy());
427  p*=ghostRescaling; // rescale SV direction/momentum
428  p.set_user_info(new VertexInfo( it - extSecVertex->begin() ));
429  fjInputs.push_back(p);
430  }
431 
432  // define jet clustering sequence
433  fjClusterSeq = ClusterSequencePtr( new fastjet::ClusterSequence( fjInputs, *fjJetDefinition ) );
434  // recluster jet constituents and inserted "ghosts"
435  std::vector<fastjet::PseudoJet> inclusiveJets = fastjet::sorted_by_pt( fjClusterSeq->inclusive_jets(jetPtMin) );
436 
437  if( useFatJets )
438  {
439  if( inclusiveJets.size() < fatJetsHandle->size() )
440  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.";
441 
442  // match reclustered and original fat jets
443  std::vector<int> reclusteredIndices;
444  matchReclusteredJets<edm::View<reco::Jet> >(fatJetsHandle,inclusiveJets,reclusteredIndices,"fat");
445 
446  // match groomed and original fat jets
447  std::vector<int> groomedIndices;
448  matchGroomedJets(fatJetsHandle,groomedFatJetsHandle,groomedIndices);
449 
450  // match subjets and original fat jets
451  std::vector<std::vector<int> > subjetIndices;
452  matchSubjets(groomedIndices,groomedFatJetsHandle,trackIPTagInfos,subjetIndices);
453 
454  // collect clustered SVs
455  for(size_t i=0; i<fatJetsHandle->size(); ++i)
456  {
457  if( reclusteredIndices.at(i) < 0 ) continue; // continue if matching reclustered to original jets failed
458 
459  if( fatJetsHandle->at(i).pt() == 0 ) // continue if the original jet has Pt=0
460  {
461  edm::LogWarning("NullTransverseMomentum") << "The original fat jet " << i << " has Pt=0. This is not expected so the jet will be skipped.";
462  continue;
463  }
464 
465  if( subjetIndices.at(i).size()==0 ) continue; // continue if the original jet does not have subjets assigned
466 
467  // since the "ghosts" are extremely soft, the configuration and ordering of the reclustered and original fat jets should in principle stay the same
468  if( ( std::abs( inclusiveJets.at(reclusteredIndices.at(i)).pt() - fatJetsHandle->at(i).pt() ) / fatJetsHandle->at(i).pt() ) > relPtTolerance )
469  {
470  if( fatJetsHandle->at(i).pt() < 10. ) // special handling for low-Pt jets (Pt<10 GeV)
471  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"
472  << "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"
473  << "Since the mismatch is at low Pt, it is ignored and only a warning is issued.\n"
474  << "\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.";
475  else
476  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"
477  << "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"
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  }
480 
481  // get jet constituents
482  std::vector<fastjet::PseudoJet> constituents = inclusiveJets.at(reclusteredIndices.at(i)).constituents();
483 
484  std::vector<int> svIndices;
485  // loop over jet constituents and try to find "ghosts"
486  for(std::vector<fastjet::PseudoJet>::const_iterator it = constituents.begin(); it != constituents.end(); ++it)
487  {
488  if( !it->has_user_info() ) continue; // skip if not a "ghost"
489 
490  svIndices.push_back( it->user_info<VertexInfo>().vertexIndex() );
491  }
492 
493  // loop over clustered SVs and assign them to different subjets based on smallest dR
494  for(size_t sv=0; sv<svIndices.size(); ++sv)
495  {
496  const reco::Vertex &pv = *(trackIPTagInfos->front().primaryVertex());
497  const VTX &extSV = (*extSecVertex)[ svIndices.at(sv) ];
498  GlobalVector dir = flightDirection(pv, extSV);
499  dir = dir.unit();
500  fastjet::PseudoJet p(dir.x(),dir.y(),dir.z(),dir.mag()); // using SV flight direction so treating SV as massless
501  if( useSVMomentum )
502  p = fastjet::PseudoJet(extSV.p4().px(),extSV.p4().py(),extSV.p4().pz(),extSV.p4().energy());
503 
504  std::vector<double> dR2toSubjets;
505 
506  for(size_t sj=0; sj<subjetIndices.at(i).size(); ++sj)
507  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() ) );
508 
509  // find the closest subjet
510  int closestSubjetIdx = std::distance( dR2toSubjets.begin(), std::min_element(dR2toSubjets.begin(), dR2toSubjets.end()) );
511 
512  clusteredSVs.at(subjetIndices.at(i).at(closestSubjetIdx)).push_back( svIndices.at(sv) );
513  }
514  }
515  }
516  else
517  {
518  if( inclusiveJets.size() < trackIPTagInfos->size() )
519  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.";
520 
521  // match reclustered and original jets
522  std::vector<int> reclusteredIndices;
523  matchReclusteredJets<std::vector<IPTI> >(trackIPTagInfos,inclusiveJets,reclusteredIndices);
524 
525  // collect clustered SVs
526  for(size_t i=0; i<trackIPTagInfos->size(); ++i)
527  {
528  if( reclusteredIndices.at(i) < 0 ) continue; // continue if matching reclustered to original jets failed
529 
530  if( trackIPTagInfos->at(i).jet()->pt() == 0 ) // continue if the original jet has Pt=0
531  {
532  edm::LogWarning("NullTransverseMomentum") << "The original jet " << i << " has Pt=0. This is not expected so the jet will be skipped.";
533  continue;
534  }
535 
536  // since the "ghosts" are extremely soft, the configuration and ordering of the reclustered and original jets should in principle stay the same
537  if( ( std::abs( inclusiveJets.at(reclusteredIndices.at(i)).pt() - trackIPTagInfos->at(i).jet()->pt() ) / trackIPTagInfos->at(i).jet()->pt() ) > relPtTolerance )
538  {
539  if( trackIPTagInfos->at(i).jet()->pt() < 10. ) // special handling for low-Pt jets (Pt<10 GeV)
540  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"
541  << "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"
542  << "Since the mismatch is at low Pt, it is ignored and only a warning is issued.\n"
543  << "\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.";
544  else
545  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"
546  << "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"
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  }
549 
550  // get jet constituents
551  std::vector<fastjet::PseudoJet> constituents = inclusiveJets.at(reclusteredIndices.at(i)).constituents();
552 
553  // loop over jet constituents and try to find "ghosts"
554  for(std::vector<fastjet::PseudoJet>::const_iterator it = constituents.begin(); it != constituents.end(); ++it)
555  {
556  if( !it->has_user_info() ) continue; // skip if not a "ghost"
557  // push back clustered SV indices
558  clusteredSVs.at(i).push_back( it->user_info<VertexInfo>().vertexIndex() );
559  }
560  }
561  }
562  }
563  // ------------------------------------ SV clustering END ----------------------------------------------
564 
565  std::auto_ptr<ConfigurableVertexReconstructor> vertexReco;
566  std::auto_ptr<GhostTrackVertexFinder> vertexRecoGT;
567  if (useGhostTrack)
568  vertexRecoGT.reset(new GhostTrackVertexFinder(
569  vtxRecoPSet.getParameter<double>("maxFitChi2"),
570  vtxRecoPSet.getParameter<double>("mergeThreshold"),
571  vtxRecoPSet.getParameter<double>("primcut"),
572  vtxRecoPSet.getParameter<double>("seccut"),
573  getGhostTrackFitType(vtxRecoPSet.getParameter<std::string>("fitType"))));
574  else
575  vertexReco.reset(
576  new ConfigurableVertexReconstructor(vtxRecoPSet));
577 
578  TransientTrackMap primariesMap;
579 
580  // result secondary vertices
581 
582  std::auto_ptr<Product> tagInfos(new Product);
583 
584  for(typename std::vector<IPTI>::const_iterator iterJets =
585  trackIPTagInfos->begin(); iterJets != trackIPTagInfos->end();
586  ++iterJets) {
587  TrackDataVector trackData;
588 // std::cout << "Jet " << iterJets-trackIPTagInfos->begin() << std::endl;
589 
590  const Vertex &pv = *iterJets->primaryVertex();
591 
592  std::set<TransientTrack> primaries;
593  if (constraint == CONSTRAINT_PV_PRIMARIES_IN_FIT) {
595  iter != pv.tracks_end(); ++iter) {
596  TransientTrackMap::iterator pos =
597  primariesMap.lower_bound(iter->get());
598 
599  if (pos != primariesMap.end() &&
600  pos->first == iter->get())
601  primaries.insert(pos->second);
602  else {
603  TransientTrack track =
604  trackBuilder->build(
605  iter->castTo<TrackRef>());
606  primariesMap.insert(pos,
607  std::make_pair(iter->get(), track));
608  primaries.insert(track);
609  }
610  }
611  }
612 
613  edm::RefToBase<Jet> jetRef = iterJets->jet();
614 
615  GlobalVector jetDir(jetRef->momentum().x(),
616  jetRef->momentum().y(),
617  jetRef->momentum().z());
618 
619  std::vector<std::size_t> indices =
620  iterJets->sortedIndexes(sortCriterium);
621 
622  input_container trackRefs = iterJets->sortedTracks(indices);
623 
624  const std::vector<reco::btag::TrackIPData> &ipData =
625  iterJets->impactParameterData();
626 
627  // build transient tracks used for vertex reconstruction
628 
629  std::vector<TransientTrack> fitTracks;
630  std::vector<GhostTrackState> gtStates;
631  std::auto_ptr<GhostTrackPrediction> gtPred;
632  if (useGhostTrack)
633  gtPred.reset(new GhostTrackPrediction(
634  *iterJets->ghostTrack()));
635 
636  for(unsigned int i = 0; i < indices.size(); i++) {
638 
639  const input_item &trackRef = trackRefs[i];
640 
641  trackData.push_back(IndexedTrackData());
642  trackData.back().first = indices[i];
643 
644  // select tracks for SV finder
645 
646  if (!trackSelector(*reco::btag::toTrack(trackRef), ipData[indices[i]], *jetRef,
648  pv.position()))) {
649  trackData.back().second.svStatus =
651  continue;
652  }
653 
654  TransientTrackMap::const_iterator pos =
655  primariesMap.find(reco::btag::toTrack((trackRef)));
656  TransientTrack fitTrack;
657  if (pos != primariesMap.end()) {
658  primaries.erase(pos->second);
659  fitTrack = pos->second;
660  } else
661  fitTrack = trackBuilder->build(trackRef);
662  fitTracks.push_back(fitTrack);
663 
664  trackData.back().second.svStatus =
666 
667  if (useGhostTrack) {
668  GhostTrackState gtState(fitTrack);
669  GlobalPoint pos =
670  ipData[indices[i]].closestToGhostTrack;
671  gtState.linearize(*gtPred, true,
672  gtPred->lambda(pos));
673  gtState.setWeight(ipData[indices[i]].ghostTrackWeight);
674  gtStates.push_back(gtState);
675  }
676  }
677 
678  std::auto_ptr<GhostTrack> ghostTrack;
679  if (useGhostTrack)
680  ghostTrack.reset(new GhostTrack(
684  GlobalVector(
685  iterJets->ghostTrack()->px(),
686  iterJets->ghostTrack()->py(),
687  iterJets->ghostTrack()->pz()),
688  0.05),
689  *gtPred, gtStates,
690  iterJets->ghostTrack()->chi2(),
691  iterJets->ghostTrack()->ndof()));
692 
693  // perform actual vertex finding
694 
695 
696  std::vector<VTX> extAssoCollection;
697  std::vector<TransientVertex> fittedSVs;
698  std::vector<SecondaryVertex> SVs;
699  if(!useExternalSV){
700  switch(constraint) {
701  case CONSTRAINT_NONE:
702  if (useGhostTrack)
703  fittedSVs = vertexRecoGT->vertices(
704  pv, *ghostTrack);
705  else
706  fittedSVs = vertexReco->vertices(fitTracks);
707  break;
708 
709  case CONSTRAINT_BEAMSPOT:
710  if (useGhostTrack)
711  fittedSVs = vertexRecoGT->vertices(
712  pv, *beamSpot, *ghostTrack);
713  else
714  fittedSVs = vertexReco->vertices(fitTracks,
715  *beamSpot);
716  break;
717 
718  case CONSTRAINT_PV_BEAMSPOT_SIZE:
719  case CONSTRAINT_PV_BS_Z_ERRORS_SCALED:
720  case CONSTRAINT_PV_ERROR_SCALED: {
722  for(unsigned int i = 0; i < 7; i++) {
723  unsigned int covSrc = bsCovSrc[i];
724  for(unsigned int j = 0; j < 7; j++) {
725  double v=0.0;
726  if (!covSrc || bsCovSrc[j] != covSrc)
727  v = 0.0;
728  else if (covSrc == 1)
729  v = beamSpot->covariance(i, j);
730  else if (j<3 && i<3)
731  v = pv.covariance(i, j) *
732  constraintScaling;
733  cov(i, j) = v;
734  }
735  }
736 
737  BeamSpot bs(pv.position(), sigmaZ,
738  beamSpot.isValid() ? beamSpot->dxdz() : 0.,
739  beamSpot.isValid() ? beamSpot->dydz() : 0.,
740  beamWidth, cov, BeamSpot::Unknown);
741 
742  if (useGhostTrack)
743  fittedSVs = vertexRecoGT->vertices(
744  pv, bs, *ghostTrack);
745  else
746  fittedSVs = vertexReco->vertices(fitTracks, bs);
747  } break;
748 
749  case CONSTRAINT_PV_PRIMARIES_IN_FIT: {
750  std::vector<TransientTrack> primaries_(
751  primaries.begin(), primaries.end());
752  if (useGhostTrack)
753  fittedSVs = vertexRecoGT->vertices(
754  pv, *beamSpot, primaries_,
755  *ghostTrack);
756  else
757  fittedSVs = vertexReco->vertices(
758  primaries_, fitTracks,
759  *beamSpot);
760  } break;
761  }
762  // build combined SV information and filter
763  SVBuilder svBuilder(pv, jetDir, withPVError, minTrackWeight);
764  std::remove_copy_if(boost::make_transform_iterator(
765  fittedSVs.begin(), svBuilder),
766  boost::make_transform_iterator(
767  fittedSVs.end(), svBuilder),
768  std::back_inserter(SVs),
769  SVFilter(vertexFilter, pv, jetDir));
770 
771  }else{
772  if( !useSVClustering ) {
773  for(size_t iExtSv = 0; iExtSv < extSecVertex->size(); iExtSv++){
774  const VTX & extVertex = (*extSecVertex)[iExtSv];
775  if( Geom::deltaR2( ( position(extVertex) - pv.position() ), jetDir ) > extSVDeltaRToJet*extSVDeltaRToJet || extVertex.p4().M() < 0.3 )
776  continue;
777  extAssoCollection.push_back( extVertex );
778  }
779 
780  }
781  else {
782  size_t jetIdx = ( iterJets - trackIPTagInfos->begin() );
783 
784  for(size_t iExtSv = 0; iExtSv < clusteredSVs.at(jetIdx).size(); iExtSv++){
785  const VTX & extVertex = (*extSecVertex)[ clusteredSVs.at(jetIdx).at(iExtSv) ];
786  if( extVertex.p4().M() < 0.3 )
787  continue;
788  extAssoCollection.push_back( extVertex );
789  }
790  }
791  // build combined SV information and filter
792  SVBuilder svBuilder(pv, jetDir, withPVError, minTrackWeight);
793  std::remove_copy_if(boost::make_transform_iterator( extAssoCollection.begin(), svBuilder),
794  boost::make_transform_iterator(extAssoCollection.end(), svBuilder),
795  std::back_inserter(SVs),
796  SVFilter(vertexFilter, pv, jetDir));
797  }
798  // clean up now unneeded collections
799  gtPred.reset();
800  ghostTrack.reset();
801  gtStates.clear();
802  fitTracks.clear();
803  fittedSVs.clear();
804  extAssoCollection.clear();
805 
806  // sort SVs by importance
807 
808  std::vector<unsigned int> vtxIndices = vertexSorting(SVs);
809 
810  std::vector<typename TemplatedSecondaryVertexTagInfo<IPTI,VTX>::VertexData> svData;
811 
812  svData.resize(vtxIndices.size());
813  for(unsigned int idx = 0; idx < vtxIndices.size(); idx++) {
814  const SecondaryVertex &sv = SVs[vtxIndices[idx]];
815 
816  svData[idx].vertex = sv;
817  svData[idx].dist2d = sv.dist2d();
818  svData[idx].dist3d = sv.dist3d();
819  svData[idx].direction = flightDirection(pv,sv);
820  // mark tracks successfully used in vertex fit
821  markUsedTracks(trackData,trackRefs,sv,idx);
822  }
823 
824  // fill result into tag infos
825 
826  tagInfos->push_back(
828  trackData, svData, SVs.size(),
829  edm::Ref<std::vector<IPTI> >(trackIPTagInfos,
830  iterJets - trackIPTagInfos->begin())));
831  }
832 
833  event.put(tagInfos);
834 }
835 
836 //Need specialized template because reco::Vertex iterators are TrackBase and it is a mess to make general
837 template <>
839 {
840  for(Vertex::trackRef_iterator iter = sv.tracks_begin(); iter != sv.tracks_end(); ++iter) {
841  if (sv.trackWeight(*iter) < minTrackWeight)
842  continue;
843 
844  typename input_container::const_iterator pos =
845  std::find(trackRefs.begin(), trackRefs.end(),
846  iter->castTo<input_item>());
847 
848  if (pos == trackRefs.end() ) {
849  if(!useExternalSV)
850  throw cms::Exception("TrackNotFound")
851  << "Could not find track from secondary "
852  "vertex in original tracks."
853  << std::endl;
854  } else {
855  unsigned int index = pos - trackRefs.begin();
856  trackData[index].second.svStatus =
858  ((unsigned int)btag::TrackData::trackAssociatedToVertex + idx);
859  }
860  }
861 }
862 template <>
864 {
865  for(typename input_container::const_iterator iter = sv.daughterPtrVector().begin(); iter != sv.daughterPtrVector().end(); ++iter)
866  {
867  typename input_container::const_iterator pos =
868  std::find(trackRefs.begin(), trackRefs.end(), *iter);
869 
870  if (pos != trackRefs.end() )
871  {
872  unsigned int index = pos - trackRefs.begin();
873  trackData[index].second.svStatus =
875  ((unsigned int)btag::TrackData::trackAssociatedToVertex + idx);
876  }
877  }
878 }
879 
880 
881 template <>
884 {
885  if(sv.originalTracks().size()>0 && sv.originalTracks()[0].trackBaseRef().isNonnull())
886  return SecondaryVertex(pv, sv, direction, withPVError);
887  else
888  {
889  edm::LogError("UnexpectedInputs") << "Building from Candidates, should not happen!";
890  return SecondaryVertex(pv, sv, direction, withPVError);
891  }
892 }
893 
894 template <>
897 {
898  if(sv.originalTracks().size()>0 && sv.originalTracks()[0].trackBaseRef().isNonnull())
899  {
900  edm::LogError("UnexpectedInputs") << "Building from Tracks, should not happen!";
901  VertexCompositePtrCandidate vtxCompPtrCand;
902 
903  vtxCompPtrCand.setCovariance(sv.vertexState().error().matrix_new());
904  vtxCompPtrCand.setChi2AndNdof(sv.totalChiSquared(), sv.degreesOfFreedom());
905  vtxCompPtrCand.setVertex(Candidate::Point(sv.position().x(),sv.position().y(),sv.position().z()));
906 
907  return SecondaryVertex(pv, vtxCompPtrCand, direction, withPVError);
908  }
909  else
910  {
911  VertexCompositePtrCandidate vtxCompPtrCand;
912 
913  vtxCompPtrCand.setCovariance(sv.vertexState().error().matrix_new());
914  vtxCompPtrCand.setChi2AndNdof(sv.totalChiSquared(), sv.degreesOfFreedom());
915  vtxCompPtrCand.setVertex(Candidate::Point(sv.position().x(),sv.position().y(),sv.position().z()));
916 
918  for(std::vector<reco::TransientTrack>::const_iterator tt = sv.originalTracks().begin(); tt != sv.originalTracks().end(); ++tt)
919  {
920  if (sv.trackWeight(*tt) < minTrackWeight)
921  continue;
922 
923  const CandidatePtrTransientTrack* cptt = dynamic_cast<const CandidatePtrTransientTrack*>(tt->basicTransientTrack());
924  if ( cptt==0 )
925  edm::LogError("DynamicCastingFailed") << "Casting of TransientTrack to CandidatePtrTransientTrack failed!";
926  else
927  {
928  p4 += cptt->candidate()->p4();
929  vtxCompPtrCand.addDaughter(cptt->candidate());
930  }
931  }
932  vtxCompPtrCand.setP4(p4);
933 
934  return SecondaryVertex(pv, vtxCompPtrCand, direction, withPVError);
935  }
936 }
937 
938 // ------------ method that matches reclustered and original jets based on minimum dR ------------
939 template<class IPTI,class VTX>
940 template<class CONTAINER>
942  const std::vector<fastjet::PseudoJet>& reclusteredJets,
943  std::vector<int>& matchedIndices,
944  const std::string& jetType)
945 {
946  std::string type = ( jetType!="" ? jetType + " " : jetType );
947 
948  std::vector<bool> matchedLocks(reclusteredJets.size(),false);
949 
950  for(size_t j=0; j<jets->size(); ++j)
951  {
952  double matchedDR2 = 1e9;
953  int matchedIdx = -1;
954 
955  for(size_t rj=0; rj<reclusteredJets.size(); ++rj)
956  {
957  if( matchedLocks.at(rj) ) continue; // skip jets that have already been matched
958 
959  double tempDR2 = Geom::deltaR2( toJet(jets->at(j))->rapidity(), toJet(jets->at(j))->phi(), reclusteredJets.at(rj).rapidity(), reclusteredJets.at(rj).phi_std() );
960  if( tempDR2 < matchedDR2 )
961  {
962  matchedDR2 = tempDR2;
963  matchedIdx = rj;
964  }
965  }
966 
967  if( matchedIdx>=0 )
968  {
969  if ( matchedDR2 > rParam*rParam )
970  {
971  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"
972  << "This is not expected so please check that the jet algorithm and jet size match those used for the original " << type << "jet collection.";
973  }
974  else
975  matchedLocks.at(matchedIdx) = true;
976  }
977  else
978  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.";
979 
980  matchedIndices.push_back(matchedIdx);
981  }
982 }
983 
984 // ------------ method that matches groomed and original jets based on minimum dR ------------
985 template<class IPTI,class VTX>
987  const edm::Handle<edm::View<reco::Jet> >& groomedJets,
988  std::vector<int>& matchedIndices)
989 {
990  std::vector<bool> jetLocks(jets->size(),false);
991  std::vector<int> jetIndices;
992 
993  for(size_t gj=0; gj<groomedJets->size(); ++gj)
994  {
995  double matchedDR2 = 1e9;
996  int matchedIdx = -1;
997 
998  if( groomedJets->at(gj).pt()>0. ) // skip pathological cases of groomed jets with Pt=0
999  {
1000  for(size_t j=0; j<jets->size(); ++j)
1001  {
1002  if( jetLocks.at(j) ) continue; // skip jets that have already been matched
1003 
1004  double tempDR2 = Geom::deltaR2( jets->at(j).rapidity(), jets->at(j).phi(), groomedJets->at(gj).rapidity(), groomedJets->at(gj).phi() );
1005  if( tempDR2 < matchedDR2 )
1006  {
1007  matchedDR2 = tempDR2;
1008  matchedIdx = j;
1009  }
1010  }
1011  }
1012 
1013  if( matchedIdx>=0 )
1014  {
1015  if ( matchedDR2 > rParam*rParam )
1016  {
1017  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"
1018  << "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.";
1019  matchedIdx = -1;
1020  }
1021  else
1022  jetLocks.at(matchedIdx) = true;
1023  }
1024  jetIndices.push_back(matchedIdx);
1025  }
1026 
1027  for(size_t j=0; j<jets->size(); ++j)
1028  {
1029  std::vector<int>::iterator matchedIndex = std::find( jetIndices.begin(), jetIndices.end(), j );
1030 
1031  matchedIndices.push_back( matchedIndex != jetIndices.end() ? std::distance(jetIndices.begin(),matchedIndex) : -1 );
1032  }
1033 }
1034 
1035 // ------------ method that matches subjets and original fat jets ------------
1036 template<class IPTI,class VTX>
1037 void TemplatedSecondaryVertexProducer<IPTI,VTX>::matchSubjets(const std::vector<int>& groomedIndices,
1038  const edm::Handle<edm::View<reco::Jet> >& groomedJets,
1039  const edm::Handle<std::vector<IPTI> >& subjets,
1040  std::vector<std::vector<int> >& matchedIndices)
1041 {
1042  for(size_t g=0; g<groomedIndices.size(); ++g)
1043  {
1044  std::vector<int> subjetIndices;
1045 
1046  if( groomedIndices.at(g)>=0 )
1047  {
1048  for(size_t s=0; s<groomedJets->at(groomedIndices.at(g)).numberOfDaughters(); ++s)
1049  {
1050  const edm::Ptr<reco::Candidate> & subjet = groomedJets->at(groomedIndices.at(g)).daughterPtr(s);
1051 
1052  for(size_t sj=0; sj<subjets->size(); ++sj)
1053  {
1054  const edm::RefToBase<reco::Jet> &subjetRef = subjets->at(sj).jet();
1055  if( subjet == edm::Ptr<reco::Candidate>( subjetRef.id(), subjetRef.get(), subjetRef.key() ) )
1056  {
1057  subjetIndices.push_back(sj);
1058  break;
1059  }
1060  }
1061  }
1062 
1063  if( subjetIndices.size() == 0 )
1064  edm::LogError("SubjetMatchingFailed") << "Matching subjets to original fat jets failed. Please check that the groomed fat jet and subjet collections belong to each other.";
1065 
1066  matchedIndices.push_back(subjetIndices);
1067  }
1068  else
1069  matchedIndices.push_back(subjetIndices);
1070  }
1071 }
1072 
1073 //define this as a plug-in
1076 
1079 
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:213
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
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:184
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
tuple jetType
JET
Definition: autophobj.py:147
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:221
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
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:229
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
double deltaR2(const T1 &t1, const T2 &t2)
Definition: deltaR.h:36
VertexSorting< SecondaryVertex > vertexSorting
static ConstraintType getConstraintType(const std::string &name)
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:76
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)
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:41
std::vector< reco::btag::IndexedTrackData > TrackDataVector
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:81
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:45
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
Definition: DDAxes.h:10
tuple trackSelector
Tracks selection.
Definition: valSkim_cff.py:4