diff --git a/Rich/RichFutureAlgorithms/src/RichSmartIDClustering.cpp b/Rich/RichFutureAlgorithms/src/RichSmartIDClustering.cpp
index 901a3a170288fe0fe6d928eac463e1f4f1cd15ab..67f64217cd1b18e4c54a8c8ba8a4e4ec52ca30a6 100644
--- a/Rich/RichFutureAlgorithms/src/RichSmartIDClustering.cpp
+++ b/Rich/RichFutureAlgorithms/src/RichSmartIDClustering.cpp
@@ -87,10 +87,13 @@ SmartIDClustering::operator()( const Rich::Future::DAQ::L1Map& data ) const
 
   // Sort PD data pointer vector by region. 
   // Faster than sorting final cluster container
+  //std::sort( pdDataV.begin(), pdDataV.end(),
+  //           []( const auto a, const auto b )
+  //           { return ( a->pdID().dataBitsOnly().key() < 
+  //                      b->pdID().dataBitsOnly().key() ); } );
   std::sort( pdDataV.begin(), pdDataV.end(),
              []( const auto a, const auto b )
-             { return ( a->pdID().dataBitsOnly().key() < 
-                        b->pdID().dataBitsOnly().key() ); } );
+             { return ( a->pdID().key() < b->pdID().key() ); } );
   
   // Loop over the PD vector and cluster
   for ( const auto PD : pdDataV )
diff --git a/Rich/RichFutureTools/src/RichSmartIDTool.cpp b/Rich/RichFutureTools/src/RichSmartIDTool.cpp
index 5d4e56eb926f33cac667b46f8b6bb933e44972c4..6e2483783a63303f2ea295b4c4f11d6825df86cb 100755
--- a/Rich/RichFutureTools/src/RichSmartIDTool.cpp
+++ b/Rich/RichFutureTools/src/RichSmartIDTool.cpp
@@ -58,6 +58,95 @@ StatusCode SmartIDTool::initialize()
   return sc;
 }
 
+//=============================================================================
+// Finds the average positions of a vector of clusters, in global LHCb 
+// coordinates on the PD entrance window
+//=============================================================================
+LHCb::STL::Vector<Gaudi::XYZPoint> 
+SmartIDTool::globalPositions( const Rich::PDPixelCluster::Vector& clusters,
+                              const bool ignoreClusters ) const 
+{
+  // allocate the vector
+  LHCb::STL::Vector<Gaudi::XYZPoint> points;
+  points.reserve( clusters.size() );
+
+  // Do we need to take the full cluster info into account
+  if ( UNLIKELY( !ignoreClusters ) )
+  {
+    // scalar loop using full cluster info
+    for ( const auto & clus : clusters )
+    {
+      points.emplace_back();
+      const auto ok = globalPosition( clus, points.back() );
+      if ( msgLevel(MSG::DEBUG) )
+      {
+        if ( UNLIKELY(!ok) )
+        { _ri_debug << "Failed to compute global position for " << clus << endmsg; }
+        else
+        { _ri_debug << clus.primaryID() << " " << points.back() << endmsg; }
+      }
+    }
+  }
+  else
+  {
+    // Speed things up using only the primary IDs and SIMD methods...
+
+    // scalar FP type for SIMD objects
+    using FP         = Rich::SIMD::DefaultScalarFP;
+    // SIMD float type
+    using SIMDFP     = Rich::SIMD::FP<FP>; 
+    // SIMD Point
+    using SIMDPoint  = Rich::SIMD::Point<FP>;
+    // Type for SmartIDs container.
+    using SmartIDs   = Rich::SIMD::STDArray<LHCb::RichSmartID>;
+
+    // working SIMD objects
+    SmartIDs ids;
+    SIMDPoint point;
+    // SIMD index
+    std::size_t index = 0;
+    // Last PD pointer
+    const DeRichPD * lastPD{nullptr};
+
+    // Save functor
+    auto saveInfo = [&]()
+      {
+        // Compute SIMD position
+        lastPD->detectionPoint( ids, point, m_hitPhotoCathSide );
+        // save scalar info to container
+        for ( std::size_t i = 0; i < index; ++i )
+        {
+          points.emplace_back( point.X()[i], point.Y()[i], point.Z()[i] ); 
+        }
+        // reset SIMD index
+        index  = 0;
+        lastPD = nullptr;
+      };
+
+    // loop over the cluster info
+    for ( const auto & clus : clusters )
+    {
+      // If new PD, or SIMD data is full, save and reset.
+      if ( lastPD && ( lastPD != clus.dePD() || index >= SIMDFP::Size ) ) { saveInfo(); }
+      // Fill info
+      lastPD     = clus.dePD();
+      ids[index] = clus.primaryID();
+      // increment index for next time
+      ++index;
+    }
+
+    // Save the last one
+    if ( lastPD && index > 0 ) { saveInfo(); }
+    
+  }
+
+  // debug sanity check
+  assert( points.size() == clusters.size() );
+
+  // return
+  return points;
+}
+
 //=============================================================================
 // Returns the position of a RichSmartID cluster in global coordinates
 // on the PD entrance window
