11 #include <boost/iterator/transform_iterator.hpp> 61 #include "fastjet/JetDefinition.hh" 62 #include "fastjet/ClusterSequence.hh" 63 #include "fastjet/PseudoJet.hh" 69 typedef std::shared_ptr<fastjet::JetDefinition>
JetDefPtr;
74 class VertexInfo :
public fastjet::PseudoJet::UserInfoBase {
78 inline const int vertexIndex()
const {
return m_vertexIndex; }
85 struct RefToBaseLess {
87 return r1.id() <
r2.id() || (
r1.id() ==
r2.id() &&
r1.key() <
r2.key());
101 template <
class IPTI,
class VTX>
107 typedef std::vector<TemplatedSecondaryVertexTagInfo<IPTI, VTX> >
Product;
115 template <
class CONTAINER>
117 const std::vector<fastjet::PseudoJet> &matchedJets,
118 std::vector<int> &matchedIndices,
122 std::vector<int> &matchedIndices);
123 void matchSubjets(
const std::vector<int> &groomedIndices,
140 CONSTRAINT_PV_PRIMARIES_IN_FIT
183 :
pv(
pv), direction(direction), withPVError(withPVError), minTrackWeight(minTrackWeight) {}
205 template <
class IPTI,
class VTX>
209 return CONSTRAINT_NONE;
210 else if (
name ==
"BeamSpot")
211 return CONSTRAINT_BEAMSPOT;
212 else if (
name ==
"BeamSpot+PVPosition")
213 return CONSTRAINT_PV_BEAMSPOT_SIZE;
214 else if (
name ==
"BeamSpotZ+PVErrorScaledXY")
215 return CONSTRAINT_PV_BS_Z_ERRORS_SCALED;
216 else if (
name ==
"PVErrorScaled")
217 return CONSTRAINT_PV_ERROR_SCALED;
218 else if (
name ==
"BeamSpot+PVTracksInFit")
219 return CONSTRAINT_PV_PRIMARIES_IN_FIT;
221 throw cms::Exception(
"InvalidArgument") <<
"TemplatedSecondaryVertexProducer: ``constraint'' parameter " 223 <<
name <<
"\" not understood." << std::endl;
227 if (
name ==
"AlwaysWithGhostTrack")
229 else if (
name ==
"SingleTracksWithGhostTrack")
231 else if (
name ==
"RefitGhostTrackWithVertices")
234 throw cms::Exception(
"InvalidArgument") <<
"TemplatedSecondaryVertexProducer: ``fitType'' " 238 "GhostTrackVertexFinder settings not " 243 template <
class IPTI,
class VTX>
248 constraintScaling(1.0),
250 useGhostTrack(vtxRecoPSet.getParameter<
std::
string>(
"finder") ==
"gtvr"),
251 withPVError(
params.getParameter<
bool>(
"usePVError")),
252 minTrackWeight(
params.getParameter<double>(
"minimumTrackWeight")),
277 (
params.existsAs<
double>(
"ghostRescaling") ?
params.getParameter<
double>(
"ghostRescaling") : 1
e-18);
279 (
params.existsAs<
double>(
"relPtTolerance")
280 ?
params.getParameter<
double>(
"relPtTolerance")
292 <<
", use CambridgeAachen | Kt | AntiKt" << std::endl;
295 esConsumes<TransientTrackBuilder, TransientTrackRecord>(
edm::ESInputTag(
"",
"TransientTrackBuilder"));
310 template <
class IPTI,
class VTX>
313 template <
class IPTI,
class VTX>
318 typedef std::map<const Track *, TransientTrack> TransientTrackMap;
328 event.getByToken(token_extSVCollection, extSecVertex);
333 event.getByToken(token_fatJets, fatJetsHandle);
334 if (useGroomedFatJets) {
335 event.getByToken(token_groomedFatJets, groomedFatJetsHandle);
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.";
344 if (!token_weights.isUninitialized())
345 event.getByToken(token_weights, weightsHandle);
348 unsigned int bsCovSrc[7] = {
351 double sigmaZ = 0.0, beamWidth = 0.0;
353 case CONSTRAINT_PV_BEAMSPOT_SIZE:
354 event.getByToken(token_BeamSpot,
beamSpot);
355 bsCovSrc[3] = bsCovSrc[4] = bsCovSrc[5] = bsCovSrc[6] = 1;
360 case CONSTRAINT_PV_BS_Z_ERRORS_SCALED:
361 event.getByToken(token_BeamSpot,
beamSpot);
362 bsCovSrc[0] = bsCovSrc[1] = 2;
363 bsCovSrc[3] = bsCovSrc[4] = bsCovSrc[5] = 1;
367 case CONSTRAINT_PV_ERROR_SCALED:
368 bsCovSrc[0] = bsCovSrc[1] = bsCovSrc[2] = 2;
371 case CONSTRAINT_BEAMSPOT:
372 case CONSTRAINT_PV_PRIMARIES_IN_FIT:
373 event.getByToken(token_BeamSpot,
beamSpot);
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()) {
397 if (token_weights.isUninitialized())
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()) {
421 if (token_weights.isUninitialized())
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);
449 fjClusterSeq = std::make_shared<fastjet::ClusterSequence>(fjInputs, *fjJetDefinition);
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;
466 if (useGroomedFatJets)
467 matchGroomedJets(fatJetsHandle, groomedFatJetsHandle, groomedIndices);
470 std::vector<std::vector<int> > subjetIndices;
471 if (useGroomedFatJets)
472 matchSubjets(groomedIndices, groomedFatJetsHandle,
trackIPTagInfos, 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()) /
493 fatJetsHandle->at(
i).pt()) > relPtTolerance) {
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;
627 if (useGroomedFatJets)
628 matchGroomedJets(fatJetsHandle, groomedFatJetsHandle, groomedIndices);
631 std::vector<std::vector<int> > subjetIndices;
632 if (useGroomedFatJets)
633 matchSubjets(groomedIndices, groomedFatJetsHandle,
trackIPTagInfos, 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>(
690 vtxRecoPSet.getParameter<
double>(
"maxFitChi2"),
691 vtxRecoPSet.getParameter<
double>(
"mergeThreshold"),
692 vtxRecoPSet.getParameter<
double>(
"primcut"),
693 vtxRecoPSet.getParameter<
double>(
"seccut"),
696 vertexReco = std::make_unique<ConfigurableVertexReconstructor>(vtxRecoPSet);
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;
713 if (
constraint == CONSTRAINT_PV_PRIMARIES_IN_FIT) {
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);
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;
801 case CONSTRAINT_NONE:
803 fittedSVs = vertexRecoGT->vertices(
pv, *ghostTrack);
808 case CONSTRAINT_BEAMSPOT:
810 fittedSVs = vertexRecoGT->vertices(
pv, *
beamSpot, *ghostTrack);
815 case CONSTRAINT_PV_BEAMSPOT_SIZE:
816 case CONSTRAINT_PV_BS_Z_ERRORS_SCALED:
817 case CONSTRAINT_PV_ERROR_SCALED: {
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)
828 v =
pv.covariance(
i,
j) * constraintScaling;
842 fittedSVs = vertexRecoGT->vertices(
pv,
bs, *ghostTrack);
847 case CONSTRAINT_PV_PRIMARIES_IN_FIT: {
848 std::vector<TransientTrack> primaries_(primaries.begin(), primaries.end());
850 fittedSVs = vertexRecoGT->vertices(
pv, *
beamSpot, primaries_, *ghostTrack);
856 SVBuilder svBuilder(
pv, jetDir, withPVError, minTrackWeight);
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),
863 if (useSVClustering || useFatJets) {
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);
883 SVBuilder svBuilder(
pv, jetDir, withPVError, minTrackWeight);
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();
899 std::vector<unsigned int> vtxIndices = vertexSorting(SVs);
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();
913 markUsedTracks(trackData, trackRefs,
sv,
idx);
935 if (
sv.trackWeight(*iter) < minTrackWeight)
938 typename input_container::const_iterator
pos =
941 if (
pos == trackRefs.end()) {
943 throw cms::Exception(
"TrackNotFound") <<
"Could not find track from secondary " 944 "vertex in original tracks." 947 unsigned int index =
pos - trackRefs.begin();
948 trackData[
index].second.svStatus = (btag::TrackData::trackAssociatedToVertex +
idx);
955 for (
typename input_container::const_iterator iter =
sv.daughterPtrVector().begin();
956 iter !=
sv.daughterPtrVector().end();
958 typename input_container::const_iterator
pos =
std::find(trackRefs.begin(), trackRefs.end(), *iter);
960 if (
pos != trackRefs.end()) {
961 unsigned int index =
pos - trackRefs.begin();
962 trackData[
index].second.svStatus = (btag::TrackData::trackAssociatedToVertex +
idx);
970 if (!
sv.originalTracks().empty() &&
sv.originalTracks()[0].trackBaseRef().isNonnull())
973 edm::LogError(
"UnexpectedInputs") <<
"Building from Candidates, should not happen!";
982 if (!
sv.originalTracks().empty() &&
sv.originalTracks()[0].trackBaseRef().isNonnull()) {
983 edm::LogError(
"UnexpectedInputs") <<
"Building from Tracks, should not happen!";
999 for (std::vector<reco::TransientTrack>::const_iterator
tt =
sv.originalTracks().begin();
1000 tt !=
sv.originalTracks().end();
1007 if (cptt ==
nullptr)
1008 edm::LogError(
"DynamicCastingFailed") <<
"Casting of TransientTrack to CandidatePtrTransientTrack failed!";
1014 vtxCompPtrCand.
setP4(p4);
1021 template <
class IPTI,
class VTX>
1022 template <
class CONTAINER>
1025 const std::vector<fastjet::PseudoJet> &reclusteredJets,
1026 std::vector<int> &matchedIndices,
1030 std::vector<bool> matchedLocks(reclusteredJets.size(),
false);
1032 for (
size_t j = 0;
j <
jets->size(); ++
j) {
1033 double matchedDR2 = 1e9;
1034 int matchedIdx = -1;
1036 for (
size_t rj = 0; rj < reclusteredJets.size(); ++rj) {
1037 if (matchedLocks.at(rj))
1042 reclusteredJets.at(rj).rapidity(),
1043 reclusteredJets.at(rj).phi_std());
1044 if (tempDR2 < matchedDR2) {
1045 matchedDR2 = tempDR2;
1050 if (matchedIdx >= 0) {
1052 edm::LogError(
"JetMatchingFailed") <<
"Matched reclustered jet " << matchedIdx <<
" and original " <<
type 1053 <<
"jet " <<
j <<
" are separated by dR=" <<
sqrt(matchedDR2)
1054 <<
" which is greater than the jet size R=" <<
rParam <<
".\n" 1055 <<
"This is not expected so please check that the jet algorithm and jet " 1056 "size match those used for the original " 1057 <<
type <<
"jet collection.";
1059 matchedLocks.at(matchedIdx) =
true;
1062 <<
"Matching reclustered to original " <<
type 1063 <<
"jets failed. Please check that the jet algorithm and jet size match those used for the original " <<
type 1064 <<
"jet collection.";
1066 matchedIndices.push_back(matchedIdx);
1071 template <
class IPTI,
class VTX>
1074 std::vector<int> &matchedIndices) {
1075 std::vector<bool> jetLocks(
jets->size(),
false);
1076 std::vector<int> jetIndices;
1078 for (
size_t gj = 0; gj < groomedJets->size(); ++gj) {
1079 double matchedDR2 = 1e9;
1080 int matchedIdx = -1;
1082 if (groomedJets->at(gj).pt() > 0.)
1084 for (
size_t j = 0;
j <
jets->size(); ++
j) {
1089 jets->at(
j).rapidity(),
jets->at(
j).phi(), groomedJets->at(gj).rapidity(), groomedJets->at(gj).phi());
1090 if (tempDR2 < matchedDR2) {
1091 matchedDR2 = tempDR2;
1097 if (matchedIdx >= 0) {
1100 <<
"Matched groomed jet " << gj <<
" and original jet " << matchedIdx
1101 <<
" are separated by dR=" <<
sqrt(matchedDR2) <<
" which is greater than the jet size R=" <<
rParam 1103 <<
"This is not expected so the matching of these two jets has been discarded. Please check that the two " 1104 "jet collections belong to each other.";
1107 jetLocks.at(matchedIdx) =
true;
1109 jetIndices.push_back(matchedIdx);
1112 for (
size_t j = 0;
j <
jets->size(); ++
j) {
1113 std::vector<int>::iterator matchedIndex =
std::find(jetIndices.begin(), jetIndices.end(),
j);
1115 matchedIndices.push_back(matchedIndex != jetIndices.end() ?
std::distance(jetIndices.begin(), matchedIndex) : -1);
1120 template <
class IPTI,
class VTX>
1125 for (
size_t g = 0;
g < groomedIndices.size(); ++
g) {
1126 std::vector<int> subjetIndices;
1128 if (groomedIndices.at(
g) >= 0) {
1129 for (
size_t s = 0;
s < groomedJets->at(groomedIndices.at(
g)).numberOfDaughters(); ++
s) {
1132 for (
size_t sj = 0; sj < subjets->size(); ++sj) {
1135 subjetIndices.push_back(sj);
1141 if (subjetIndices.empty())
1142 edm::LogError(
"SubjetMatchingFailed") <<
"Matching subjets to original fat jets failed. Please check that the " 1143 "groomed fat jet and subjet collections belong to each other.";
1145 matchedIndices.push_back(subjetIndices);
1147 matchedIndices.push_back(subjetIndices);
1152 template <
class IPTI,
class VTX>
1156 for (
size_t fj = 0; fj < fatJets->size(); ++fj) {
1157 std::vector<int> subjetIndices;
1158 size_t nSubjetCollections = 0;
1159 size_t nSubjets = 0;
1161 const pat::Jet *fatJet =
dynamic_cast<const pat::Jet *
>(fatJets->ptrAt(fj).get());
1166 <<
"Wrong jet type for input fat jets. Please check that the input fat jets are of the pat::Jet type.";
1168 matchedIndices.push_back(subjetIndices);
1173 if (nSubjetCollections > 0) {
1174 for (
size_t coll = 0; coll < nSubjetCollections; ++coll) {
1177 for (
size_t fjsj = 0; fjsj < fatJetSubjets.size(); ++fjsj) {
1180 for (
size_t sj = 0; sj < subjets->size(); ++sj) {
1181 const pat::Jet *subJet =
dynamic_cast<const pat::Jet *
>(subjets->at(sj).jet().get());
1184 if (fj == 0 && coll == 0 && fjsj == 0 && sj == 0)
1185 edm::LogError(
"WrongJetType") <<
"Wrong jet type for input subjets. Please check that the input " 1186 "subjets are of the pat::Jet type.";
1190 if (subJet->
originalObjectRef() == fatJetSubjets.at(fjsj)->originalObjectRef()) {
1191 subjetIndices.push_back(sj);
1199 if (subjetIndices.empty() && nSubjets > 0)
1200 edm::LogError(
"SubjetMatchingFailed") <<
"Matching subjets to fat jets failed. Please check that the fat jet " 1201 "and subjet collections belong to each other.";
1203 matchedIndices.push_back(subjetIndices);
1205 matchedIndices.push_back(subjetIndices);
1211 template <
class IPTI,
class VTX>
1214 desc.add<
double>(
"extSVDeltaRToJet", 0.3);
1241 vertexCuts.add<
double>(
"distSig3dMax", 99999.9);
1244 vertexCuts.add<
bool>(
"useTrackWeights",
true);
1245 vertexCuts.add<
double>(
"maxDeltaRToJetAxis", 0.4);
1248 v0Filter.add<
double>(
"k0sMassWindow", 0.05);
1252 vertexCuts.add<
unsigned int>(
"multiplicityMin", 2);
1253 vertexCuts.add<
double>(
"distVal2dMin", 0.01);
1254 vertexCuts.add<
double>(
"distSig2dMax", 99999.9);
1255 vertexCuts.add<
double>(
"distVal3dMax", 99999.9);
1256 vertexCuts.add<
double>(
"minimumTrackWeight", 0.5);
1257 vertexCuts.add<
double>(
"distVal3dMin", -99999.9);
1259 vertexCuts.add<
double>(
"distSig3dMin", -99999.9);
1262 desc.add<
bool>(
"useExternalSV",
false);
1263 desc.add<
double>(
"minimumTrackWeight", 0.5);
1264 desc.add<
bool>(
"usePVError",
true);
1301 desc.addOptional<
bool>(
"useSVMomentum",
false);
1302 desc.addOptional<
double>(
"ghostRescaling", 1
e-18);
1303 desc.addOptional<
double>(
"relPtTolerance", 1
e-03);
std::shared_ptr< fastjet::JetDefinition > JetDefPtr
math::Error< dimension >::type CovarianceMatrix
reco::Vertex::Point convertPos(const GlobalPoint &p)
edm::EDGetTokenT< edm::View< reco::Jet > > token_fatJets
SecondaryVertex operator()(const VTX &sv) const
edm::ESGetToken< TransientTrackBuilder, TransientTrackRecord > token_trackBuilder
const math::XYZPoint & position(const reco::Vertex &sv)
reco::btag::SortCriteria getCriterium(const std::string &name)
virtual double energy() const =0
energy
TemplatedSecondaryVertex< reco::Vertex > SecondaryVertex
TrackSelector trackSelector
trackSelector
Tracks selection.
TemplatedSecondaryVertexProducer(const edm::ParameterSet ¶ms)
void produce(edm::Event &event, const edm::EventSetup &es) override
const GlobalVector & direction
virtual double pt() const =0
transverse momentum
ClusterSequencePtr fjClusterSeq
CandidatePtr candidate() const override
#define DEFINE_FWK_MODULE(type)
edm::EDGetTokenT< reco::BeamSpot > token_BeamSpot
Base class for all types of Jets.
virtual double pz() const =0
z coordinate of momentum vector
reco::Vertex::Error convertError(const GlobalError &ge)
pat::JetPtrCollection const & subjets(unsigned int index=0) const
Access to subjet list.
void setWeight(double weight)
SVFilter(const VertexFilter &filter, const Vertex &pv, const GlobalVector &direction)
VertexFilter vertexFilter
reco::btag::SortCriteria sortCriterium
Log< level::Error, false > LogError
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
const reco::Track * toTrack(const reco::TrackBaseRef &t)
bool operator()(const SecondaryVertex &sv) const
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
TemplatedSecondaryVertexProducer< CandIPTagInfo, reco::VertexCompositePtrCandidate > CandSecondaryVertexProducer
void setVertex(const Point &vertex) override
set vertex
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="")
ConstraintType constraint
reco::TransientTrack build(const reco::Track *p) const
edm::EDGetTokenT< std::vector< IPTI > > token_trackIPTagInfo
std::vector< std::string > const & subjetCollectionNames() const
Subjet collection names.
IPTI::input_container::value_type input_item
Container::value_type value_type
reco::btag::IndexedTrackData IndexedTrackData
void addDefault(ParameterSetDescription const &psetDescription)
std::vector< TemplatedSecondaryVertexTagInfo< IPTI, VTX > > Product
GlobalVector flightDirection(const reco::Vertex &pv, const reco::Vertex &sv)
const reco::Jet * toJet(const IPTI &j)
std::vector< edm::Ptr< pat::Jet > > JetPtrCollection
edm::EDGetTokenT< edm::ValueMap< float > > token_weights
Abs< T >::type abs(const T &t)
std::shared_ptr< fastjet::ClusterSequence > ClusterSequencePtr
VertexSorting< SecondaryVertex > vertexSorting
static ConstraintType getConstraintType(const std::string &name)
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)
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
virtual double px() const =0
x coordinate of momentum vector
SVBuilder(const reco::Vertex &pv, const GlobalVector &direction, bool withPVError, double minTrackWeight)
std::shared_ptr< fastjet::ClusterSequence > ClusterSequencePtr
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
TemplatedSecondaryVertex< VTX > SecondaryVertex
edm::ParameterSet vtxRecoPSet
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
std::shared_ptr< fastjet::JetDefinition > JetDefPtr
Analysis-level calorimeter jet class.
TemplatedSecondaryVertexProducer< TrackIPTagInfo, reco::Vertex > SecondaryVertexProducer
math::XYZTLorentzVector LorentzVector
Lorentz vector.
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
SecondaryVertex operator()(const TransientVertex &sv) const
std::vector< reco::btag::IndexedTrackData > TrackDataVector
const GlobalVector & direction
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
void setCovariance(const CovarianceMatrix &m)
set covariance matrix
void addDaughter(const CandidatePtr &)
add a daughter via a reference
const VertexFilter & filter
math::XYZPoint Point
point in the space
const edm::Ptr< reco::Candidate > & originalObjectRef() const
reference to original object. Returns a null reference if not available
void setChi2AndNdof(double chi2, double ndof)
set chi2 and ndof
Log< level::Warning, false > LogWarning
JetDefPtr fjJetDefinition
~TemplatedSecondaryVertexProducer() override
value_type const * get() const
void setP4(const LorentzVector &p4) final
set 4-momentum
const reco::Jet * toJet(const reco::Jet &j)
std::vector< TrackBaseRef >::const_iterator trackRef_iterator
The iteratator for the vector<TrackRef>
std::pair< unsigned int, TrackData > IndexedTrackData
Global3DVector GlobalVector
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
IPTI::input_container input_container