diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoConfig.py b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoConfig.py
index 5f71217e171dcbaf0f29954dca3391e764e457db..8b578896b97b37b3522d64ea8643e98d4f5251f8 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoConfig.py
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoConfig.py
@@ -111,5 +111,8 @@ class TrigMultiTrkComboHypoConfig(object):
         if 'noos' in chainDict['topo']:
             tool.totalCharge = -100 # negative number to indicate no charge cut
 
+        if 'Lxy0' in chainDict['topo']:
+            tool.LxyCut = 0.0
+
         tool.MonTool = TrigMultiTrkComboHypoToolMonitoring('MonTool')
         return tool
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoMonitoringConfig.py b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoMonitoringConfig.py
index cf34702cbeaded0516842208904b156f885e8021..6f78aea12b94bfa2a11c18cbbfc3eae083b913bc 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoMonitoringConfig.py
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/python/TrigMultiTrkComboHypoMonitoringConfig.py
@@ -24,6 +24,7 @@ class TrigMultiTrkComboHypoMonitoring(GenericMonitoringTool):
             defineHistogram('bphysFitMass', type='TH1F', path='EXPERT', title="fit mass of N tracks; fit mass of N selected tracks [GeV]", xbins=100, xmin=0, xmax=20),
             defineHistogram('bphysMass', type='TH1F', path='EXPERT', title="mass of N tracks; mass of N selected tracks [GeV]", xbins=100, xmin=0, xmax=20),
             defineHistogram('bphysCharge', type='TH1F', path='EXPERT', title="total charge of N tracks; Total Charge", xbins=20, xmin=-10, xmax=10),
+            defineHistogram('bphysLxy', type='TH1F', path='EXPERT', title="Lxy of Vertex; [mm]", xbins=30, xmin=-10, xmax=20),
             defineHistogram('TIME_all', type='TH1F', path='EXPERT', title='execution time; [microseconds]', xbins=100, xmin=0, xmax=1000),
             ]
 
@@ -34,6 +35,7 @@ class TrigMultiTrkComboHypoToolMonitoring(GenericMonitoringTool):
         defineHistogram('totalCharge', type='TH1F', path='EXPERT', title="Total Charge of N tracks; total charge", xbins=20, xmin=-10, xmax=10),
         defineHistogram('chi2', type='TH1F', path='EXPERT', title="chi2 fit of N tracks; vertex chi2", xbins=100, xmin=0, xmax=100),
         defineHistogram('mass', type='TH1F', path='EXPERT', title="mass of track pairs; m_{#mu#mu} [GeV]", xbins=100, xmin=0, xmax=20),
+        defineHistogram('Lxy', type='TH1F', path='EXPERT', title="Lxy of Vertex; [mm]", xbins=30, xmin=-10, xmax=20),
         defineHistogram('pT_trk1', type='TH1F', path='EXPERT', title="p_{T} of the first track; p_{T}(#mu_{1}) [GeV]", xbins=100, xmin=0, xmax=40),
         defineHistogram('pT_trk2', type='TH1F', path='EXPERT', title="p_{T} of the second track; p_{T}(#mu_{2}) [GeV]", xbins=100, xmin=0, xmax=40),
         ]
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigBmumuxComboHypo.cxx b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigBmumuxComboHypo.cxx
index 51afbededbef64319ff0f060e64cfdc1a0a24a1a..77cfe5ad6ed415a547bcb5bd37e4591942e46acb 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigBmumuxComboHypo.cxx
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigBmumuxComboHypo.cxx
@@ -313,7 +313,7 @@ StatusCode TrigBmumuxComboHypo::findDimuonCandidates(TrigBmumuxState& state) con
       }
 
       // fit muons to the common vertex and pass this vertex to the dimuons collection which also takes the ownership of the created object
-      xAOD::Vertex* vertex = fit(trackParticleLinks);
+      xAOD::Vertex* vertex = fit(state.context, trackParticleLinks);
       if (!vertex) continue;
       muonIndices(*vertex) = std::vector<size_t>{itrk1, itrk2};
       state.dimuons.push_back(vertex);
