9 #include <boost/iterator/zip_iterator.hpp>
18 m_deco_charge(
"charge"),
21 m_deco_sig3D(
"significance3D"),
22 m_deco_deltaR(
"deltaR"),
25 m_deco_eFrac(
"efracsv"),
26 m_deco_nHFTracks(
"nHFtrk"){
27 declareInterface<IGNNVertexFitterInterface>(
this);
47 std::string linkNameMod =
"";
58 return StatusCode::SUCCESS;
63 TLorentzVector
sum(0., 0., 0., 0.);
64 for (
int i = 0;
i < (
int)selTrk.size(); ++
i) {
65 if (selTrk[
i] == NULL)
67 sum += selTrk[
i]->p4();
74 const std::vector<double> &secVrtErr,
double &signif)
const {
75 double distx = primVrt.
x() - secVrt.x();
76 double disty = primVrt.
y() - secVrt.y();
77 double distz = primVrt.
z() - secVrt.z();
79 AmgSymMatrix(3) primCovMtx = primVrt.covariancePosition();
80 primCovMtx(0, 0) += secVrtErr[0];
81 primCovMtx(0, 1) += secVrtErr[1];
82 primCovMtx(1, 0) += secVrtErr[1];
83 primCovMtx(1, 1) += secVrtErr[2];
84 primCovMtx(0, 2) += secVrtErr[3];
85 primCovMtx(2, 0) += secVrtErr[3];
86 primCovMtx(1, 2) += secVrtErr[4];
87 primCovMtx(2, 1) += secVrtErr[4];
88 primCovMtx(2, 2) += secVrtErr[5];
92 signif = distx * wgtMtx(0, 0) * distx + disty * wgtMtx(1, 1) * disty + distz * wgtMtx(2, 2) * distz +
93 2. * distx * wgtMtx(0, 1) * disty + 2. * distx * wgtMtx(0, 2) * distz + 2. * disty * wgtMtx(1, 2) * distz;
94 signif = std::sqrt(std::abs(signif));
97 return std::sqrt(distx * distx + disty * disty + distz * distz);
103 const xAOD::Vertex &primVrt,
const EventContext &ctx)
const {
105 using TLC = std::vector<ElementLink<DataVector<xAOD::TrackParticle_v1>>>;
116 for (
const auto &
jet : *inJetContainer) {
119 auto vertexCollection = vertexLinksHandle(*
jet);
120 auto trackCollection = trackLinksHandle(*
jet);
121 auto trackOriginCollection = trackOriginsHandle(*
jet);
123 using indexList = std::vector<int>;
124 using trackCountMap = std::map<char, std::set<TL>>;
126 indexList iList(vertexCollection.size());
128 trackCountMap allTracksMap;
129 trackCountMap heavyFlavourVertexMap;
130 trackCountMap primaryVertexMap;
131 trackCountMap fittingMap;
134 heavyFlavourVertexMap.clear();
135 primaryVertexMap.clear();
136 allTracksMap.clear();
142 auto trackOrigin = trackOriginCollection[
index];
143 auto trackLink = trackCollection[
index];
145 allTracksMap[
vertex].insert(trackLink);
150 heavyFlavourVertexMap[
vertex].insert(trackLink);
154 primaryVertexMap[
vertex].insert(trackLink);
159 auto pvCandidate = std::max_element(
160 primaryVertexMap.begin(), primaryVertexMap.end(),
161 [](
const auto&
a,
const auto&
b) { return a.second.size() < b.second.size(); }
165 for (
const auto &vertexTrackPair : allTracksMap) {
167 const auto &[
vertex, trackLinks] = vertexTrackPair;
170 if(
vertex == pvCandidate) {
176 if (heavyFlavourVertexMap.find(
vertex) == heavyFlavourVertexMap.end()) {
182 if (heavyFlavourVertexMap.find(
vertex) != heavyFlavourVertexMap.end() &&
183 (
static_cast<float>(heavyFlavourVertexMap[
vertex].size()) / trackLinks.size()) <
m_HFRatioThres) {
188 fittingMap.insert(std::pair<
char, std::set<TL>>(
vertex, trackLinks));
193 const char mergedVertexKey = 0;
194 std::set<TL> mergedSet;
195 std::set<TL> combinedHFTracks;
198 for (
const auto &vertexTrackPair : fittingMap) {
200 mergedSet.insert(vertexTrackPair.second.begin(), vertexTrackPair.second.end());
201 combinedHFTracks.insert(heavyFlavourVertexMap[vertexTrackPair.first].begin(), heavyFlavourVertexMap[vertexTrackPair.first].end());
206 fittingMap[mergedVertexKey] = std::move(mergedSet);
207 heavyFlavourVertexMap.clear();
208 heavyFlavourVertexMap[mergedVertexKey] = std::move(combinedHFTracks);
216 xAODwrk->beamX = beamSpotHandle->beamPos().x();
217 xAODwrk->beamY = beamSpotHandle->beamPos().y();
218 xAODwrk->beamZ = beamSpotHandle->beamPos().z();
219 xAODwrk->tanBeamTiltX =
tan(beamSpotHandle->beamTilt(0));
220 xAODwrk->tanBeamTiltY =
tan(beamSpotHandle->beamTilt(1));
222 std::unique_ptr<std::vector<WrkVrt>> wrkVrtSet = std::make_unique<std::vector<WrkVrt>>();
226 std::vector<const xAOD::NeutralParticle *> neutralPartDummy(0);
229 for (
const auto &pair : fittingMap) {
231 if (pair.second.size() >= 2) {
232 int NTRKS = pair.second.size();
233 std::vector<double> InpMass(NTRKS,
m_massPi);
236 xAODwrk->listSelTracks.clear();
239 xAODwrk->listSelTracks.push_back(*
TrackLink);
243 TLorentzVector jetDir(
jet->p4());
248 if (
sc.isFailure() || FitVertex.perp() >
m_maxLxy) {
253 vDist = FitVertex - primVrt.
position();
254 double JetVrtDir = jetDir.Px() * vDist.x() + jetDir.Py() * vDist.y() + jetDir.Pz() * vDist.z();
256 JetVrtDir = fabs(JetVrtDir);
266 sc = (
m_vertexFitterTool->VKalVrtFit(xAODwrk->listSelTracks, neutralPartDummy, newvrt.vertex, newvrt.vertexMom,
267 newvrt.vertexCharge, newvrt.vertexCov, newvrt.chi2PerTrk, newvrt.trkAtVrt,
268 newvrt.chi2, *state,
false));
273 auto NDOF = 2 * (newvrt.trkAtVrt.size()) - 3.0;
277 ATH_MSG_DEBUG(
"Found IniVertex=" << newvrt.vertex[0] <<
", " << newvrt.vertex[1] <<
", " << newvrt.vertex[2]
278 <<
" trks " << newvrt.trkAtVrt.size());
285 (vDir.x() * newvrt.vertexMom.Px() + vDir.y() * newvrt.vertexMom.Py() + vDir.z() * newvrt.vertexMom.Pz()) /
286 newvrt.vertexMom.Rho();
288 double Lxy = sqrt(vDir[0] * vDir[0] + vDir[1] * vDir[1]);
289 double Lxyz = sqrt(vDir[0] * vDir[0] + vDir[1] * vDir[1] + vDir[2] * vDir[2]);
294 int ntrk = newvrt.trkAtVrt.size();
296 TLorentzVector MomentumVtx =
TotalMom(xAODwrk->listSelTracks);
298 double eRatio = MomentumVtx.E() /
jet->p4().E();
300 [[maybe_unused]]
double distToPV =
vrtVrtDist(primVrt, newvrt.vertex, newvrt.vertexCov, signif3D);
318 for (
const auto *trk : xAODwrk->listSelTracks) {
322 GNNvertex->addTrackAtVertex(link_trk, 1.);
327 GNNvertex->setPosition(newvrt.vertex);
328 GNNvertex->setFitQuality(newvrt.chi2, NDOF);
331 m_deco_pt(*GNNvertex) = newvrt.vertexMom.Perp();
345 jetWriteDecorHandleVertexLink(*jet).push_back(linkVertex);
350 return StatusCode::SUCCESS;