diff --git a/Trigger/TrigAlgorithms/TrigT2BeamSpot/CMakeLists.txt b/Trigger/TrigAlgorithms/TrigT2BeamSpot/CMakeLists.txt
index ce22c00a73fea15bc07068db2fe0e838af85d5d2..dcaab83db172601906ea951f7185c3c6d641118d 100644
--- a/Trigger/TrigAlgorithms/TrigT2BeamSpot/CMakeLists.txt
+++ b/Trigger/TrigAlgorithms/TrigT2BeamSpot/CMakeLists.txt
@@ -11,7 +11,10 @@ atlas_add_component( TrigT2BeamSpot
                      src/*.cxx
                      src/components/TrigT2*.cxx
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers AthenaBaseComps AthenaMonitoringKernelLib BeamSpotConditionsData EventPrimitives GaudiKernel StoreGateLib TrigInDetEvent TrigInDetToolInterfacesLib TrigInterfacesLib TrigNavigationLib TrigSteeringEvent TrigTimeAlgsLib TrkParameters TrkTrack TrkTrackSummary xAODEventInfo )
+                     LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers AthenaBaseComps AthenaMonitoringKernelLib
+                        BeamSpotConditionsData EventPrimitives GaudiKernel StoreGateLib TrigInDetEvent
+                        TrigInDetToolInterfacesLib TrigInterfacesLib TrigNavigationLib TrigSteeringEvent
+                        TrigTimeAlgsLib TrkParameters TrkTrack TrkTrackSummary xAODEventInfo )
 
 # Install files from the package:
 atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
diff --git a/Trigger/TrigAlgorithms/TrigT2BeamSpot/TrigT2BeamSpot/T2VertexBeamSpotTool.h b/Trigger/TrigAlgorithms/TrigT2BeamSpot/TrigT2BeamSpot/T2VertexBeamSpotTool.h
index ba80ec2c7b4a1faaf09275e3b47939b73d5909b5..bbff59fcf9269747dd746735173f44098e9c95db 100644
--- a/Trigger/TrigAlgorithms/TrigT2BeamSpot/TrigT2BeamSpot/T2VertexBeamSpotTool.h
+++ b/Trigger/TrigAlgorithms/TrigT2BeamSpot/TrigT2BeamSpot/T2VertexBeamSpotTool.h
@@ -29,6 +29,7 @@
 #include "../src/T2Track.h"
 #include "../src/T2BeamSpot.h"
 #include "../src/T2SplitVertex.h"
+#include "../src/T2TrackClusterer.h"
 //Athena tools
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "GaudiKernel/ToolHandle.h"
@@ -54,7 +55,6 @@ namespace HLT {
 }
 namespace PESA {
    class T2SplitVertex;
-   class T2TrackClusterer;
    /**
     *   This class uses primary vertex reconstruction to measure
     *   and monitor the LHC beam as seen by the ATLAS detector. 
@@ -116,6 +116,8 @@ namespace PESA {
          bool         m_splitWholeCluster;
          bool         m_reclusterSplit;
          double       m_trackSeedPt;
+         std::string  m_clusterPerigee = "original"; // one of "original", "beamspot", "beamline"
+         T2TrackClusterer::TrackPerigee m_clusterTrackPerigee = T2TrackClusterer::perigee_original;
 
          /* Track selection criteria */
          unsigned  m_totalNTrkMin;
@@ -177,10 +179,8 @@ namespace PESA {
          std::string m_vertexCollName;
 
       private:
-         ToolHandle<GenericMonitoringTool> m_monTool{this,"MonTool","","Monitoring tool"};
-
-         
 
+         ToolHandle<GenericMonitoringTool> m_monTool{this,"MonTool","","Monitoring tool"};
 
    };
 
diff --git a/Trigger/TrigAlgorithms/TrigT2BeamSpot/python/T2VertexBeamSpotConfig.py b/Trigger/TrigAlgorithms/TrigT2BeamSpot/python/T2VertexBeamSpotConfig.py
index 9a82a28453f462f7c7beb3fe564d5dc512e13978..7b7a431bcbcfc7168183029a873b6afa21ec1b54 100644
--- a/Trigger/TrigAlgorithms/TrigT2BeamSpot/python/T2VertexBeamSpotConfig.py
+++ b/Trigger/TrigAlgorithms/TrigT2BeamSpot/python/T2VertexBeamSpotConfig.py
@@ -21,6 +21,7 @@ InDetTrigMTBeamSpotTool = PESA__T2VertexBeamSpotTool(
     MonTool = bsToolMonitoring,
     WeightClusterZ      = True,     # Use the track Z0 weighted cluster Z position as seed
     ReclusterSplit      = False,    # Recluster split track collections before vertex fitting
+    ClusterPerigee      = "beamspot",
     nSplitVertices      = 2,        # Turn on (>1) or off vertex splitting
     TotalNTrackMin      = 4,        # Minimum number of tracks required in an event
     TrackMinPt          = 0.5,      # Minimum track pT to be considered for vertexing
diff --git a/Trigger/TrigAlgorithms/TrigT2BeamSpot/python/T2VertexBeamSpotMonitoring.py b/Trigger/TrigAlgorithms/TrigT2BeamSpot/python/T2VertexBeamSpotMonitoring.py
index 94b7896b2184672fe7fb48e726c650bb797737bc..87c857417a5ad997a5d2dc3f37a947a1adefff94 100644
--- a/Trigger/TrigAlgorithms/TrigT2BeamSpot/python/T2VertexBeamSpotMonitoring.py
+++ b/Trigger/TrigAlgorithms/TrigT2BeamSpot/python/T2VertexBeamSpotMonitoring.py
@@ -237,6 +237,8 @@ class T2VertexBeamSpotToolMonitoring(BaseMonitoringTool):
                              title="ClusterDeltaZ0; Delta of track Z0 and cluster Z position [mm]; Number of tracks")
             self.makeHisto1D('ClusterZ0Pull', 'TH1I', 100, -10.0, 10.0,
                              title="ClusterZ0Pull; Pull of track Z0 with respect to cluster Z position; Number of tracks")
+            self.makeHisto1D('ClusterClusterDeltaZ0', 'TH1I', 200, -100.0, 100.0,
+                             title="ClusterClusterDeltaZ0; Delta of cluster-cluster Z position [mm]; Number of clusters")
 
     def defineVertexHistos(self, detail):
 
diff --git a/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2TrackClusterer.cxx b/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2TrackClusterer.cxx
index 4454071b7e0c1380ea2c2fd5bd08d4aa08268a09..fdce5e5daa8c736851fd9eb0a0ad0fc90c30cf09 100644
--- a/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2TrackClusterer.cxx
+++ b/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2TrackClusterer.cxx
@@ -10,14 +10,34 @@
 
 #include "TrkParameters/TrackParameters.h"
 #include "EventPrimitives/EventPrimitivesHelpers.h"
+#include "BeamSpotConditionsData/BeamSpotData.h"
 
 #include <cmath>
+#include <stdexcept>
+
 using std::abs;
 using std::sqrt;
+using std::sin;
+using std::cos;
+using std::tan;
 
 using namespace PESA;
 
 
+T2TrackClusterer::TrackPerigee
+T2TrackClusterer::trackPerigeeFromString(const std::string& perigeeStr)
+{
+   if (perigeeStr == "original") {
+      return perigee_original;
+   } else if (perigeeStr == "beamspot") {
+      return perigee_beamspot;
+   } else if (perigeeStr == "beamline") {
+      return perigee_beamline;
+   } else {
+     throw std::runtime_error("Invalid value of ClusterPerigee parameter: " + perigeeStr);
+   }
+}
+
 double
 T2TrackClusterer::trackWeight( const Trk::Track& track ) const
 {
@@ -27,7 +47,7 @@ T2TrackClusterer::trackWeight( const Trk::Track& track ) const
 }
 
 const TrackCollection&
-T2TrackClusterer::cluster( const TrackCollection& tracks )
+T2TrackClusterer::cluster( const TrackCollection& tracks, const InDet::BeamSpotData* beamspot )
 {
   m_seedZ0      = 0.;
   m_totalZ0Err  = 0.;
@@ -41,9 +61,9 @@ T2TrackClusterer::cluster( const TrackCollection& tracks )
     }
 
   const Trk::Track* seedTrack = *tracks.begin();
-  
-  const Trk::TrackParameters* seedTrackPars = seedTrack->perigeeParameters();
-  const double seedPT = std::abs(sin(seedTrackPars->parameters()[Trk::theta])/seedTrackPars->parameters()[Trk::qOverP]);
+
+  auto& params = seedTrack->perigeeParameters()->parameters();
+  const double seedPT = std::abs(sin(params[Trk::theta])/params[Trk::qOverP]);
 
   if ( seedPT < m_minPT )
     {
@@ -51,16 +71,16 @@ T2TrackClusterer::cluster( const TrackCollection& tracks )
       return *m_cluster.asDataVector();
     }
 
+
   double sumWeight = trackWeight( *seedTrack );
-  m_seedZ0 = seedTrackPars->parameters()[Trk::z0]; // becomes the weighted-average z0 of the cluster
+  m_seedZ0 = trackPerigeeZ0(*seedTrack, beamspot);
 
   m_cluster.push_back( seedTrack );
 
   for ( TrackCollection::const_iterator track = tracks.begin() + 1;
         track != tracks.end(); ++track )
     {
-      const Trk::TrackParameters* trackPars = (*track)->perigeeParameters();
-      const double trackZ0 = trackPars->parameters()[Trk::z0];
+      const double trackZ0 = trackPerigeeZ0(**track, beamspot);
       const double deltaZ  = trackZ0 - m_seedZ0;
       const double weight  = trackWeight( **track );
 
@@ -81,3 +101,32 @@ T2TrackClusterer::cluster( const TrackCollection& tracks )
 
   return *m_cluster.asDataVector();
 }
+
+double
+T2TrackClusterer::trackPerigeeZ0(const Trk::Track& track, const InDet::BeamSpotData* beamspot) const
+{
+  auto& params0 = track.perigeeParameters()->parameters();
+  if (m_trackPerigee == perigee_original or beamspot == nullptr) {
+    return params0[Trk::z0];
+  } else if (m_trackPerigee == perigee_beamspot or m_trackPerigee == perigee_beamline) {
+    // TODO: beamline is doing the same as beamspot for now, I think it should be OK
+    // with our track resolution, somethig to check in the future (when I retire)
+
+    // This assumes that track perigee is defined at 0,0, transform is:
+    //     z = z_0 + (B_x*cos(phi) + B_y*sin(phi)) / tan(theta)
+
+    double z_0 = params0[Trk::z0];
+    double phi = params0[Trk::phi];
+    double theta = params0[Trk::theta];
+    auto& beamPos = beamspot->beamPos();
+    double B_x = beamPos[0];
+    double B_y = beamPos[1];
+
+    double z = z_0 + (B_x*cos(phi) + B_y*sin(phi)) / tan(theta);
+    return z;
+
+  } else {
+    // fallback to "original"
+    return params0[Trk::z0];
+  }
+}
\ No newline at end of file
diff --git a/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2TrackClusterer.h b/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2TrackClusterer.h
index 130345b740f80eee9b954a55e81b2f1588248d2c..d58500686d0e74d10e32c3ff6e5c2ecc04fe8235 100644
--- a/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2TrackClusterer.h
+++ b/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2TrackClusterer.h
@@ -33,6 +33,8 @@
 #include <vector>
 #include <cmath>
 
+namespace InDet { class BeamSpotData; }
+
 namespace PESA
 {
 
@@ -40,14 +42,28 @@ namespace PESA
   {
   public:
 
+    // option for calculating track perigee parameters
+    enum TrackPerigee {
+      perigee_original,   // Use original track perigee parameters, usually means
+                          // perigee w.r.t. coordinate system origin x,y=0,0
+      perigee_beamspot,   // Perigee to a beamspot position, ignoring tilt
+      perigee_beamline,   // Perigee to a beam line, including tilt
+    };
+
+    // convert string to above enum value
+    static TrackPerigee trackPerigeeFromString(const std::string& perigeeStr);
+
     // Constructor
-    T2TrackClusterer( double deltaZ = 10.*Gaudi::Units::mm, double minPT = 1.*Gaudi::Units::GeV, bool weightedZ = true, unsigned maxSize = 10000. )
+    // clusterPerigee is one of '0'=origin, 's'=beamspot, 'l'=beamline
+    T2TrackClusterer( double deltaZ = 10.*Gaudi::Units::mm, double minPT = 1.*Gaudi::Units::GeV, bool weightedZ = true, unsigned maxSize = 10000.,
+                      TrackPerigee trackPerigee = perigee_original)
       : m_deltaZ    ( deltaZ    )
       , m_minPT     ( minPT     )
       , m_weightedZ ( weightedZ )
       , m_maxSize   ( maxSize   )
       , m_seedZ0    ( 0. )
       , m_totalZ0Err( 0. )
+      , m_trackPerigee( trackPerigee )
       {}
 
     // Accessors
@@ -60,9 +76,13 @@ namespace PESA
     // Methods
     double trackWeight( const Trk::Track& track ) const;
 
-    const TrackCollection& cluster( const TrackCollection& tracks );
+    const TrackCollection& cluster( const TrackCollection& tracks, const InDet::BeamSpotData* beamspot = nullptr );
 
   private:
+
+    // return perigee z0 for a track
+    double trackPerigeeZ0(const Trk::Track& track, const InDet::BeamSpotData* beamspot) const;
+
     // Data members
     const double   m_deltaZ;
     const double   m_minPT;
@@ -72,6 +92,8 @@ namespace PESA
     double m_seedZ0;
     double m_totalZ0Err;
 
+    const TrackPerigee m_trackPerigee = perigee_original;
+
     ConstDataVector<TrackCollection> m_cluster;
     ConstDataVector<TrackCollection> m_unusedTracks;
   };
diff --git a/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2VertexBeamSpotTool.cxx b/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2VertexBeamSpotTool.cxx
index e9b9fa304a8c677f4b874a59fca6e81ad607591e..c6a813924cc662bc4c94c081bb7cbba3af3f2bad 100644
--- a/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2VertexBeamSpotTool.cxx
+++ b/Trigger/TrigAlgorithms/TrigT2BeamSpot/src/T2VertexBeamSpotTool.cxx
@@ -14,7 +14,6 @@
 //============================================================
 // This algorithm
 #include "TrigT2BeamSpot/T2VertexBeamSpotTool.h"
-#include "T2TrackClusterer.h"
 #include "T2TrackManager.h"
 #include "T2Timer.h"
 // Specific to this algorithm
@@ -85,6 +84,7 @@ PESA::T2VertexBeamSpotTool::T2VertexBeamSpotTool( const std::string& type, const
    declareProperty("WeightClusterZ",    m_weightSeed        = true     ); 
    declareProperty("ReclusterSplit",    m_reclusterSplit    = true     ); 
    declareProperty("SplitWholeCluster", m_splitWholeCluster = false    ); 
+   declareProperty("ClusterPerigee",    m_clusterPerigee    = "beamspot" );
 
    // Track Selection criteria 
    declareProperty("TrackMinPt",      m_minTrackPt       =  0.7*GeV ); 
@@ -125,9 +125,6 @@ PESA::T2VertexBeamSpotTool::T2VertexBeamSpotTool( const std::string& type, const
    // Single interaction trigger
    declareProperty("minNpvTrigger",  m_minNpvTrigger  = 0);
    declareProperty("maxNpvTrigger",  m_maxNpvTrigger  = 2);
-
-
- 
 }
 
 
@@ -145,6 +142,8 @@ StatusCode T2VertexBeamSpotTool::initialize(){
    //Retrieve primary vertex fitter tool
    ATH_CHECK( m_primaryVertexFitterTool.retrieve() );
 
+   m_clusterTrackPerigee = T2TrackClusterer::trackPerigeeFromString(m_clusterPerigee);
+
    return StatusCode::SUCCESS;
 }
 
@@ -253,9 +252,18 @@ unsigned int T2VertexBeamSpotTool::reconstructVertices( ConstDataVector<TrackCol
      auto mon = Monitored::Group(m_monTool,  timeToSortTracks ); 
   }
 
+  // Extract beam spot parameters
+  SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey, ctx };
+  const InDet::BeamSpotData* indetBeamSpot(*beamSpotHandle);
+  const T2BeamSpot beamSpot(indetBeamSpot);
+   ATH_MSG_DEBUG( "Beamspot from BeamCondSvc: " << beamSpot);
+
   // Prepare a track clustering algorithm with the given parameters
   // Should we leave this as a standalone class or merge with the tool?
-   T2TrackClusterer trackClusterer( m_trackClusDZ, m_trackSeedPt, m_weightSeed, m_vtxNTrkMax );
+   T2TrackClusterer trackClusterer( m_trackClusDZ, m_trackSeedPt, m_weightSeed, m_vtxNTrkMax,
+                                    m_clusterTrackPerigee );
+
+   std::vector<double> clusterZ0; // Z0 for each cluster, for monitoring only
 
   // Create clusters from the track collection until all its tracks are used
    while ( ! mySelectedTrackCollection.empty() ) {
@@ -270,7 +278,7 @@ unsigned int T2VertexBeamSpotTool::reconstructVertices( ConstDataVector<TrackCol
       // as the seed.
       {
          auto timeToZCluster = Monitored::Timer("TIME_toZCluster");
-         trackClusterer.cluster( *mySelectedTrackCollection.asDataVector() );
+         trackClusterer.cluster( *mySelectedTrackCollection.asDataVector(), indetBeamSpot );
          auto mon = Monitored::Group(m_monTool,  timeToZCluster ); 
       }
 
@@ -330,13 +338,6 @@ unsigned int T2VertexBeamSpotTool::reconstructVertices( ConstDataVector<TrackCol
       // Update vertex counter
       nVtx++;
 
-      // Extract beam spot parameters
-      SG::ReadCondHandle<InDet::BeamSpotData> beamSpotHandle { m_beamSpotKey, ctx };
-
-      T2BeamSpot beamSpot(*beamSpotHandle);
-
-      ATH_MSG_DEBUG( "Beamspot from BeamCondSvc: " << beamSpot);
-
       const T2Vertex myVertex( *primaryVertex, vertexTracks, beamSpot, trackClusterer.seedZ0() );
 
       // Monitor all vertices parameters
@@ -364,6 +365,13 @@ unsigned int T2VertexBeamSpotTool::reconstructVertices( ConstDataVector<TrackCol
       auto deltaVtxZ  = Monitored::Scalar<double>   ( "ClusterDeltaVertexZ",  trackClusterer.seedZ0() - myVertex.Z() );
       auto mon = Monitored::Group(m_monTool,  deltaVtxZ ); 
 
+      // monitor cluster-cluster delta Z0
+      for (double prevClusterZ0: clusterZ0) {
+         auto clusterClusterDeltaZ  = Monitored::Scalar<double>("ClusterClusterDeltaZ0",  trackClusterer.seedZ0() - prevClusterZ0);
+         auto mon = Monitored::Group(m_monTool,  clusterClusterDeltaZ);
+      }
+      clusterZ0.push_back(trackClusterer.seedZ0());
+
       // If the vertex is good, splits are requested, and we have enough tracks to split, split them!
       if ( passVertex && m_nSplitVertices > 1 ) {