@@ -210,6 +299,17 @@ SmartIDTool::globalToPDPanel ( const Gaudi::XYZPoint& globalPoint ) const
         panel(Rich::Rich2,Rich::right) ->globalToPDPanelMatrix()*globalPoint ) );
 }
 
+//=============================================================================
+// Converts a SIMD position in global coordinates to the local coordinate system
+//=============================================================================
+SmartIDTool::SIMDPoint
+SmartIDTool::globalToPDPanel ( const Rich::DetectorType rich,
+                               const Rich::Side side,
+                               const SIMDPoint& globalPoint ) const
+{
+  return panel(rich,side) -> globalToPDPanelMatrixSIMD() * globalPoint; 
+}
+
 //=============================================================================
 // Converts a SIMD position in global coordinates to the local coordinate system
 //=============================================================================
diff --git a/Rich/RichFutureTools/src/RichSmartIDTool.h b/Rich/RichFutureTools/src/RichSmartIDTool.h
index 1e47637b0b1455ab31efb12ae43a218f67a0d985..ce3b8c3a3dd21f24476190537a431dc57c3bea27 100755
--- a/Rich/RichFutureTools/src/RichSmartIDTool.h
+++ b/Rich/RichFutureTools/src/RichSmartIDTool.h
@@ -15,6 +15,7 @@
 // STL
 #include <vector>
 #include <array>
+#include <cassert>
 
 // Base class
 #include "RichFutureKernel/RichToolBase.h"
@@ -76,6 +77,11 @@ namespace Rich
       // Finds the average position of a cluster of RichSmartIDs, in global LHCb coordinates
       virtual bool globalPosition( const Rich::PDPixelCluster& cluster,
                                    Gaudi::XYZPoint& detectPoint ) const override;
+      
+      // Finds the average positions of a vector of clusters, in global LHCb coordinates
+      virtual LHCb::STL::Vector<Gaudi::XYZPoint> 
+      globalPositions( const Rich::PDPixelCluster::Vector& clusters,
+                       const bool ignoreClusters = false ) const override;
 
       // Converts an PD RichSmartID identification into a position in global LHCb coordinates.
       virtual bool pdPosition( const LHCb::RichSmartID& pdid,
@@ -100,6 +106,11 @@ namespace Rich
       virtual SIMDPoint globalToPDPanel ( const Rich::DetectorType rich,
                                           const SIMDPoint& globalPoint ) const override;
 
+      // Converts a SIMD position in global coordinates to the local coordinate system
+      virtual SIMDPoint globalToPDPanel ( const Rich::DetectorType rich,
+                                          const Rich::Side side,
+                                          const SIMDPoint& globalPoint ) const override;
+
     private:
 
       /// photodetector panels per rich