8 #include "AthLinks/ElementLink.h" 
   23       m_deco_charge(
"charge"),
 
   26       m_deco_sig3D(
"significance3D"),
 
   27       m_deco_deltaR(
"deltaR"),
 
   30       m_deco_eFrac(
"efracsv"),
 
   31       m_deco_nHFTracks(
"nHFtrk"){
 
   32   declareInterface<IGNNVertexFitterInterface>(
this);
 
   52   std::string linkNameMod = 
"";
 
   63   return StatusCode::SUCCESS;
 
   68   TLorentzVector 
sum(0., 0., 0., 0.);
 
   69   for (
int i = 0; 
i < (
int)selTrk.size(); ++
i) {
 
   70     if (selTrk[
i] == NULL)
 
   72     sum += selTrk[
i]->p4();
 
   79                                             const std::vector<double> &secVrtErr, 
double &signif)
 const {
 
   80   double distx = primVrt.
x() - secVrt.x();
 
   81   double disty = primVrt.
y() - secVrt.y();
 
   82   double distz = primVrt.
z() - secVrt.z();
 
   84   AmgSymMatrix(3) primCovMtx = primVrt.covariancePosition(); 
 
   85   primCovMtx(0, 0) += secVrtErr[0];
 
   86   primCovMtx(0, 1) += secVrtErr[1];
 
   87   primCovMtx(1, 0) += secVrtErr[1];
 
   88   primCovMtx(1, 1) += secVrtErr[2];
 
   89   primCovMtx(0, 2) += secVrtErr[3];
 
   90   primCovMtx(2, 0) += secVrtErr[3];
 
   91   primCovMtx(1, 2) += secVrtErr[4];
 
   92   primCovMtx(2, 1) += secVrtErr[4];
 
   93   primCovMtx(2, 2) += secVrtErr[5];
 
   97   signif = distx * wgtMtx(0, 0) * distx + disty * wgtMtx(1, 1) * disty + distz * wgtMtx(2, 2) * distz +
 
   98            2. * distx * wgtMtx(0, 1) * disty + 2. * distx * wgtMtx(0, 2) * distz + 2. * disty * wgtMtx(1, 2) * distz;
 
   99   signif = std::sqrt(std::abs(signif));
 
  100   if (signif != signif)
 
  102   return std::sqrt(distx * distx + disty * disty + distz * distz);
 
  108                                                       const xAOD::Vertex &primVrt, 
const EventContext &ctx)
 const {
 
  110   using TLC = std::vector<ElementLink<DataVector<xAOD::TrackParticle_v1>>>;
 
  124     auto vertexCollection = vertexLinksHandle(*
jet);
 
  125     auto trackCollection = trackLinksHandle(*
jet);
 
  126     auto trackOriginCollection = trackOriginsHandle(*
jet);
 
  128     using indexList = std::vector<int>;
 
  129     using trackCountMap = std::map<char, std::set<TL>>;
 
  131     indexList iList(vertexCollection.size());
 
  133     trackCountMap allTracksMap;          
 
  134     trackCountMap heavyFlavourVertexMap; 
 
  135     trackCountMap primaryVertexMap; 
 
  136     trackCountMap fittingMap;            
 
  139     heavyFlavourVertexMap.clear();
 
  140     primaryVertexMap.clear();
 
  141     allTracksMap.clear();
 
  147       auto trackOrigin = trackOriginCollection[
index];
 
  148       auto trackLink   = trackCollection[
index];
 
  150       allTracksMap[
vertex].insert(trackLink);
 
  155         heavyFlavourVertexMap[
vertex].insert(trackLink);
 
  159         primaryVertexMap[
vertex].insert(trackLink);
 
  164     auto pvCandidate = std::max_element(
 
  165         primaryVertexMap.begin(), primaryVertexMap.end(),
 
  166         [](
const auto& 
a, 
const auto& 
b) { return a.second.size() < b.second.size(); }
 
  170     for (
const auto &vertexTrackPair : allTracksMap) {
 
  172       const auto &[
vertex, trackLinks] = vertexTrackPair;
 
  175         if(
vertex == pvCandidate) {
 
  181         if (heavyFlavourVertexMap.find(
vertex) == heavyFlavourVertexMap.end()) {
 
  187         if (heavyFlavourVertexMap.find(
vertex) != heavyFlavourVertexMap.end() &&
 
  188             (
static_cast<float>(heavyFlavourVertexMap[
vertex].size()) / trackLinks.size()) < 
m_HFRatioThres) {
 
  193       fittingMap.insert(std::pair<
char, std::set<TL>>(
vertex, trackLinks));
 
  198       const char mergedVertexKey = 0;
 
  199       std::set<TL> mergedSet;
 
  200       std::set<TL> combinedHFTracks;
 
  203       for (
const auto &vertexTrackPair : fittingMap) {
 
  205         mergedSet.insert(vertexTrackPair.second.begin(), vertexTrackPair.second.end());
 
  206         combinedHFTracks.insert(heavyFlavourVertexMap[vertexTrackPair.first].begin(), heavyFlavourVertexMap[vertexTrackPair.first].end());
 
  211       fittingMap[mergedVertexKey] = std::move(mergedSet);
 
  212       heavyFlavourVertexMap.clear();
 
  213       heavyFlavourVertexMap[mergedVertexKey] = std::move(combinedHFTracks);
 
  221     xAODwrk->beamX = beamSpotHandle->beamPos().x();
 
  222     xAODwrk->beamY = beamSpotHandle->beamPos().y();
 
  223     xAODwrk->beamZ = beamSpotHandle->beamPos().z();
 
  224     xAODwrk->tanBeamTiltX = 
tan(beamSpotHandle->beamTilt(0));
 
  225     xAODwrk->tanBeamTiltY = 
tan(beamSpotHandle->beamTilt(1));
 
  227     std::unique_ptr<std::vector<WrkVrt>> wrkVrtSet = std::make_unique<std::vector<WrkVrt>>();
 
  231     std::vector<const xAOD::NeutralParticle *> neutralPartDummy(0);
 
  234     for (
const auto &pair : fittingMap) {
 
  236       if (pair.second.size() >= 2) {
 
  237         int NTRKS = pair.second.size();
 
  238         std::vector<double> InpMass(NTRKS, 
m_massPi);
 
  241         xAODwrk->listSelTracks.clear();
 
  244           xAODwrk->listSelTracks.push_back(*
TrackLink);
 
  248         TLorentzVector jetDir(
jet->p4()); 
 
  253         if (
sc.isFailure() || FitVertex.perp() > 
m_maxLxy) { 
 
  258           vDist = FitVertex - primVrt.
position();
 
  259           double JetVrtDir = jetDir.Px() * vDist.x() + jetDir.Py() * vDist.y() + jetDir.Pz() * vDist.z();
 
  261             JetVrtDir = fabs(JetVrtDir); 
 
  271         sc = (
m_vertexFitterTool->VKalVrtFit(xAODwrk->listSelTracks, neutralPartDummy, newvrt.vertex, newvrt.vertexMom,
 
  272                                              newvrt.vertexCharge, newvrt.vertexCov, newvrt.chi2PerTrk, newvrt.trkAtVrt,
 
  273                                              newvrt.chi2, *state, 
false));
 
  278         auto NDOF = 2 * (newvrt.trkAtVrt.size()) - 3.0; 
 
  282         ATH_MSG_DEBUG(
"Found IniVertex=" << newvrt.vertex[0] << 
", " << newvrt.vertex[1] << 
", " << newvrt.vertex[2]
 
  283                                          << 
" trks " << newvrt.trkAtVrt.size());
 
  290             (vDir.x() * newvrt.vertexMom.Px() + vDir.y() * newvrt.vertexMom.Py() + vDir.z() * newvrt.vertexMom.Pz()) /
 
  291             newvrt.vertexMom.Rho();
 
  293         double Lxy = sqrt(vDir[0] * vDir[0] + vDir[1] * vDir[1]);
 
  294         double Lxyz = sqrt(vDir[0] * vDir[0] + vDir[1] * vDir[1] + vDir[2] * vDir[2]);
 
  299         int ntrk = newvrt.trkAtVrt.size(); 
 
  301         TLorentzVector MomentumVtx = 
TotalMom(xAODwrk->listSelTracks);
 
  303         double eRatio = MomentumVtx.E() / 
jet->p4().E();
 
  305         [[maybe_unused]] 
double distToPV = 
vrtVrtDist(primVrt, newvrt.vertex, newvrt.vertexCov, signif3D);
 
  323         for (
const auto *trk : xAODwrk->listSelTracks) {
 
  327           GNNvertex->addTrackAtVertex(link_trk, 1.);
 
  332         GNNvertex->setPosition(newvrt.vertex);
 
  333         GNNvertex->setFitQuality(newvrt.chi2, NDOF);
 
  336         m_deco_pt(*GNNvertex)              = newvrt.vertexMom.Perp();
 
  350         jetWriteDecorHandleVertexLink(*jet).push_back(linkVertex);
 
  355   return StatusCode::SUCCESS;