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) {
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];
404 fastjet::PseudoJet(constit->
px() *
w, constit->
py() *
w, constit->
pz() *
w, constit->
energy() *
w));
407 fjInputs.push_back(fastjet::PseudoJet(constit->
px(), constit->
py(), constit->
pz(), constit->
energy()));
414 std::vector<edm::Ptr<reco::Candidate> > constituents = it->jet()->getJetConstituents();
415 std::vector<edm::Ptr<reco::Candidate> >::const_iterator
m;
416 for (
m = constituents.begin();
m != constituents.end(); ++
m) {
419 edm::LogWarning(
"NullTransverseMomentum") <<
"dropping input candidate with pt=0";
422 if (it->jet()->isWeighted()) {
423 if (token_weights.isUninitialized())
425 <<
"TemplatedSecondaryVertexProducer: No weights (e.g. PUPPI) given for weighted jet collection" 427 float w = (*weightsHandle)[constit];
430 fastjet::PseudoJet(constit->
px() *
w, constit->
py() *
w, constit->
pz() *
w, constit->
energy() *
w));
433 fjInputs.push_back(fastjet::PseudoJet(constit->
px(), constit->
py(), constit->
pz(), constit->
energy()));
443 fastjet::PseudoJet
p(
446 p = fastjet::PseudoJet(it->p4().px(), it->p4().py(), it->p4().pz(), it->p4().energy());
448 p.set_user_info(
new VertexInfo(it - extSecVertex->begin()));
449 fjInputs.push_back(
p);
453 fjClusterSeq = std::make_shared<fastjet::ClusterSequence>(fjInputs, *fjJetDefinition);
455 std::vector<fastjet::PseudoJet> inclusiveJets = fastjet::sorted_by_pt(fjClusterSeq->inclusive_jets(
jetPtMin));
458 if (inclusiveJets.size() < fatJetsHandle->size())
460 <<
"There are fewer reclustered (" << inclusiveJets.size() <<
") than original fat jets (" 461 << fatJetsHandle->size()
462 <<
"). Please check that the jet algorithm and jet size match those used for the original jet collection.";
465 std::vector<int> reclusteredIndices;
466 matchReclusteredJets<edm::View<reco::Jet> >(fatJetsHandle, inclusiveJets, reclusteredIndices,
"fat");
469 std::vector<int> groomedIndices;
470 if (useGroomedFatJets)
471 matchGroomedJets(fatJetsHandle, groomedFatJetsHandle, groomedIndices);
474 std::vector<std::vector<int> > subjetIndices;
475 if (useGroomedFatJets)
476 matchSubjets(groomedIndices, groomedFatJetsHandle,
trackIPTagInfos, subjetIndices);
481 for (
size_t i = 0;
i < fatJetsHandle->size(); ++
i) {
482 if (reclusteredIndices.at(
i) < 0)
485 if (fatJetsHandle->at(
i).pt() == 0)
488 <<
"The original fat jet " <<
i <<
" has Pt=0. This is not expected so the jet will be skipped.";
492 if (subjetIndices.at(
i).empty())
496 if ((
std::abs(inclusiveJets.at(reclusteredIndices.at(
i)).
pt() - fatJetsHandle->at(
i).pt()) /
497 fatJetsHandle->at(
i).pt()) > relPtTolerance) {
498 if (fatJetsHandle->at(
i).pt() < 10.)
500 <<
"The reclustered and original fat jet " <<
i <<
" have different Pt's (" 501 << inclusiveJets.at(reclusteredIndices.at(
i)).
pt() <<
" vs " << fatJetsHandle->at(
i).pt()
502 <<
" GeV, respectively).\n" 503 <<
"Please check that the jet algorithm and jet size match those used for the original fat jet " 504 "collection and also make sure the original fat jets are uncorrected. In addition, make sure you " 505 "are not using CaloJets which are presently not supported.\n" 506 <<
"Since the mismatch is at low Pt, it is ignored and only a warning is issued.\n" 507 <<
"\nIn extremely rare instances the mismatch could be caused by a difference in the machine " 508 "precision in which case make sure the original jet collection is produced and reclustering is " 509 "performed in the same job.";
512 <<
"The reclustered and original fat jet " <<
i <<
" have different Pt's (" 513 << inclusiveJets.at(reclusteredIndices.at(
i)).
pt() <<
" vs " << fatJetsHandle->at(
i).pt()
514 <<
" GeV, respectively).\n" 515 <<
"Please check that the jet algorithm and jet size match those used for the original fat jet " 516 "collection and also make sure the original fat jets are uncorrected. In addition, make sure you " 517 "are not using CaloJets which are presently not supported.\n" 518 <<
"\nIn extremely rare instances the mismatch could be caused by a difference in the machine " 519 "precision in which case make sure the original jet collection is produced and reclustering is " 520 "performed in the same job.";
524 std::vector<fastjet::PseudoJet> constituents = inclusiveJets.at(reclusteredIndices.at(
i)).constituents();
526 std::vector<int> svIndices;
528 for (std::vector<fastjet::PseudoJet>::const_iterator it = constituents.begin(); it != constituents.end();
530 if (!it->has_user_info())
533 svIndices.push_back(it->user_info<VertexInfo>().vertexIndex());
537 for (
size_t sv = 0;
sv < svIndices.size(); ++
sv) {
539 const VTX &extSV = (*extSecVertex)[svIndices.at(
sv)];
542 fastjet::PseudoJet
p(
545 p = fastjet::PseudoJet(extSV.p4().px(), extSV.p4().py(), extSV.p4().pz(), extSV.p4().energy());
547 std::vector<double> dR2toSubjets;
549 for (
size_t sj = 0; sj < subjetIndices.at(
i).size(); ++sj)
556 int closestSubjetIdx =
557 std::distance(dR2toSubjets.begin(), std::min_element(dR2toSubjets.begin(), dR2toSubjets.end()));
559 clusteredSVs.at(subjetIndices.at(
i).at(closestSubjetIdx)).
push_back(svIndices.at(
sv));
565 <<
"There are fewer reclustered (" << inclusiveJets.size() <<
") than original jets (" 567 <<
"). Please check that the jet algorithm and jet size match those used for the original jet collection.";
570 std::vector<int> reclusteredIndices;
571 matchReclusteredJets<std::vector<IPTI> >(
trackIPTagInfos, inclusiveJets, reclusteredIndices);
575 if (reclusteredIndices.at(
i) < 0)
581 <<
"The original jet " <<
i <<
" has Pt=0. This is not expected so the jet will be skipped.";
590 <<
"The reclustered and original jet " <<
i <<
" have different Pt's (" 591 << inclusiveJets.at(reclusteredIndices.at(
i)).
pt() <<
" vs " <<
trackIPTagInfos->at(
i).jet()->pt()
592 <<
" GeV, respectively).\n" 593 <<
"Please check that the jet algorithm and jet size match those used for the original jet collection " 594 "and also make sure the original jets are uncorrected. In addition, make sure you are not using " 595 "CaloJets which are presently not supported.\n" 596 <<
"Since the mismatch is at low Pt, it is ignored and only a warning is issued.\n" 597 <<
"\nIn extremely rare instances the mismatch could be caused by a difference in the machine " 598 "precision in which case make sure the original jet collection is produced and reclustering is " 599 "performed in the same job.";
602 <<
"The reclustered and original jet " <<
i <<
" have different Pt's (" 603 << inclusiveJets.at(reclusteredIndices.at(
i)).
pt() <<
" vs " <<
trackIPTagInfos->at(
i).jet()->pt()
604 <<
" GeV, respectively).\n" 605 <<
"Please check that the jet algorithm and jet size match those used for the original jet collection " 606 "and also make sure the original jets are uncorrected. In addition, make sure you are not using " 607 "CaloJets which are presently not supported.\n" 608 <<
"\nIn extremely rare instances the mismatch could be caused by a difference in the machine " 609 "precision in which case make sure the original jet collection is produced and reclustering is " 610 "performed in the same job.";
614 std::vector<fastjet::PseudoJet> constituents = inclusiveJets.at(reclusteredIndices.at(
i)).constituents();
617 for (std::vector<fastjet::PseudoJet>::const_iterator it = constituents.begin(); it != constituents.end();
619 if (!it->has_user_info())
622 clusteredSVs.at(
i).push_back(it->user_info<VertexInfo>().vertexIndex());
630 std::vector<int> groomedIndices;
631 if (useGroomedFatJets)
632 matchGroomedJets(fatJetsHandle, groomedFatJetsHandle, groomedIndices);
635 std::vector<std::vector<int> > subjetIndices;
636 if (useGroomedFatJets)
637 matchSubjets(groomedIndices, groomedFatJetsHandle,
trackIPTagInfos, subjetIndices);
642 for (
size_t i = 0;
i < fatJetsHandle->size(); ++
i) {
643 if (fatJetsHandle->at(
i).pt() == 0)
646 <<
"The original fat jet " <<
i <<
" has Pt=0. This is not expected so the jet will be skipped.";
650 if (subjetIndices.at(
i).empty())
656 size_t sv = (it - extSecVertex->begin());
659 const VTX &extSV = (*extSecVertex)[
sv];
661 GlobalVector jetDir(fatJetsHandle->at(
i).px(), fatJetsHandle->at(
i).py(), fatJetsHandle->at(
i).pz());
667 fastjet::PseudoJet
p(
670 p = fastjet::PseudoJet(extSV.p4().px(), extSV.p4().py(), extSV.p4().pz(), extSV.p4().energy());
672 std::vector<double> dR2toSubjets;
674 for (
size_t sj = 0; sj < subjetIndices.at(
i).size(); ++sj)
681 int closestSubjetIdx =
682 std::distance(dR2toSubjets.begin(), std::min_element(dR2toSubjets.begin(), dR2toSubjets.end()));
684 clusteredSVs.at(subjetIndices.at(
i).at(closestSubjetIdx)).
push_back(
sv);
690 std::unique_ptr<ConfigurableVertexReconstructor>
vertexReco;
691 std::unique_ptr<GhostTrackVertexFinder> vertexRecoGT;
693 vertexRecoGT = std::make_unique<GhostTrackVertexFinder>(
694 vtxRecoPSet.getParameter<
double>(
"maxFitChi2"),
695 vtxRecoPSet.getParameter<
double>(
"mergeThreshold"),
696 vtxRecoPSet.getParameter<
double>(
"primcut"),
697 vtxRecoPSet.getParameter<
double>(
"seccut"),
700 vertexReco = std::make_unique<ConfigurableVertexReconstructor>(vtxRecoPSet);
702 TransientTrackMap primariesMap;
706 auto tagInfos = std::make_unique<Product>();
708 for (
typename std::vector<IPTI>::const_iterator iterJets =
trackIPTagInfos->begin();
714 const Vertex &
pv = *iterJets->primaryVertex();
716 std::set<TransientTrack> primaries;
717 if (
constraint == CONSTRAINT_PV_PRIMARIES_IN_FIT) {
719 TransientTrackMap::iterator
pos = primariesMap.lower_bound(iter->get());
721 if (
pos != primariesMap.end() &&
pos->first == iter->get())
722 primaries.insert(
pos->second);
725 primariesMap.insert(
pos, std::make_pair(iter->get(),
track));
726 primaries.insert(
track);
733 GlobalVector jetDir(jetRef->momentum().x(), jetRef->momentum().y(), jetRef->momentum().z());
739 const std::vector<reco::btag::TrackIPData> &ipData = iterJets->impactParameterData();
743 std::vector<TransientTrack> fitTracks;
744 std::vector<GhostTrackState> gtStates;
745 std::unique_ptr<GhostTrackPrediction> gtPred;
747 gtPred = std::make_unique<GhostTrackPrediction>(*iterJets->ghostTrack());
749 for (
unsigned int i = 0;
i <
indices.size();
i++) {
755 trackData.back().first =
indices[
i];
767 if (
pos != primariesMap.end()) {
768 primaries.erase(
pos->second);
769 fitTrack =
pos->second;
771 fitTrack = trackBuilder->
build(trackRef);
772 fitTracks.push_back(fitTrack);
781 gtStates.push_back(gtState);
785 std::unique_ptr<GhostTrack> ghostTrack;
787 ghostTrack = std::make_unique<GhostTrack>(
791 GlobalVector(iterJets->ghostTrack()->px(), iterJets->ghostTrack()->py(), iterJets->ghostTrack()->pz()),
795 iterJets->ghostTrack()->chi2(),
796 iterJets->ghostTrack()->ndof());
800 std::vector<VTX> extAssoCollection;
801 std::vector<TransientVertex> fittedSVs;
802 std::vector<SecondaryVertex> SVs;
805 case CONSTRAINT_NONE:
807 fittedSVs = vertexRecoGT->vertices(
pv, *ghostTrack);
812 case CONSTRAINT_BEAMSPOT:
814 fittedSVs = vertexRecoGT->vertices(
pv, *
beamSpot, *ghostTrack);
819 case CONSTRAINT_PV_BEAMSPOT_SIZE:
820 case CONSTRAINT_PV_BS_Z_ERRORS_SCALED:
821 case CONSTRAINT_PV_ERROR_SCALED: {
823 for (
unsigned int i = 0;
i < 7;
i++) {
824 unsigned int covSrc = bsCovSrc[
i];
825 for (
unsigned int j = 0;
j < 7;
j++) {
827 if (!covSrc || bsCovSrc[
j] != covSrc)
829 else if (covSrc == 1)
831 else if (
j < 3 &&
i < 3)
832 v =
pv.covariance(
i,
j) * constraintScaling;
846 fittedSVs = vertexRecoGT->vertices(
pv,
bs, *ghostTrack);
851 case CONSTRAINT_PV_PRIMARIES_IN_FIT: {
852 std::vector<TransientTrack> primaries_(primaries.begin(), primaries.end());
854 fittedSVs = vertexRecoGT->vertices(
pv, *
beamSpot, primaries_, *ghostTrack);
860 SVBuilder svBuilder(
pv, jetDir, withPVError, minTrackWeight);
861 std::remove_copy_if(boost::make_transform_iterator(fittedSVs.begin(), svBuilder),
862 boost::make_transform_iterator(fittedSVs.end(), svBuilder),
863 std::back_inserter(SVs),
867 if (useSVClustering || useFatJets) {
870 for (
size_t iExtSv = 0; iExtSv < clusteredSVs.at(
jetIdx).size(); iExtSv++) {
871 const VTX &extVertex = (*extSecVertex)[clusteredSVs.at(
jetIdx).at(iExtSv)];
872 if (extVertex.p4().M() < 0.3)
874 extAssoCollection.push_back(extVertex);
877 for (
size_t iExtSv = 0; iExtSv < extSecVertex->size(); iExtSv++) {
878 const VTX &extVertex = (*extSecVertex)[iExtSv];
881 extVertex.p4().M() < 0.3)
883 extAssoCollection.push_back(extVertex);
887 SVBuilder svBuilder(
pv, jetDir, withPVError, minTrackWeight);
888 std::remove_copy_if(boost::make_transform_iterator(extAssoCollection.begin(), svBuilder),
889 boost::make_transform_iterator(extAssoCollection.end(), svBuilder),
890 std::back_inserter(SVs),
899 extAssoCollection.clear();
903 std::vector<unsigned int> vtxIndices = vertexSorting(SVs);
905 std::vector<typename TemplatedSecondaryVertexTagInfo<IPTI, VTX>::VertexData> svData;
907 svData.resize(vtxIndices.size());
908 for (
unsigned int idx = 0;
idx < vtxIndices.size();
idx++) {
911 svData[
idx].vertex =
sv;
912 svData[
idx].dist1d =
sv.dist1d();
913 svData[
idx].dist2d =
sv.dist2d();
914 svData[
idx].dist3d =
sv.dist3d();
917 markUsedTracks(trackData, trackRefs,
sv,
idx);
939 if (
sv.trackWeight(*iter) < minTrackWeight)
942 typename input_container::const_iterator
pos =
945 if (
pos == trackRefs.end()) {
947 throw cms::Exception(
"TrackNotFound") <<
"Could not find track from secondary " 948 "vertex in original tracks." 951 unsigned int index =
pos - trackRefs.begin();
952 trackData[
index].second.svStatus = (btag::TrackData::trackAssociatedToVertex +
idx);
959 for (
typename input_container::const_iterator iter =
sv.daughterPtrVector().begin();
960 iter !=
sv.daughterPtrVector().end();
962 typename input_container::const_iterator
pos =
std::find(trackRefs.begin(), trackRefs.end(), *iter);
964 if (
pos != trackRefs.end()) {
965 unsigned int index =
pos - trackRefs.begin();
966 trackData[
index].second.svStatus = (btag::TrackData::trackAssociatedToVertex +
idx);
974 if (!
sv.originalTracks().empty() &&
sv.originalTracks()[0].trackBaseRef().isNonnull())
977 edm::LogError(
"UnexpectedInputs") <<
"Building from Candidates, should not happen!";
986 if (!
sv.originalTracks().empty() &&
sv.originalTracks()[0].trackBaseRef().isNonnull()) {
987 edm::LogError(
"UnexpectedInputs") <<
"Building from Tracks, should not happen!";
1003 for (std::vector<reco::TransientTrack>::const_iterator
tt =
sv.originalTracks().begin();
1004 tt !=
sv.originalTracks().end();
1011 if (cptt ==
nullptr)
1012 edm::LogError(
"DynamicCastingFailed") <<
"Casting of TransientTrack to CandidatePtrTransientTrack failed!";
1018 vtxCompPtrCand.
setP4(p4);
1025 template <
class IPTI,
class VTX>
1026 template <
class CONTAINER>
1029 const std::vector<fastjet::PseudoJet> &reclusteredJets,
1030 std::vector<int> &matchedIndices,
1034 std::vector<bool> matchedLocks(reclusteredJets.size(),
false);
1036 for (
size_t j = 0;
j <
jets->size(); ++
j) {
1037 double matchedDR2 = 1e9;
1038 int matchedIdx = -1;
1040 for (
size_t rj = 0; rj < reclusteredJets.size(); ++rj) {
1041 if (matchedLocks.at(rj))
1046 reclusteredJets.at(rj).rapidity(),
1047 reclusteredJets.at(rj).phi_std());
1048 if (tempDR2 < matchedDR2) {
1049 matchedDR2 = tempDR2;
1054 if (matchedIdx >= 0) {
1056 edm::LogError(
"JetMatchingFailed") <<
"Matched reclustered jet " << matchedIdx <<
" and original " <<
type 1057 <<
"jet " <<
j <<
" are separated by dR=" <<
sqrt(matchedDR2)
1058 <<
" which is greater than the jet size R=" <<
rParam <<
".\n" 1059 <<
"This is not expected so please check that the jet algorithm and jet " 1060 "size match those used for the original " 1061 <<
type <<
"jet collection.";
1063 matchedLocks.at(matchedIdx) =
true;
1066 <<
"Matching reclustered to original " <<
type 1067 <<
"jets failed. Please check that the jet algorithm and jet size match those used for the original " <<
type 1068 <<
"jet collection.";
1070 matchedIndices.push_back(matchedIdx);
1075 template <
class IPTI,
class VTX>
1078 std::vector<int> &matchedIndices) {
1079 std::vector<bool> jetLocks(
jets->size(),
false);
1080 std::vector<int> jetIndices;
1082 for (
size_t gj = 0; gj < groomedJets->size(); ++gj) {
1083 double matchedDR2 = 1e9;
1084 int matchedIdx = -1;
1086 if (groomedJets->at(gj).pt() > 0.)
1088 for (
size_t j = 0;
j <
jets->size(); ++
j) {
1093 jets->at(
j).rapidity(),
jets->at(
j).phi(), groomedJets->at(gj).rapidity(), groomedJets->at(gj).phi());
1094 if (tempDR2 < matchedDR2) {
1095 matchedDR2 = tempDR2;
1101 if (matchedIdx >= 0) {
1104 <<
"Matched groomed jet " << gj <<
" and original jet " << matchedIdx
1105 <<
" are separated by dR=" <<
sqrt(matchedDR2) <<
" which is greater than the jet size R=" <<
rParam 1107 <<
"This is not expected so the matching of these two jets has been discarded. Please check that the two " 1108 "jet collections belong to each other.";
1111 jetLocks.at(matchedIdx) =
true;
1113 jetIndices.push_back(matchedIdx);
1116 for (
size_t j = 0;
j <
jets->size(); ++
j) {
1117 std::vector<int>::iterator matchedIndex =
std::find(jetIndices.begin(), jetIndices.end(),
j);
1119 matchedIndices.push_back(matchedIndex != jetIndices.end() ?
std::distance(jetIndices.begin(), matchedIndex) : -1);
1124 template <
class IPTI,
class VTX>
1129 for (
size_t g = 0;
g < groomedIndices.size(); ++
g) {
1130 std::vector<int> subjetIndices;
1132 if (groomedIndices.at(
g) >= 0) {
1133 for (
size_t s = 0;
s < groomedJets->at(groomedIndices.at(
g)).numberOfDaughters(); ++
s) {
1136 for (
size_t sj = 0; sj < subjets->size(); ++sj) {
1139 subjetIndices.push_back(sj);
1145 if (subjetIndices.empty())
1146 edm::LogError(
"SubjetMatchingFailed") <<
"Matching subjets to original fat jets failed. Please check that the " 1147 "groomed fat jet and subjet collections belong to each other.";
1149 matchedIndices.push_back(subjetIndices);
1151 matchedIndices.push_back(subjetIndices);
1156 template <
class IPTI,
class VTX>
1160 for (
size_t fj = 0; fj < fatJets->size(); ++fj) {
1161 std::vector<int> subjetIndices;
1162 size_t nSubjetCollections = 0;
1163 size_t nSubjets = 0;
1165 const pat::Jet *fatJet =
dynamic_cast<const pat::Jet *
>(fatJets->ptrAt(fj).get());
1170 <<
"Wrong jet type for input fat jets. Please check that the input fat jets are of the pat::Jet type.";
1172 matchedIndices.push_back(subjetIndices);
1177 if (nSubjetCollections > 0) {
1178 for (
size_t coll = 0; coll < nSubjetCollections; ++coll) {
1181 for (
size_t fjsj = 0; fjsj < fatJetSubjets.size(); ++fjsj) {
1184 for (
size_t sj = 0; sj < subjets->size(); ++sj) {
1185 const pat::Jet *subJet =
dynamic_cast<const pat::Jet *
>(subjets->at(sj).jet().get());
1188 if (fj == 0 && coll == 0 && fjsj == 0 && sj == 0)
1189 edm::LogError(
"WrongJetType") <<
"Wrong jet type for input subjets. Please check that the input " 1190 "subjets are of the pat::Jet type.";
1194 if (subJet->
originalObjectRef() == fatJetSubjets.at(fjsj)->originalObjectRef()) {
1195 subjetIndices.push_back(sj);
1203 if (subjetIndices.empty() && nSubjets > 0)
1204 edm::LogError(
"SubjetMatchingFailed") <<
"Matching subjets to fat jets failed. Please check that the fat jet " 1205 "and subjet collections belong to each other.";
1207 matchedIndices.push_back(subjetIndices);
1209 matchedIndices.push_back(subjetIndices);
1215 template <
class IPTI,
class VTX>
1218 desc.add<
double>(
"extSVDeltaRToJet", 0.3);
1245 vertexCuts.add<
double>(
"distSig3dMax", 99999.9);
1248 vertexCuts.add<
bool>(
"useTrackWeights",
true);
1249 vertexCuts.add<
double>(
"maxDeltaRToJetAxis", 0.4);
1252 v0Filter.add<
double>(
"k0sMassWindow", 0.05);
1256 vertexCuts.add<
unsigned int>(
"multiplicityMin", 2);
1257 vertexCuts.add<
double>(
"distVal2dMin", 0.01);
1258 vertexCuts.add<
double>(
"distSig2dMax", 99999.9);
1259 vertexCuts.add<
double>(
"distVal3dMax", 99999.9);
1260 vertexCuts.add<
double>(
"minimumTrackWeight", 0.5);
1261 vertexCuts.add<
double>(
"distVal3dMin", -99999.9);
1263 vertexCuts.add<
double>(
"distSig3dMin", -99999.9);
1266 desc.add<
bool>(
"useExternalSV",
false);
1267 desc.add<
double>(
"minimumTrackWeight", 0.5);
1268 desc.add<
bool>(
"usePVError",
true);
1305 desc.addOptional<
bool>(
"useSVMomentum",
false);
1306 desc.addOptional<
double>(
"ghostRescaling", 1
e-18);
1307 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
bool isNull() const
Checks for null.
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