318 typedef std::map<const Track *, TransientTrack> TransientTrackMap;
337 if (groomedFatJetsHandle->size() > fatJetsHandle->size())
339 <<
"There are more groomed (" << groomedFatJetsHandle->size() <<
") than original fat jets (" 340 << fatJetsHandle->size() <<
"). Please check that the two jet collections belong to each other.";
348 unsigned int bsCovSrc[7] = {
351 double sigmaZ = 0.0, beamWidth = 0.0;
355 bsCovSrc[3] = bsCovSrc[4] = bsCovSrc[5] = bsCovSrc[6] = 1;
362 bsCovSrc[0] = bsCovSrc[1] = 2;
363 bsCovSrc[3] = bsCovSrc[4] = bsCovSrc[5] = 1;
368 bsCovSrc[0] = bsCovSrc[1] = bsCovSrc[2] = 2;
381 std::vector<std::vector<int> > clusteredSVs(
trackIPTagInfos->size(), std::vector<int>());
384 std::vector<fastjet::PseudoJet> fjInputs;
388 std::vector<edm::Ptr<reco::Candidate> > constituents = it->getJetConstituents();
389 std::vector<edm::Ptr<reco::Candidate> >::const_iterator
m;
390 for (
m = constituents.begin();
m != constituents.end(); ++
m) {
392 if (constit->
pt() == 0) {
393 edm::LogWarning(
"NullTransverseMomentum") <<
"dropping input candidate with pt=0";
396 if (it->isWeighted()) {
399 <<
"TemplatedSecondaryVertexProducer: No weights (e.g. PUPPI) given for weighted jet collection" 401 float w = (*weightsHandle)[constit];
403 fastjet::PseudoJet(constit->
px() *
w, constit->
py() *
w, constit->
pz() *
w, constit->
energy() *
w));
405 fjInputs.push_back(fastjet::PseudoJet(constit->
px(), constit->
py(), constit->
pz(), constit->
energy()));
412 std::vector<edm::Ptr<reco::Candidate> > constituents = it->jet()->getJetConstituents();
413 std::vector<edm::Ptr<reco::Candidate> >::const_iterator
m;
414 for (
m = constituents.begin();
m != constituents.end(); ++
m) {
416 if (constit->
pt() == 0) {
417 edm::LogWarning(
"NullTransverseMomentum") <<
"dropping input candidate with pt=0";
420 if (it->jet()->isWeighted()) {
423 <<
"TemplatedSecondaryVertexProducer: No weights (e.g. PUPPI) given for weighted jet collection" 425 float w = (*weightsHandle)[constit];
427 fastjet::PseudoJet(constit->
px() *
w, constit->
py() *
w, constit->
pz() *
w, constit->
energy() *
w));
429 fjInputs.push_back(fastjet::PseudoJet(constit->
px(), constit->
py(), constit->
pz(), constit->
energy()));
439 fastjet::PseudoJet
p(
442 p = fastjet::PseudoJet(it->p4().px(), it->p4().py(), it->p4().pz(), it->p4().energy());
444 p.set_user_info(
new VertexInfo(it - extSecVertex->begin()));
445 fjInputs.push_back(
p);
451 std::vector<fastjet::PseudoJet> inclusiveJets = fastjet::sorted_by_pt(
fjClusterSeq->inclusive_jets(
jetPtMin));
454 if (inclusiveJets.size() < fatJetsHandle->size())
456 <<
"There are fewer reclustered (" << inclusiveJets.size() <<
") than original fat jets (" 457 << fatJetsHandle->size()
458 <<
"). Please check that the jet algorithm and jet size match those used for the original jet collection.";
461 std::vector<int> reclusteredIndices;
462 matchReclusteredJets<edm::View<reco::Jet> >(fatJetsHandle, inclusiveJets, reclusteredIndices,
"fat");
465 std::vector<int> groomedIndices;
470 std::vector<std::vector<int> > subjetIndices;
477 for (
size_t i = 0;
i < fatJetsHandle->size(); ++
i) {
478 if (reclusteredIndices.at(
i) < 0)
481 if (fatJetsHandle->at(
i).pt() == 0)
484 <<
"The original fat jet " <<
i <<
" has Pt=0. This is not expected so the jet will be skipped.";
488 if (subjetIndices.at(
i).empty())
492 if ((
std::abs(inclusiveJets.at(reclusteredIndices.at(
i)).
pt() - fatJetsHandle->at(
i).pt()) /
494 if (fatJetsHandle->at(
i).pt() < 10.)
496 <<
"The reclustered and original fat jet " <<
i <<
" have different Pt's (" 497 << inclusiveJets.at(reclusteredIndices.at(
i)).
pt() <<
" vs " << fatJetsHandle->at(
i).pt()
498 <<
" GeV, respectively).\n" 499 <<
"Please check that the jet algorithm and jet size match those used for the original fat jet " 500 "collection and also make sure the original fat jets are uncorrected. In addition, make sure you " 501 "are not using CaloJets which are presently not supported.\n" 502 <<
"Since the mismatch is at low Pt, it is ignored and only a warning is issued.\n" 503 <<
"\nIn extremely rare instances the mismatch could be caused by a difference in the machine " 504 "precision in which case make sure the original jet collection is produced and reclustering is " 505 "performed in the same job.";
508 <<
"The reclustered and original fat jet " <<
i <<
" have different Pt's (" 509 << inclusiveJets.at(reclusteredIndices.at(
i)).
pt() <<
" vs " << fatJetsHandle->at(
i).pt()
510 <<
" GeV, respectively).\n" 511 <<
"Please check that the jet algorithm and jet size match those used for the original fat jet " 512 "collection and also make sure the original fat jets are uncorrected. In addition, make sure you " 513 "are not using CaloJets which are presently not supported.\n" 514 <<
"\nIn extremely rare instances the mismatch could be caused by a difference in the machine " 515 "precision in which case make sure the original jet collection is produced and reclustering is " 516 "performed in the same job.";
520 std::vector<fastjet::PseudoJet> constituents = inclusiveJets.at(reclusteredIndices.at(
i)).constituents();
522 std::vector<int> svIndices;
524 for (std::vector<fastjet::PseudoJet>::const_iterator it = constituents.begin(); it != constituents.end();
526 if (!it->has_user_info())
529 svIndices.push_back(it->user_info<VertexInfo>().vertexIndex());
533 for (
size_t sv = 0;
sv < svIndices.size(); ++
sv) {
535 const VTX &extSV = (*extSecVertex)[svIndices.at(
sv)];
538 fastjet::PseudoJet
p(
541 p = fastjet::PseudoJet(extSV.p4().px(), extSV.p4().py(), extSV.p4().pz(), extSV.p4().energy());
543 std::vector<double> dR2toSubjets;
545 for (
size_t sj = 0; sj < subjetIndices.at(
i).size(); ++sj)
552 int closestSubjetIdx =
553 std::distance(dR2toSubjets.begin(), std::min_element(dR2toSubjets.begin(), dR2toSubjets.end()));
555 clusteredSVs.at(subjetIndices.at(
i).at(closestSubjetIdx)).
push_back(svIndices.at(
sv));
561 <<
"There are fewer reclustered (" << inclusiveJets.size() <<
") than original jets (" 563 <<
"). Please check that the jet algorithm and jet size match those used for the original jet collection.";
566 std::vector<int> reclusteredIndices;
567 matchReclusteredJets<std::vector<IPTI> >(
trackIPTagInfos, inclusiveJets, reclusteredIndices);
571 if (reclusteredIndices.at(
i) < 0)
577 <<
"The original jet " <<
i <<
" has Pt=0. This is not expected so the jet will be skipped.";
586 <<
"The reclustered and original jet " <<
i <<
" have different Pt's (" 587 << inclusiveJets.at(reclusteredIndices.at(
i)).
pt() <<
" vs " <<
trackIPTagInfos->at(
i).jet()->pt()
588 <<
" GeV, respectively).\n" 589 <<
"Please check that the jet algorithm and jet size match those used for the original jet collection " 590 "and also make sure the original jets are uncorrected. In addition, make sure you are not using " 591 "CaloJets which are presently not supported.\n" 592 <<
"Since the mismatch is at low Pt, it is ignored and only a warning is issued.\n" 593 <<
"\nIn extremely rare instances the mismatch could be caused by a difference in the machine " 594 "precision in which case make sure the original jet collection is produced and reclustering is " 595 "performed in the same job.";
598 <<
"The reclustered and original jet " <<
i <<
" have different Pt's (" 599 << inclusiveJets.at(reclusteredIndices.at(
i)).
pt() <<
" vs " <<
trackIPTagInfos->at(
i).jet()->pt()
600 <<
" GeV, respectively).\n" 601 <<
"Please check that the jet algorithm and jet size match those used for the original jet collection " 602 "and also make sure the original jets are uncorrected. In addition, make sure you are not using " 603 "CaloJets which are presently not supported.\n" 604 <<
"\nIn extremely rare instances the mismatch could be caused by a difference in the machine " 605 "precision in which case make sure the original jet collection is produced and reclustering is " 606 "performed in the same job.";
610 std::vector<fastjet::PseudoJet> constituents = inclusiveJets.at(reclusteredIndices.at(
i)).constituents();
613 for (std::vector<fastjet::PseudoJet>::const_iterator it = constituents.begin(); it != constituents.end();
615 if (!it->has_user_info())
618 clusteredSVs.at(
i).push_back(it->user_info<VertexInfo>().vertexIndex());
626 std::vector<int> groomedIndices;
631 std::vector<std::vector<int> > subjetIndices;
638 for (
size_t i = 0;
i < fatJetsHandle->size(); ++
i) {
639 if (fatJetsHandle->at(
i).pt() == 0)
642 <<
"The original fat jet " <<
i <<
" has Pt=0. This is not expected so the jet will be skipped.";
646 if (subjetIndices.at(
i).empty())
652 size_t sv = (it - extSecVertex->begin());
655 const VTX &extSV = (*extSecVertex)[
sv];
657 GlobalVector jetDir(fatJetsHandle->at(
i).px(), fatJetsHandle->at(
i).py(), fatJetsHandle->at(
i).pz());
663 fastjet::PseudoJet
p(
666 p = fastjet::PseudoJet(extSV.p4().px(), extSV.p4().py(), extSV.p4().pz(), extSV.p4().energy());
668 std::vector<double> dR2toSubjets;
670 for (
size_t sj = 0; sj < subjetIndices.at(
i).size(); ++sj)
677 int closestSubjetIdx =
678 std::distance(dR2toSubjets.begin(), std::min_element(dR2toSubjets.begin(), dR2toSubjets.end()));
680 clusteredSVs.at(subjetIndices.at(
i).at(closestSubjetIdx)).
push_back(
sv);
686 std::unique_ptr<ConfigurableVertexReconstructor>
vertexReco;
687 std::unique_ptr<GhostTrackVertexFinder> vertexRecoGT;
689 vertexRecoGT = std::make_unique<GhostTrackVertexFinder>(
698 TransientTrackMap primariesMap;
702 auto tagInfos = std::make_unique<Product>();
704 for (
typename std::vector<IPTI>::const_iterator iterJets =
trackIPTagInfos->begin();
710 const Vertex &
pv = *iterJets->primaryVertex();
712 std::set<TransientTrack> primaries;
715 TransientTrackMap::iterator
pos = primariesMap.lower_bound(iter->get());
717 if (
pos != primariesMap.end() &&
pos->first == iter->get())
718 primaries.insert(
pos->second);
721 primariesMap.insert(
pos, std::make_pair(iter->get(),
track));
722 primaries.insert(
track);
729 GlobalVector jetDir(jetRef->momentum().x(), jetRef->momentum().y(), jetRef->momentum().z());
735 const std::vector<reco::btag::TrackIPData> &ipData = iterJets->impactParameterData();
739 std::vector<TransientTrack> fitTracks;
740 std::vector<GhostTrackState> gtStates;
741 std::unique_ptr<GhostTrackPrediction> gtPred;
743 gtPred = std::make_unique<GhostTrackPrediction>(*iterJets->ghostTrack());
745 for (
unsigned int i = 0;
i <
indices.size();
i++) {
751 trackData.back().first =
indices[
i];
763 if (
pos != primariesMap.end()) {
764 primaries.erase(
pos->second);
765 fitTrack =
pos->second;
767 fitTrack = trackBuilder->
build(trackRef);
768 fitTracks.push_back(fitTrack);
775 gtState.linearize(*gtPred,
true, gtPred->lambda(
pos));
776 gtState.setWeight(ipData[
indices[
i]].ghostTrackWeight);
777 gtStates.push_back(gtState);
781 std::unique_ptr<GhostTrack> ghostTrack;
783 ghostTrack = std::make_unique<GhostTrack>(
787 GlobalVector(iterJets->ghostTrack()->px(), iterJets->ghostTrack()->py(), iterJets->ghostTrack()->pz()),
791 iterJets->ghostTrack()->chi2(),
792 iterJets->ghostTrack()->ndof());
796 std::vector<VTX> extAssoCollection;
797 std::vector<TransientVertex> fittedSVs;
798 std::vector<SecondaryVertex> SVs;
803 fittedSVs = vertexRecoGT->vertices(
pv, *ghostTrack);
810 fittedSVs = vertexRecoGT->vertices(
pv, *
beamSpot, *ghostTrack);
819 for (
unsigned int i = 0;
i < 7;
i++) {
820 unsigned int covSrc = bsCovSrc[
i];
821 for (
unsigned int j = 0;
j < 7;
j++) {
823 if (!covSrc || bsCovSrc[
j] != covSrc)
825 else if (covSrc == 1)
827 else if (
j < 3 &&
i < 3)
842 fittedSVs = vertexRecoGT->vertices(
pv,
bs, *ghostTrack);
848 std::vector<TransientTrack> primaries_(primaries.begin(), primaries.end());
850 fittedSVs = vertexRecoGT->vertices(
pv, *
beamSpot, primaries_, *ghostTrack);
857 std::remove_copy_if(boost::make_transform_iterator(fittedSVs.begin(), svBuilder),
858 boost::make_transform_iterator(fittedSVs.end(), svBuilder),
859 std::back_inserter(SVs),
866 for (
size_t iExtSv = 0; iExtSv < clusteredSVs.at(
jetIdx).size(); iExtSv++) {
867 const VTX &extVertex = (*extSecVertex)[clusteredSVs.at(
jetIdx).at(iExtSv)];
868 if (extVertex.p4().M() < 0.3)
870 extAssoCollection.push_back(extVertex);
873 for (
size_t iExtSv = 0; iExtSv < extSecVertex->size(); iExtSv++) {
874 const VTX &extVertex = (*extSecVertex)[iExtSv];
877 extVertex.p4().M() < 0.3)
879 extAssoCollection.push_back(extVertex);
884 std::remove_copy_if(boost::make_transform_iterator(extAssoCollection.begin(), svBuilder),
885 boost::make_transform_iterator(extAssoCollection.end(), svBuilder),
886 std::back_inserter(SVs),
895 extAssoCollection.clear();
901 std::vector<typename TemplatedSecondaryVertexTagInfo<IPTI, VTX>::VertexData> svData;
903 svData.resize(vtxIndices.size());
904 for (
unsigned int idx = 0;
idx < vtxIndices.size();
idx++) {
907 svData[
idx].vertex =
sv;
908 svData[
idx].dist1d =
sv.dist1d();
909 svData[
idx].dist2d =
sv.dist2d();
910 svData[
idx].dist3d =
sv.dist3d();
math::Error< dimension >::type CovarianceMatrix
reco::Vertex::Point convertPos(const GlobalPoint &p)
edm::EDGetTokenT< edm::View< reco::Jet > > token_fatJets
edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > token_trackBuilder
const math::XYZPoint & position(const reco::Vertex &sv)
T getParameter(std::string const &) const
virtual double energy() const =0
energy
TrackSelector trackSelector
virtual double pt() const =0
transverse momentum
ClusterSequencePtr fjClusterSeq
edm::EDGetTokenT< reco::BeamSpot > token_BeamSpot
virtual double pz() const =0
z coordinate of momentum vector
reco::Vertex::Error convertError(const GlobalError &ge)
constexpr bool isUninitialized() const noexcept
VertexFilter vertexFilter
reco::btag::SortCriteria sortCriterium
Log< level::Error, false > LogError
const reco::Track * toTrack(const reco::TrackBaseRef &t)
static GhostTrackVertexFinder::FitType getGhostTrackFitType(const std::string &name)
ConstraintType constraint
reco::TransientTrack build(const reco::Track *p) const
edm::EDGetTokenT< std::vector< IPTI > > token_trackIPTagInfo
IPTI::input_container::value_type input_item
reco::btag::IndexedTrackData IndexedTrackData
GlobalVector flightDirection(const reco::Vertex &pv, const reco::Vertex &sv)
edm::EDGetTokenT< edm::ValueMap< float > > token_weights
Abs< T >::type abs(const T &t)
VertexSorting< SecondaryVertex > vertexSorting
virtual double py() const =0
y coordinate of momentum vector
ESHandle< T > getHandle(const ESGetToken< T, R > &iToken) const
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
virtual double px() const =0
x coordinate of momentum vector
edm::ParameterSet vtxRecoPSet
edm::EDGetTokenT< edm::View< reco::Jet > > token_groomedFatJets
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
std::vector< reco::btag::IndexedTrackData > TrackDataVector
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Log< level::Warning, false > LogWarning
JetDefPtr fjJetDefinition
std::vector< TrackBaseRef >::const_iterator trackRef_iterator
The iteratator for the vector<TrackRef>
std::pair< unsigned int, TrackData > IndexedTrackData
Global3DVector GlobalVector
IPTI::input_container input_container