@@ -399,7 +399,7 @@ StatusCode TrigBmumuxComboHypo::findBmumuxCandidates(TrigBmumuxState& state) con
       if (m_BplusToMuMuKaon &&
           p_trk1.Pt() > m_BplusToMuMuKaon_minKaonPt &&
           isInMassRange((p_dimuon + p_trk1.SetM(PDG::mKaon)).M(), m_BplusToMuMuKaon_massRange)) {
-        vtx1 = fit(trackParticleLinks_vtx1, kB_2mu1trk, *dimuonTriggerObjectEL);
+        vtx1 = fit(state.context, trackParticleLinks_vtx1, kB_2mu1trk, *dimuonTriggerObjectEL);
         makeFit_vtx1 = false;
         if (vtx1 && vtx1->chiSquared() < m_BplusToMuMuKaon_chi2) {
           xAOD::TrigBphys* trigBphys = makeTriggerObject(vtx1, xAOD::TrigBphys::BKMUMU, {PDG::mMuon, PDG::mMuon, PDG::mKaon}, dimuonTriggerObjectEL);
@@ -413,7 +413,7 @@ StatusCode TrigBmumuxComboHypo::findBmumuxCandidates(TrigBmumuxState& state) con
           isInMassRange(p_dimuon.M(), m_BcToMuMuPion_dimuonMassRange) &&
           isInMassRange((p_dimuon + p_trk1.SetM(PDG::mPion)).M() - p_dimuon.M() + PDG::mJpsi, m_BcToMuMuPion_massRange)) {
         if (!vtx1 && makeFit_vtx1) {
-          vtx1 = fit(trackParticleLinks_vtx1, kB_2mu1trk, *dimuonTriggerObjectEL);
+          vtx1 = fit(state.context, trackParticleLinks_vtx1, kB_2mu1trk, *dimuonTriggerObjectEL);
           makeFit_vtx1 = false;
         }
         if (vtx1 && vtx1->chiSquared() < m_BcToMuMuPion_chi2) {
@@ -445,7 +445,7 @@ StatusCode TrigBmumuxComboHypo::findBmumuxCandidates(TrigBmumuxState& state) con
             p_trk2.Pt() > m_BsToMuMuPhi1020_minKaonPt &&
             isInMassRange((p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mKaon)).M(), m_BsToMuMuPhi1020_phiMassRange) &&
             isInMassRange((p_dimuon + p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mKaon)).M(), m_BsToMuMuPhi1020_massRange)) {
-          vtx2 = fit(trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
+          vtx2 = fit(state.context, trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
           makeFit_vtx2 = false;
           if (vtx2 && vtx2->chiSquared() < m_BsToMuMuPhi1020_chi2) {
             xAOD::TrigBphys* trigBphys = makeTriggerObject(vtx2, xAOD::TrigBphys::BSPHIMUMU, {PDG::mMuon, PDG::mMuon, PDG::mKaon, PDG::mKaon}, dimuonTriggerObjectEL);
@@ -461,7 +461,7 @@ StatusCode TrigBmumuxComboHypo::findBmumuxCandidates(TrigBmumuxState& state) con
             isInMassRange((p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mPion)).M(), m_BdToMuMuKstar0_KstarMassRange) &&
             isInMassRange((p_dimuon + p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mPion)).M(), m_BdToMuMuKstar0_massRange)) {
           if (!vtx2 && makeFit_vtx2) {
-            vtx2 = fit(trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
+            vtx2 = fit(state.context, trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
             makeFit_vtx2 = false;
           }
           if (vtx2 && vtx2->chiSquared() < m_BdToMuMuKstar0_chi2) {
@@ -477,7 +477,7 @@ StatusCode TrigBmumuxComboHypo::findBmumuxCandidates(TrigBmumuxState& state) con
             isInMassRange((p_trk1.SetM(PDG::mPion) + p_trk2.SetM(PDG::mKaon)).M(), m_BdToMuMuKstar0_KstarMassRange) &&
             isInMassRange((p_dimuon + p_trk1.SetM(PDG::mPion) + p_trk2.SetM(PDG::mKaon)).M(), m_BdToMuMuKstar0_massRange)) {
           if (!vtx2 && makeFit_vtx2) {
-            vtx2 = fit(trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
+            vtx2 = fit(state.context, trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
             makeFit_vtx2 = false;
           }
           if (vtx2 && vtx2->chiSquared() < m_BdToMuMuKstar0_chi2) {
@@ -495,7 +495,7 @@ StatusCode TrigBmumuxComboHypo::findBmumuxCandidates(TrigBmumuxState& state) con
             isInMassRange(p_dimuon.M(), m_LambdaBToMuMuProtonKaon_dimuonMassRange) &&
             isInMassRange((p_dimuon + p_trk1.SetM(PDG::mProton) + p_trk2.SetM(PDG::mKaon)).M() - p_dimuon.M() + PDG::mJpsi, m_LambdaBToMuMuProtonKaon_massRange)) {
           if (!vtx2 && makeFit_vtx2) {
-            vtx2 = fit(trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
+            vtx2 = fit(state.context, trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
             makeFit_vtx2 = false;
           }
           if (vtx2 && vtx2->chiSquared() < m_LambdaBToMuMuProtonKaon_chi2) {
@@ -512,7 +512,7 @@ StatusCode TrigBmumuxComboHypo::findBmumuxCandidates(TrigBmumuxState& state) con
             isInMassRange(p_dimuon.M(), m_LambdaBToMuMuProtonKaon_dimuonMassRange) &&
             isInMassRange((p_dimuon + p_trk1.SetM(PDG::mKaon) + p_trk2.SetM(PDG::mProton)).M() - p_dimuon.M() + PDG::mJpsi, m_LambdaBToMuMuProtonKaon_massRange)) {
           if (!vtx2 && makeFit_vtx2) {
-            vtx2 = fit(trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
+            vtx2 = fit(state.context, trackParticleLinks_vtx2, kB_2mu2trk, *dimuonTriggerObjectEL);
             makeFit_vtx2 = false;
           }
           if (vtx2 && vtx2->chiSquared() < m_LambdaBToMuMuProtonKaon_chi2) {
@@ -584,7 +584,8 @@ StatusCode TrigBmumuxComboHypo::createDecisionObjects(TrigBmumuxState& state) co
 }
 
 
-xAOD::Vertex* TrigBmumuxComboHypo::fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& trackParticleLinks,
+xAOD::Vertex* TrigBmumuxComboHypo::fit(const EventContext* context,
+                                       const std::vector<ElementLink<xAOD::TrackParticleContainer>>& trackParticleLinks,
                                        Decay decay,
                                        const xAOD::TrigBphys* dimuon) const {
   ATH_MSG_DEBUG( "Perform vertex fit" );
@@ -615,7 +616,7 @@ xAOD::Vertex* TrigBmumuxComboHypo::fit(const std::vector<ElementLink<xAOD::Track
   }
   ATH_MSG_DEBUG( "Starting point: (" << startingPoint(0) << ", " << startingPoint(1) << ", " << startingPoint(2) << ")" );
 
-  auto fitterState = m_vertexFitter->makeState();
+  auto fitterState = m_vertexFitter->makeState(*context);
   m_vertexFitter->setMassInputParticles(m_trkMass[static_cast<size_t>(decay)], *fitterState);
   xAOD::Vertex* vertex = m_vertexFitter->fit(tracklist, startingPoint, *fitterState);
   if (!vertex) {
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigBmumuxComboHypo.h b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigBmumuxComboHypo.h
index 2a26d34de3153f0d8112433991ed712f6ca79f68..9c83a32fb5ddca3e3b91c68329178318738eb6c8 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigBmumuxComboHypo.h
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigBmumuxComboHypo.h
@@ -99,7 +99,8 @@ class TrigBmumuxComboHypo: public ::ComboHypo {
   StatusCode findDimuonCandidates(TrigBmumuxState&) const;
   StatusCode findBmumuxCandidates(TrigBmumuxState&) const;
   StatusCode createDecisionObjects(TrigBmumuxState&) const;
-  xAOD::Vertex* fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& tracklist, Decay = kPsi_2mu, const xAOD::TrigBphys* dimuon = nullptr) const;
+  xAOD::Vertex* fit(const EventContext* context, const std::vector<ElementLink<xAOD::TrackParticleContainer>>& tracklist,
+                                     Decay = kPsi_2mu, const xAOD::TrigBphys* dimuon = nullptr) const;
   xAOD::TrigBphys* makeTriggerObject(const xAOD::Vertex*,
                                      xAOD::TrigBphys::pType type = xAOD::TrigBphys::MULTIMU,
                                      const std::vector<double>& trkMass = {PDG::mMuon, PDG::mMuon},
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.cxx b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.cxx
index e5a3b6ae965b67c7a4e76a480c07140cc91a5253..c48a0eaffc80d91a4332c5ed69cfb64d1b77fb69 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.cxx
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.cxx
@@ -153,6 +153,7 @@ StatusCode TrigMultiTrkComboHypo::initialize() {
     ATH_MSG_DEBUG( "No GenericMonitoringTool configured: no monitoring histograms will be available" );
   }
 
+  ATH_CHECK( m_beamSpotKey.initialize(m_trigLevelString == "EF")); //Only enable for EF
   return StatusCode::SUCCESS;
 }
 
@@ -265,12 +266,12 @@ StatusCode TrigMultiTrkComboHypo::executeL2(const EventContext& context) const {
 
       if (!isInMassRange(mass)) continue;
 
-      xAOD::TrigBphys* trigBphys = fit(std::vector<ElementLink<xAOD::TrackParticleContainer>>{tracks[itrk1], tracks[itrk2]});
-      if (!trigBphys) continue;
+      auto fitterState = m_vertexFitter->makeState(context);
+      std::unique_ptr<xAOD::Vertex> vertex(fit(std::vector<ElementLink<xAOD::TrackParticleContainer>>{tracks[itrk1], tracks[itrk2]}, fitterState.get()));
+      if (!vertex) continue;
 
       ATH_MSG_DEBUG( "Found good dimuon pair at L2 level: stop looking for dimuon pairs" );
       mon_isEventAccepted = 1;
-      delete trigBphys;
       break;
     }
   }
@@ -312,6 +313,11 @@ StatusCode TrigMultiTrkComboHypo::executeEF(const EventContext& context) const {
   ATH_CHECK( trigBphysHandle.record(std::make_unique<xAOD::TrigBphysContainer>(),
                                     std::make_unique<xAOD::TrigBphysAuxContainer>()) );
 
+  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey, context };
+  if(!beamSpotHandle.isValid()) {
+    ATH_MSG_ERROR( "BeamSpot not found" );
+    return StatusCode::FAILURE;
+  }
   // monitored variables
   auto mon_nTrk = Monitored::Scalar<int>("nTrk", 0);
   auto mon_nAcceptedTrk = Monitored::Scalar<int>("nAcceptedTrk", 0);
@@ -324,6 +330,7 @@ StatusCode TrigMultiTrkComboHypo::executeEF(const EventContext& context) const {
   std::vector<int> bphysCharge;
   auto mon_trkMassBeforeFit = Monitored::Collection("trkMassBeforeFit", trkMassBeforeFit);
   auto mon_bphysChi2 = Monitored::Collection("bphysChi2", *trigBphysHandle, &xAOD::TrigBphys::fitchi2);
+  auto mon_bphysLxy = Monitored::Collection("bphysLxy", *trigBphysHandle, &xAOD::TrigBphys::lxy);
   auto mon_bphysFitMass = Monitored::Collection("bphysFitMass", *trigBphysHandle, [](const xAOD::TrigBphys* x){ return x->fitmass()*0.001; } );
   auto mon_bphysMass = Monitored::Collection("bphysMass", bphysMass);
   auto mon_bphysCharge = Monitored::Collection("bphysCharge", bphysCharge);
@@ -332,7 +339,7 @@ StatusCode TrigMultiTrkComboHypo::executeEF(const EventContext& context) const {
 
   auto group = Monitored::Group(m_monTool,
     mon_nTrk, mon_nAcceptedTrk, mon_nCombination, mon_nCombinationBeforeFit, mon_nBPhysObject,
-    mon_trkMassBeforeFit, mon_bphysChi2, mon_bphysFitMass, mon_bphysMass, mon_bphysCharge,
+    mon_trkMassBeforeFit, mon_bphysChi2, mon_bphysLxy, mon_bphysFitMass, mon_bphysMass, mon_bphysCharge,
     mon_timer);
 
   // combine all muons from the event views, make overlap removal
@@ -413,10 +420,11 @@ StatusCode TrigMultiTrkComboHypo::executeEF(const EventContext& context) const {
       if (!isInMassRange(mass)) continue;
 
       mon_nCombinationBeforeFit++;
-
-      xAOD::TrigBphys* trigBphys = fit(std::vector<ElementLink<xAOD::TrackParticleContainer>>{tracks[itrk1].first, tracks[itrk2].first});
-      if (!trigBphys) continue;
-
+      auto fitterState = m_vertexFitter->makeState(context);
+      std::vector<ElementLink<xAOD::TrackParticleContainer>> trackLinks {tracks[itrk1].first, tracks[itrk2].first};
+      std::unique_ptr<xAOD::Vertex> vertex(fit(trackLinks, fitterState.get()));
+      if (!vertex) continue;
+      xAOD::TrigBphys* trigBphys = makeTrigBPhys(vertex.get(), fitterState.get(), beamSpotHandle->beamPos());
       trigBphysHandle->push_back(trigBphys);
       trigBphysTrackIdx.emplace_back(std::vector<size_t>{itrk1, itrk2});
 
@@ -470,8 +478,9 @@ StatusCode TrigMultiTrkComboHypo::executeEF(const EventContext& context) const {
 }
 
 
-xAOD::TrigBphys* TrigMultiTrkComboHypo::fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& trackParticleLinks) const {
-  xAOD::TrigBphys* result = nullptr;
+xAOD::Vertex* TrigMultiTrkComboHypo::fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& trackParticleLinks,
+         Trk::IVKalState* fitterState) const {
+
 
   ATH_MSG_DEBUG( "Perform vertex fit" );
   std::vector<const xAOD::TrackParticle*> tracklist(trackParticleLinks.size(), nullptr);
@@ -486,20 +495,25 @@ xAOD::TrigBphys* TrigMultiTrkComboHypo::fit(const std::vector<ElementLink<xAOD::
   if (errorcode != 0) startingPoint = Amg::Vector3D::Zero(3);
   ATH_MSG_DEBUG( "Starting point: (" << startingPoint(0) << ", " << startingPoint(1) << ", " << startingPoint(2) << ")" );
 
-  auto fitterState = m_vertexFitter->makeState();
   m_vertexFitter->setMassInputParticles(m_trkMass, *fitterState);
   xAOD::Vertex* vertex = m_vertexFitter->fit(tracklist, startingPoint, *fitterState);
   if (!vertex) {
     ATH_MSG_DEBUG( "Vertex fit fails" );
-    return result;
+    return nullptr;
   }
   if (vertex->chiSquared() > 150.) {
     ATH_MSG_DEBUG( "Fit is successful, but vertex chi2 is too high, we are not going to save it (chi2 = " << vertex->chiSquared() << ")" );
     delete vertex;
-    return result;
+    return nullptr;
   }
   ATH_MSG_DEBUG( "Fit is successful" );
+  vertex->clearTracks();
+  vertex->setTrackParticleLinks(trackParticleLinks);
+  return vertex;
+}
+
 
+xAOD::TrigBphys* TrigMultiTrkComboHypo::makeTrigBPhys(xAOD::Vertex* vertex, Trk::IVKalState* fitterState, const Amg::Vector3D  &beamspot) const {
   double invariantMass = 0.;
   double invariantMassError = 0.;
   if (!m_vertexFitter->VKalGetMassError(invariantMass, invariantMassError, *fitterState).isSuccess()) {
@@ -507,14 +521,14 @@ xAOD::TrigBphys* TrigMultiTrkComboHypo::fit(const std::vector<ElementLink<xAOD::
     invariantMass = -9999.;
   }
 
-  xAOD::TrackParticle::GenVecFourMom_t momentum;
+  xAOD::TrackParticle::GenVecFourMom_t momentum(0, 0, 0, 0);
   for (size_t i = 0; i < vertex->nTrackParticles(); ++i) {
     auto p = vertex->trackParticle(i)->genvecP4();
     p.SetM(m_trkMass[i]);
     momentum += p;
   }
 
-  result = new xAOD::TrigBphys();
+  xAOD::TrigBphys* result = new xAOD::TrigBphys();
   result->makePrivateStore();
   result->initialise(0, momentum.Eta(), momentum.Phi(), momentum.Pt(), xAOD::TrigBphys::MULTIMU, momentum.M(), m_trigLevel);
 
@@ -524,9 +538,8 @@ xAOD::TrigBphys* TrigMultiTrkComboHypo::fit(const std::vector<ElementLink<xAOD::
   result->setFitx(vertex->x());
   result->setFity(vertex->y());
   result->setFitz(vertex->z());
-  result->setTrackParticleLinks(trackParticleLinks);
-
-  delete vertex;
+  result->setTrackParticleLinks(vertex->trackParticleLinks());
+  result->setLxy(Lxy(result, beamspot));
 
   ATH_MSG_DEBUG(
     "TrigBphys objects:\n\t  " <<
@@ -538,7 +551,8 @@ xAOD::TrigBphys* TrigMultiTrkComboHypo::fit(const std::vector<ElementLink<xAOD::
     "mass:          " << result->mass() << "\n\t  " <<
     "fitmass:       " << result->fitmass() << "\n\t  " <<
     "chi2/NDF:      " << result->fitchi2() << " / " << result->fitndof() << "\n\t  " <<
-    "vertex:        (" << result->fitx() << ", " << result->fity() << ", " << result->fitz() << ")" );
+    "vertex:        (" << result->fitx() << ", " << result->fity() << ", " << result->fitz() << "\n\t  " << 
+    "Lxy            " <<  result->lxy() << ")" );
 
   return result;
 }
@@ -550,6 +564,20 @@ bool TrigMultiTrkComboHypo::isIdenticalTracks(const xAOD::TrackParticle* lhs, co
   return (ROOT::Math::VectorUtil::DeltaR(lhs->genvecP4(), rhs->genvecP4()) < m_deltaR);
 }
 
+float TrigMultiTrkComboHypo::Lxy(const xAOD::TrigBphys* bphy, const Amg::Vector3D  &beamSpot) const{
+    double Dx = bphy->fitx() - beamSpot.x();
+    double Dy = bphy->fity() - beamSpot.y();
+    double pBx = 0, pBy=0;
+    size_t n = bphy->nTrackParticles();
+    for (size_t i = 0; i < n; ++i) {
+        auto mom = bphy->trackParticle(i)->genvecP4();
+        pBx+= mom.x();
+        pBy+= mom.y();
+    }
+    double pBt = std::sqrt(pBx*pBx + pBy*pBy);
+    double BsLxy = (pBx*Dx+pBy*Dy)/pBt;
+    return BsLxy;
+}
 
 bool TrigMultiTrkComboHypo::isInMassRange(double mass) const {
 
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.h b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.h
index 8d497279ee3e1f16522a06d3509978c574f83d68..f96b337cbf22cf0cc1f0d905a0c750e9ae353ad7 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.h
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypo.h
@@ -36,6 +36,11 @@
 #include "AthenaMonitoringKernel/GenericMonitoringTool.h"
 
 #include "TrigMultiTrkComboHypoTool.h"
+#include "BeamSpotConditionsData/BeamSpotData.h"
+
+namespace Trk {
+class IVKalState;
+}
 
 
 class TrigMultiTrkComboHypo: public ::ComboHypo {
@@ -52,10 +57,11 @@ class TrigMultiTrkComboHypo: public ::ComboHypo {
  private:
   StatusCode executeL2(const EventContext& context) const;
   StatusCode executeEF(const EventContext& context) const;
-  xAOD::TrigBphys* fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& tracklist) const;
+  xAOD::Vertex* fit(const std::vector<ElementLink<xAOD::TrackParticleContainer>>& tracklist, Trk::IVKalState*) const;
+  xAOD::TrigBphys* makeTrigBPhys(xAOD::Vertex* vertex, Trk::IVKalState* fitterState, const Amg::Vector3D  &beamspot) const;
   bool isIdenticalTracks(const xAOD::TrackParticle* lhs, const xAOD::TrackParticle* rhs) const;
   bool isInMassRange(double mass) const;
-
+  float Lxy(const xAOD::TrigBphys*, const Amg::Vector3D&) const;
   SG::ReadHandleKey<xAOD::TrackParticleContainer>
     m_trackParticleContainerKey {this, "TrackCollectionKey", "Tracks", "input TrackParticle container name"};
 
@@ -78,7 +84,7 @@ class TrigMultiTrkComboHypo: public ::ComboHypo {
   ToolHandle<Trk::TrkVKalVrtFitter> m_vertexFitter {this, "VertexFitter", "", "VKalVrtFitter tool to fit tracks into the common vertex"};
 
   ToolHandle<GenericMonitoringTool> m_monTool {this, "MonTool", "", "monitoring tool"};
-
+  SG::ReadCondHandleKey<InDet::BeamSpotData> m_beamSpotKey { this, "BeamSpotKey", "BeamSpotData", "SG key for beam spot" };
   TrigCompositeUtils::DecisionIDContainer m_allowedIDs;
 
 };
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.cxx b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.cxx
index 6795284168d82f20f033967177a2a513ceaa93e9..0801e7b0ff8cdc87c7f1a84c2b16d31dd378c40d 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.cxx
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.cxx
@@ -32,7 +32,8 @@ StatusCode TrigMultiTrkComboHypoTool::initialize() {
                  "   AcceptAll = " << (m_acceptAll ? "True" : "False") << endmsg <<
                  "   mass range: ( " <<  m_massRange.value().first << ", " << m_massRange.value().second << " )" << endmsg <<
                  "   chi2 cut: " << m_chi2 << endmsg <<
-                 "   " << (m_totalCharge < 0 ? "total charge cut is disabled" : "total charge cut: only right charge combinations") );
+                 "   " << (m_totalCharge < 0 ? "total charge cut is disabled" : "total charge cut: only right charge combinations"));
+  ATH_MSG_DEBUG("   LxyCut: > " << m_LxyCut.value());
 
   ATH_CHECK( m_nTrk >= 2 );
 
@@ -56,10 +57,13 @@ bool TrigMultiTrkComboHypoTool::passed(const xAOD::TrigBphys* trigBphys) const {
   auto mon_mass = Monitored::Scalar<float>("mass", -1.);
   auto mon_pT_trk1 = Monitored::Scalar<float>("pT_trk1", -1.);
   auto mon_pT_trk2 = Monitored::Scalar<float>("pT_trk2", -1.);
+  auto mon_Lxy  = Monitored::Scalar<float>("Lxy", -1.);
 
-  auto mon = Monitored::Group( m_monTool, mon_totalCharge, mon_chi2, mon_mass, mon_pT_trk1, mon_pT_trk2);
+  auto mon = Monitored::Group( m_monTool, mon_totalCharge, mon_chi2, mon_mass, mon_pT_trk1, mon_pT_trk2, mon_Lxy);
 
-  if (m_acceptAll || (isInMassRange(trigBphys->mass()) && passedChi2Cut(trigBphys->fitchi2()) && passedChargeCut(totalCharge(trigBphys)))) {
+  if (m_acceptAll || (isInMassRange(trigBphys->mass()) && passedChi2Cut(trigBphys->fitchi2()) && passedChargeCut(totalCharge(trigBphys)) && 
+             trigBphys->lxy() > m_LxyCut )) {
+    mon_Lxy = trigBphys->lxy();
     mon_totalCharge = totalCharge(trigBphys);
     mon_chi2 = trigBphys->fitchi2();
     mon_mass = trigBphys->mass();
diff --git a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.h b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.h
index d690479b56fc5c2b0c0cb13bf948bf1fd2e69af3..618deaa84c086c19431a5ee52968a348505379ff 100644
--- a/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.h
+++ b/Trigger/TrigHypothesis/TrigBphysHypo/src/TrigMultiTrkComboHypoTool.h
@@ -51,7 +51,7 @@ class TrigMultiTrkComboHypoTool: public ComboHypoToolBase {
   Gaudi::Property<std::pair<double, double>> m_massRange {this, "massRange", {-99., -9.}, "range for the fitted mass, no selection applied if negative"};
   Gaudi::Property<float> m_chi2 {this, "chi2", -99. , "Chi2 cut for vertex (0 < chi2 < cut), no selection applied if negative" };
   Gaudi::Property<bool> m_acceptAll {this, "AcceptAll", false, "if AcceptAll flag is set to true, no selection will be applied for xAOD::TrigBphys object" };
-
+  Gaudi::Property<float> m_LxyCut {this, "LxyCut", -999., "Applies an Lxy Cut if set > -999"};
   ToolHandle<GenericMonitoringTool> m_monTool { this, "MonTool", "", "Monitoring tool" };
 };