From 6cd9bed62670c4c26ba9d7c6a56604fb05d4b692 Mon Sep 17 00:00:00 2001
From: nmchugh <niall.thomas.mchugh@cern.ch>
Date: Thu, 13 Mar 2025 00:32:44 +0000
Subject: [PATCH 1/2] add initial version of pv splitting

---
 Rec/RecAlgs/CMakeLists.txt             |   1 +
 Rec/RecAlgs/src/LumiPVs_nobeamline.cpp | 112 ++++++++-----
 Rec/RecAlgs/src/PVSplitter.cpp         | 222 +++++++++++++++++++++++++
 3 files changed, 295 insertions(+), 40 deletions(-)
 create mode 100644 Rec/RecAlgs/src/PVSplitter.cpp

diff --git a/Rec/RecAlgs/CMakeLists.txt b/Rec/RecAlgs/CMakeLists.txt
index 93fdeb5ec75..e1582852bac 100644
--- a/Rec/RecAlgs/CMakeLists.txt
+++ b/Rec/RecAlgs/CMakeLists.txt
@@ -21,6 +21,7 @@ gaudi_add_module(RecAlgs
         src/UniqueIDGeneratorAlg.cpp
         src/LumiSummaryTuple.cpp
         src/LumiPVs_nobeamline.cpp
+        src/PVSplitter.cpp
     LINK
         AIDA::aida
         Boost::headers
diff --git a/Rec/RecAlgs/src/LumiPVs_nobeamline.cpp b/Rec/RecAlgs/src/LumiPVs_nobeamline.cpp
index 3235b435a54..f1c3367de7b 100644
--- a/Rec/RecAlgs/src/LumiPVs_nobeamline.cpp
+++ b/Rec/RecAlgs/src/LumiPVs_nobeamline.cpp
@@ -21,64 +21,96 @@
 #include "DetDesc/DetectorElement.h"
 #include "TrackInterfaces/IPVOfflineTool.h"
 
-using InputVeloTracks = LHCb::Event::v1::Tracks;
+using InputPVs        = LHCb::RecVertices;
 using InputHlt        = LHCb::HltDecReports;
 using RecPV           = LHCb::RecVertex;
+
+namespace {
+  int count_backwards_tracks( RecPV* pv ) {
+    int nbw = 0;
+    for ( auto tr: pv->tracks()) {
+      if( tr->isVeloBackward() ) nbw++;
+    }
+    return nbw;
+  }
+
+  // convert from LHCb::RecVertices -> std::vector<LHCb::RecVertex*>
+  void convert ( const InputPVs& oldvec, std::vector<RecPV*>& newvec ) {
+    std::copy( oldvec.begin(), oldvec.end(), std::back_inserter( newvec ) );
+  }
+}
+
 class LumiPVs_nobeamline
     : public virtual LHCb::Algorithm::Consumer<
-          void( const LHCb::ODIN&, const InputVeloTracks&, const InputHlt&, const DetectorElement& ),
-          LHCb::Algorithm::Traits::usesBaseAndConditions<GaudiTupleAlg, DetectorElement>> {
+          void( const LHCb::ODIN&, const InputPVs&, const InputPVs&, const InputPVs&, const InputHlt& ),
+          LHCb::Algorithm::Traits::usesBaseAndConditions<GaudiTupleAlg>> {
+
 private:
-  Gaudi::Property<std::string> m_tupleName{ this, "BeamGasTuple", "BeamGasTuple" };
-  ToolHandle<IPVOfflineTool>   m_toolpv{ this, "PVOfflineTool", "PVOfflineTool" };
-  LHCb::RecVertices            reconstructMultiPVFromTracks( std::vector<const LHCb::Event::v1::Track*>& tracks2use,
-                                                             Gaudi::XYZPoint const&                      beamSpot ) const;
+  Gaudi::Property<std::string> m_tupleName{this, "BeamGasTuple", "BeamGasTuple"};
 
 public:
-  virtual void operator()( const LHCb::ODIN&, const InputVeloTracks&, const InputHlt&,
-                           const DetectorElement& ) const override;
+  virtual void operator()( const LHCb::ODIN&, const InputPVs&, const InputPVs&, const InputPVs&, const InputHlt& ) const override;
   LumiPVs_nobeamline( const std::string& name, ISvcLocator* pSvcLocator );
 };
 
 DECLARE_COMPONENT_WITH_ID( LumiPVs_nobeamline, "LumiPVs_nobeamline" );
 LumiPVs_nobeamline::LumiPVs_nobeamline( const std::string& name, ISvcLocator* pSvcLocator )
     : Consumer( name, pSvcLocator,
-                { KeyValue{ "ODIN", "" }, KeyValue{ "InputVeloTracks", "" }, KeyValue{ "InputHlt", "" },
-                  KeyValue{ "StandardGeometryTop", LHCb::standard_geometry_top } } ) {}
-
-void LumiPVs_nobeamline::operator()( const LHCb::ODIN& odin, const InputVeloTracks& tracks, const InputHlt& decreport,
-                                     const DetectorElement& lhcb ) const {
+                {KeyValue{"ODIN", ""},
+                 KeyValue{"InputPVs", ""},
+                 KeyValue{"InputSplitPVs1", ""},
+                 KeyValue{"InputSplitPVs2", ""},
+                 KeyValue{"InputHlt", ""}} ) {}
 
+void LumiPVs_nobeamline::operator()( const LHCb::ODIN& odin, const InputPVs& _pvs, const InputPVs& _split1,
+                                     const InputPVs& _split2, const InputHlt& decreport ) const {
   auto tuple = nTuple( m_tupleName );
 
-  std::vector<const LHCb::Track*> selectedtracks;
-  std::vector<RecPV>              vtxlist;
-  std::copy_if( tracks.begin(), tracks.end(), std::back_inserter( selectedtracks ),
-                []( const LHCb::Track* tr ) { return tr->hasVelo(); } );
+  // convert to vectors, as I can't find a way to simultaneously iterate over KeyedContainers
+  std::vector<RecPV*> pvs, split1, split2;
+  convert( _pvs, pvs );
+  convert( _split1, split1 );
+  convert( _split2, split2 );
+
+  StatusCode sc;
+  std::string suffix;
+  RecPV* pv;
+  for ( int i = 0; i < static_cast<int>( pvs.size() ); i++ ) {
+    sc = tuple->column( "runNumber", odin.runNumber() );
+    sc &= tuple->column( "gpsTime", static_cast<unsigned long long>( odin.gpsTime() ) );
+    sc &= tuple->column( "eventNumber", static_cast<unsigned long long>( odin.eventNumber() ) );
+    sc &= tuple->column( "eventType", odin.eventType() );
+    sc &= tuple->column( "triggerType", odin.triggerType() );
+    sc &= tuple->column( "orbitNumber", odin.orbitNumber() );
+    sc &= tuple->column( "bxType", static_cast<std::uint16_t>( odin.bunchCrossingType() ) );
+    sc &= tuple->column( "bxId", odin.bunchId() );
+    sc &= tuple->column( "step", odin.calibrationStep() );
+    for ( const auto& kvp : decreport ) { sc &= tuple->column( kvp.first, kvp.second.decision() ); }
 
-  m_toolpv->reconstructMultiPVFromTracks( selectedtracks, vtxlist, *lhcb.geometry() ).ignore();
+    for ( int j = 0; j < 3; j++) {
+      if ( j == 0 ) {
+        suffix = "";
+        pv = pvs.at(i);
+      } else if ( j == 1 ) {
+        suffix = "_1";
+        pv = split1.at(i);
+      } else {
+        suffix = "_2";
+        pv = split2.at(i);
+      }
 
-  auto sc = tuple->column( "runNumber", odin.runNumber() );
-  sc      = tuple->column( "gpsTime", static_cast<unsigned long long>( odin.gpsTime() ) );
-  sc      = tuple->column( "eventNumber", static_cast<unsigned long long>( odin.eventNumber() ) );
-  sc      = tuple->column( "eventType", odin.eventType() );
-  sc      = tuple->column( "triggerType", odin.triggerType() );
-  sc      = tuple->column( "orbitNumber", odin.orbitNumber() );
-  sc      = tuple->column( "bxType", static_cast<std::uint16_t>( odin.bunchCrossingType() ) );
-  sc      = tuple->column( "bxId", odin.bunchId() );
-  sc      = tuple->column( "step", odin.calibrationStep() );
-  sc      = tuple->column( "nVeloTracks", static_cast<unsigned long long>( tracks.size() ) );
-  for ( const auto& kvp : decreport ) { sc = tuple->column( kvp.first, kvp.second.decision() ); }
+      sc &= tuple->column( "PV_ntracks"+suffix, static_cast<unsigned long long>( pv->tracks().size() ) );
+      sc &= tuple->column( "PV_ntracksbw"+suffix, count_backwards_tracks( pv ) );
+      sc &= tuple->column( "PV_chi2"+suffix, pv->chi2() );
+      sc &= tuple->column( "PV_ndof"+suffix, pv->nDoF() );
+      sc &= tuple->column( "PVX"+suffix, pv->position().x() );
+      sc &= tuple->column( "PVY"+suffix, pv->position().y() );
+      sc &= tuple->column( "PVZ"+suffix, pv->position().z() );
+    }
 
-  sc = tuple->farray(
-      { { "PV_nTracks", +[]( const RecPV& pv ) -> double { return pv.tracks().size(); } },
-        { "PV_chi2ndof", +[]( const RecPV& pv ) { return pv.chi2() / pv.nDoF(); } },
-        { "PVX", +[]( const RecPV& pv ) { return pv.position().x(); } },
-        { "PVY", +[]( const RecPV& pv ) { return pv.position().y(); } },
-        { "PVZ", +[]( const RecPV& pv ) { return pv.position().z(); } },
-        { "PVR",
-          +[]( const RecPV& pv ) { return sqrt( pow( pv.position().x(), 2 ) + pow( pv.position().y(), 2 ) ); } } },
-      vtxlist.begin(), vtxlist.end(), "nPVs", 1000 );
+    if ( sc.isFailure() ) continue;
 
-  sc.andThen( [&] { return tuple->write(); } ).orThrow( "Failed to fill ntuple", "LumiPV_nobeamline Alg" );
+    sc = tuple->write();
+    if ( sc.isFailure() ) throw GaudiException( "Cannot fill ntuple", "LumiPVs_nobeamline", StatusCode::FAILURE );
+  }
 }
diff --git a/Rec/RecAlgs/src/PVSplitter.cpp b/Rec/RecAlgs/src/PVSplitter.cpp
new file mode 100644
index 00000000000..d3e47be6350
--- /dev/null
+++ b/Rec/RecAlgs/src/PVSplitter.cpp
@@ -0,0 +1,222 @@
+/*****************************************************************************\
+* (c) Copyright 2000-2018 CERN for the benefit of the LHCb Collaboration      *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+#include "Event/RecVertex.h"
+#include "Event/Track.h"
+#include "LHCbAlgs/Transformer.h"
+#include "TrackInterfaces/IPVOfflineTool.h"
+#include "Kernel/HitPattern.h"
+#include "Detector/LHCb/DeLHCb.h"
+#include "DetDesc/DetectorElement.h"
+
+#include <random>
+#include <cmath>
+
+using Track     = LHCb::Track;
+using TrackVec  = std::vector<const LHCb::Track*>;
+using Tracks    = LHCb::Tracks;
+using RecPV     = LHCb::RecVertex;
+using RecPVs    = LHCb::RecVertices;
+using OutputPVs = std::tuple<RecPVs, RecPVs, RecPVs>;
+
+namespace {
+  using base_t = LHCb::Algorithm::MultiTransformer< OutputPVs( const Tracks&, LHCb::Detector::DeLHCb const& ),
+                                               LHCb::Algorithm::Traits::usesConditions<LHCb::Detector::DeLHCb> >;
+
+  int random_offset( const Track* track ) {
+    // bit hacky but this should be randomish, right ...?
+    const int rnd = static_cast<int>( track->lhcbIDs()[0].lhcbID() );
+    return rnd % 2;
+  }
+
+  bool is_left_track( const Track* tr ) {
+    LHCb::HitPattern hits{tr->lhcbIDs()};
+    if ( hits.numVeloA() == hits.numVeloC() ) {
+      // pseudo-randomly allocate "mixed" tracks
+      return static_cast<bool>( random_offset( tr ) );
+    }
+    return hits.numVeloA() > hits.numVeloC();
+  }
+
+  bool is_top_track( const Track* tr ) {
+    // the old version checked for sin(phi) > 0 of each VELO sensor/hit -
+    // make sure this naive port does the same thing...
+    return ( std::sin( tr->phi() ) > 0 );
+  }
+
+  TrackVec unpack_tracks( const RecPV* pv, const bool shuffle ) {
+    const SmartRefVector<Track>& _tracks = pv->tracks();
+    TrackVec tracks;
+    for ( auto tr: _tracks ) {
+      tracks.push_back( tr );
+    }
+
+    if ( shuffle ) {
+      const int seed = static_cast<int>( tracks[0]->lhcbIDs()[0].lhcbID() );
+      std::mt19937 rng(seed);
+      std::shuffle(tracks.begin(), tracks.end(), rng);
+    }
+    return tracks;
+  }
+
+  void random_split_subsets( TrackVec& tracks1, TrackVec& tracks2, TrackVec* splittracks ) {
+    if ( tracks1.size() < 5 || tracks2.size() < 5 ) return;
+
+    // randomly divide two sets of tracks between two containers
+    int offset = random_offset( tracks1[0] );
+    for ( auto tr: tracks1 ) {
+      splittracks[offset % 2].push_back( tr );
+      offset++;
+    }
+    offset = random_offset( tracks2[0] );
+    for ( auto tr: tracks2 ) {
+      splittracks[offset % 2].push_back( tr );
+      offset++;
+    }
+  }
+}
+
+class PVSplitter : public base_t {
+
+public:
+  PVSplitter( const std::string& name, ISvcLocator* pSvcLocator )
+      : base_t ( name, pSvcLocator,
+                 { KeyValue{"InputVeloTracks", ""},
+                   KeyValue{"StandardGeometryTop", LHCb::standard_geometry_top} },
+                 { KeyValue{"OutputPVs", "Rec/Vertex/SplitPVs/PVs"}, 
+                   KeyValue{"OutputSplitPVs1", "Rec/Vertex/SplitPVs/SplitPVs1"}, 
+                   KeyValue{"OutputSplitPVs2", "Rec/Vertex/SplitPVs/SplitPVs2"} }) {}
+
+  OutputPVs operator()( const Tracks&, LHCb::Detector::DeLHCb const& ) const override;
+
+private:
+  ToolHandle<IPVOfflineTool> m_toolpv{this, "PVOfflineTool", "PVOfflineTool"};
+  Gaudi::Property<std::string> m_splitMethod{this, "SplitMethod", "random"};
+
+  StatusCode split_pv( const RecPV, RecPV*, LHCb::Detector::DeLHCb const& ) const;
+
+  typedef void ( PVSplitter::*SplitTracksFunc )( const TrackVec, TrackVec* ) const;
+  SplitTracksFunc m_splitFunc;
+  void splitTracksRandomly( const TrackVec, TrackVec* ) const;
+  void splitTracksByVeloHalf( const TrackVec, TrackVec* ) const;
+  void splitTracksEqualVeloHalf( const TrackVec, TrackVec* ) const;
+  void splitTracksByTopBottom( const TrackVec, TrackVec* ) const;
+  void splitTracksEqualTopBottom( const TrackVec, TrackVec* ) const;
+
+  StatusCode initialize() override;
+};
+
+DECLARE_COMPONENT( PVSplitter )
+
+StatusCode PVSplitter::initialize() {
+  return MultiTransformer::initialize().andThen( [&] {
+    if ( m_splitMethod == "random" )
+      m_splitFunc = &PVSplitter::splitTracksRandomly;
+    else if ( m_splitMethod == "byvelohalf" )
+      m_splitFunc = &PVSplitter::splitTracksByVeloHalf;
+    else if ( m_splitMethod == "equalvelohalf" )
+      m_splitFunc = &PVSplitter::splitTracksEqualVeloHalf;
+    else if ( m_splitMethod == "bytopbottom" )
+      m_splitFunc = &PVSplitter::splitTracksByTopBottom;
+    else if ( m_splitMethod == "equaltopbottom" )
+      m_splitFunc = &PVSplitter::splitTracksEqualTopBottom;
+    else
+      throw GaudiException( "Unrecognised splitting algorithm", "PVSplitter", StatusCode::FAILURE );
+  } );
+}
+
+OutputPVs PVSplitter::operator()( const Tracks& _tracks, LHCb::Detector::DeLHCb const& lhcb ) const {
+  std::vector<RecPV> pvs;
+  std::vector<const Track*> tracks;
+  std::copy( _tracks.begin(), _tracks.end(), std::back_inserter( tracks ) );
+  m_toolpv->reconstructMultiPVFromTracks( tracks, pvs, *lhcb.geometry() ).ignore();
+
+  RecPVs retpvs;
+  RecPVs splitpvs1;
+  RecPVs splitpvs2;
+  StatusCode sc;
+  for ( auto pv: pvs ) {
+    // require 5 tracks / split pv => 10 total
+    if (pv.tracks().size() < 10) continue;
+
+    RecPV splitpvs[2];
+    sc = split_pv( pv, splitpvs, lhcb );
+    if ( sc.isFailure() ) continue;
+
+    retpvs.insert( new RecPV{pv} );
+    splitpvs1.insert( new RecPV{splitpvs[0]} );
+    splitpvs2.insert( new RecPV{splitpvs[1]} );
+  }
+
+  return OutputPVs{ std::move( retpvs ), std::move( splitpvs1 ), std::move( splitpvs2 ) };
+}
+
+StatusCode PVSplitter::split_pv( const RecPV pv, RecPV* splitpvs, LHCb::Detector::DeLHCb const& lhcb ) const {
+  TrackVec splittracks[2];
+  TrackVec tracks = unpack_tracks( &pv, true );
+  ( this->*m_splitFunc )( tracks, splittracks );
+
+  StatusCode sc;
+  for ( int i = 0; i < 2; i++ ){
+    sc = m_toolpv->reconstructSinglePVFromTracks( pv.position(), splittracks[i], splitpvs[i], *lhcb.geometry() );
+    if ( sc.isFailure() ) return sc;
+  }
+  return sc;
+}
+
+void PVSplitter::splitTracksRandomly( const TrackVec tracks, TrackVec* splittracks ) const {
+  // randomly 0 or 1, to avoid first split pv always having >= ntracks in second split pv
+  int offset = random_offset( tracks[0] );
+  for ( auto tr: tracks ) {
+    splittracks[offset % 2].push_back( tr );
+    offset++;
+  }
+}
+
+void PVSplitter::splitTracksByVeloHalf( const TrackVec tracks, TrackVec* splittracks ) const {
+  for (auto tr: tracks ) {
+    if ( is_left_track( tr ) )
+      splittracks[0].push_back( tr );
+    else
+      splittracks[1].push_back( tr );
+  }
+}
+
+void PVSplitter::splitTracksEqualVeloHalf( const TrackVec tracks, TrackVec* splittracks ) const {
+  TrackVec left, right;
+  for( auto tr: tracks ) {
+    if ( is_left_track( tr ) )
+      left.push_back( tr );
+    else
+      right.push_back( tr );
+  }
+  random_split_subsets( left, right, splittracks );
+}
+
+void PVSplitter::splitTracksByTopBottom( const TrackVec tracks, TrackVec* splittracks ) const {
+  for (auto tr: tracks ) {
+    if ( is_top_track( tr ) )
+      splittracks[0].push_back( tr );
+    else
+      splittracks[1].push_back( tr );
+  }
+}
+
+void PVSplitter::splitTracksEqualTopBottom( const TrackVec tracks, TrackVec* splittracks ) const {
+    TrackVec top, bottom;
+    for( auto tr: tracks ) {
+      if ( is_top_track( tr ) )
+        top.push_back( tr );
+      else
+        bottom.push_back( tr );
+    }
+  random_split_subsets( top, bottom, splittracks );
+}
+
-- 
GitLab


From b79072c7ae319067ef379edc5d555f0dceb18733 Mon Sep 17 00:00:00 2001
From: Gitlab CI <noreply@cern.ch>
Date: Thu, 13 Mar 2025 00:33:43 +0000
Subject: [PATCH 2/2] pre-commit fixes

patch generated by https://gitlab.cern.ch/lhcb/Rec/-/jobs/52659815
---
 Rec/RecAlgs/src/LumiPVs_nobeamline.cpp |  58 +++++++-------
 Rec/RecAlgs/src/PVSplitter.cpp         | 100 ++++++++++++-------------
 2 files changed, 76 insertions(+), 82 deletions(-)

diff --git a/Rec/RecAlgs/src/LumiPVs_nobeamline.cpp b/Rec/RecAlgs/src/LumiPVs_nobeamline.cpp
index f1c3367de7b..69decb073ee 100644
--- a/Rec/RecAlgs/src/LumiPVs_nobeamline.cpp
+++ b/Rec/RecAlgs/src/LumiPVs_nobeamline.cpp
@@ -21,46 +21,44 @@
 #include "DetDesc/DetectorElement.h"
 #include "TrackInterfaces/IPVOfflineTool.h"
 
-using InputPVs        = LHCb::RecVertices;
-using InputHlt        = LHCb::HltDecReports;
-using RecPV           = LHCb::RecVertex;
+using InputPVs = LHCb::RecVertices;
+using InputHlt = LHCb::HltDecReports;
+using RecPV    = LHCb::RecVertex;
 
 namespace {
   int count_backwards_tracks( RecPV* pv ) {
     int nbw = 0;
-    for ( auto tr: pv->tracks()) {
-      if( tr->isVeloBackward() ) nbw++;
+    for ( auto tr : pv->tracks() ) {
+      if ( tr->isVeloBackward() ) nbw++;
     }
     return nbw;
   }
 
   // convert from LHCb::RecVertices -> std::vector<LHCb::RecVertex*>
-  void convert ( const InputPVs& oldvec, std::vector<RecPV*>& newvec ) {
+  void convert( const InputPVs& oldvec, std::vector<RecPV*>& newvec ) {
     std::copy( oldvec.begin(), oldvec.end(), std::back_inserter( newvec ) );
   }
-}
+} // namespace
 
 class LumiPVs_nobeamline
-    : public virtual LHCb::Algorithm::Consumer<
-          void( const LHCb::ODIN&, const InputPVs&, const InputPVs&, const InputPVs&, const InputHlt& ),
-          LHCb::Algorithm::Traits::usesBaseAndConditions<GaudiTupleAlg>> {
+    : public virtual LHCb::Algorithm::Consumer<void( const LHCb::ODIN&, const InputPVs&, const InputPVs&,
+                                                     const InputPVs&, const InputHlt& ),
+                                               LHCb::Algorithm::Traits::usesBaseAndConditions<GaudiTupleAlg>> {
 
 private:
-  Gaudi::Property<std::string> m_tupleName{this, "BeamGasTuple", "BeamGasTuple"};
+  Gaudi::Property<std::string> m_tupleName{ this, "BeamGasTuple", "BeamGasTuple" };
 
 public:
-  virtual void operator()( const LHCb::ODIN&, const InputPVs&, const InputPVs&, const InputPVs&, const InputHlt& ) const override;
+  virtual void operator()( const LHCb::ODIN&, const InputPVs&, const InputPVs&, const InputPVs&,
+                           const InputHlt& ) const override;
   LumiPVs_nobeamline( const std::string& name, ISvcLocator* pSvcLocator );
 };
 
 DECLARE_COMPONENT_WITH_ID( LumiPVs_nobeamline, "LumiPVs_nobeamline" );
 LumiPVs_nobeamline::LumiPVs_nobeamline( const std::string& name, ISvcLocator* pSvcLocator )
     : Consumer( name, pSvcLocator,
-                {KeyValue{"ODIN", ""},
-                 KeyValue{"InputPVs", ""},
-                 KeyValue{"InputSplitPVs1", ""},
-                 KeyValue{"InputSplitPVs2", ""},
-                 KeyValue{"InputHlt", ""}} ) {}
+                { KeyValue{ "ODIN", "" }, KeyValue{ "InputPVs", "" }, KeyValue{ "InputSplitPVs1", "" },
+                  KeyValue{ "InputSplitPVs2", "" }, KeyValue{ "InputHlt", "" } } ) {}
 
 void LumiPVs_nobeamline::operator()( const LHCb::ODIN& odin, const InputPVs& _pvs, const InputPVs& _split1,
                                      const InputPVs& _split2, const InputHlt& decreport ) const {
@@ -72,9 +70,9 @@ void LumiPVs_nobeamline::operator()( const LHCb::ODIN& odin, const InputPVs& _pv
   convert( _split1, split1 );
   convert( _split2, split2 );
 
-  StatusCode sc;
+  StatusCode  sc;
   std::string suffix;
-  RecPV* pv;
+  RecPV*      pv;
   for ( int i = 0; i < static_cast<int>( pvs.size() ); i++ ) {
     sc = tuple->column( "runNumber", odin.runNumber() );
     sc &= tuple->column( "gpsTime", static_cast<unsigned long long>( odin.gpsTime() ) );
@@ -87,25 +85,25 @@ void LumiPVs_nobeamline::operator()( const LHCb::ODIN& odin, const InputPVs& _pv
     sc &= tuple->column( "step", odin.calibrationStep() );
     for ( const auto& kvp : decreport ) { sc &= tuple->column( kvp.first, kvp.second.decision() ); }
 
-    for ( int j = 0; j < 3; j++) {
+    for ( int j = 0; j < 3; j++ ) {
       if ( j == 0 ) {
         suffix = "";
-        pv = pvs.at(i);
+        pv     = pvs.at( i );
       } else if ( j == 1 ) {
         suffix = "_1";
-        pv = split1.at(i);
+        pv     = split1.at( i );
       } else {
         suffix = "_2";
-        pv = split2.at(i);
+        pv     = split2.at( i );
       }
 
-      sc &= tuple->column( "PV_ntracks"+suffix, static_cast<unsigned long long>( pv->tracks().size() ) );
-      sc &= tuple->column( "PV_ntracksbw"+suffix, count_backwards_tracks( pv ) );
-      sc &= tuple->column( "PV_chi2"+suffix, pv->chi2() );
-      sc &= tuple->column( "PV_ndof"+suffix, pv->nDoF() );
-      sc &= tuple->column( "PVX"+suffix, pv->position().x() );
-      sc &= tuple->column( "PVY"+suffix, pv->position().y() );
-      sc &= tuple->column( "PVZ"+suffix, pv->position().z() );
+      sc &= tuple->column( "PV_ntracks" + suffix, static_cast<unsigned long long>( pv->tracks().size() ) );
+      sc &= tuple->column( "PV_ntracksbw" + suffix, count_backwards_tracks( pv ) );
+      sc &= tuple->column( "PV_chi2" + suffix, pv->chi2() );
+      sc &= tuple->column( "PV_ndof" + suffix, pv->nDoF() );
+      sc &= tuple->column( "PVX" + suffix, pv->position().x() );
+      sc &= tuple->column( "PVY" + suffix, pv->position().y() );
+      sc &= tuple->column( "PVZ" + suffix, pv->position().z() );
     }
 
     if ( sc.isFailure() ) continue;
diff --git a/Rec/RecAlgs/src/PVSplitter.cpp b/Rec/RecAlgs/src/PVSplitter.cpp
index d3e47be6350..67305d0432d 100644
--- a/Rec/RecAlgs/src/PVSplitter.cpp
+++ b/Rec/RecAlgs/src/PVSplitter.cpp
@@ -8,16 +8,16 @@
 * granted to it by virtue of its status as an Intergovernmental Organization  *
 * or submit itself to any jurisdiction.                                       *
 \*****************************************************************************/
+#include "DetDesc/DetectorElement.h"
+#include "Detector/LHCb/DeLHCb.h"
 #include "Event/RecVertex.h"
 #include "Event/Track.h"
+#include "Kernel/HitPattern.h"
 #include "LHCbAlgs/Transformer.h"
 #include "TrackInterfaces/IPVOfflineTool.h"
-#include "Kernel/HitPattern.h"
-#include "Detector/LHCb/DeLHCb.h"
-#include "DetDesc/DetectorElement.h"
 
-#include <random>
 #include <cmath>
+#include <random>
 
 using Track     = LHCb::Track;
 using TrackVec  = std::vector<const LHCb::Track*>;
@@ -27,8 +27,8 @@ using RecPVs    = LHCb::RecVertices;
 using OutputPVs = std::tuple<RecPVs, RecPVs, RecPVs>;
 
 namespace {
-  using base_t = LHCb::Algorithm::MultiTransformer< OutputPVs( const Tracks&, LHCb::Detector::DeLHCb const& ),
-                                               LHCb::Algorithm::Traits::usesConditions<LHCb::Detector::DeLHCb> >;
+  using base_t = LHCb::Algorithm::MultiTransformer<OutputPVs( const Tracks&, LHCb::Detector::DeLHCb const& ),
+                                                   LHCb::Algorithm::Traits::usesConditions<LHCb::Detector::DeLHCb>>;
 
   int random_offset( const Track* track ) {
     // bit hacky but this should be randomish, right ...?
@@ -37,7 +37,7 @@ namespace {
   }
 
   bool is_left_track( const Track* tr ) {
-    LHCb::HitPattern hits{tr->lhcbIDs()};
+    LHCb::HitPattern hits{ tr->lhcbIDs() };
     if ( hits.numVeloA() == hits.numVeloC() ) {
       // pseudo-randomly allocate "mixed" tracks
       return static_cast<bool>( random_offset( tr ) );
@@ -53,15 +53,13 @@ namespace {
 
   TrackVec unpack_tracks( const RecPV* pv, const bool shuffle ) {
     const SmartRefVector<Track>& _tracks = pv->tracks();
-    TrackVec tracks;
-    for ( auto tr: _tracks ) {
-      tracks.push_back( tr );
-    }
+    TrackVec                     tracks;
+    for ( auto tr : _tracks ) { tracks.push_back( tr ); }
 
     if ( shuffle ) {
-      const int seed = static_cast<int>( tracks[0]->lhcbIDs()[0].lhcbID() );
-      std::mt19937 rng(seed);
-      std::shuffle(tracks.begin(), tracks.end(), rng);
+      const int    seed = static_cast<int>( tracks[0]->lhcbIDs()[0].lhcbID() );
+      std::mt19937 rng( seed );
+      std::shuffle( tracks.begin(), tracks.end(), rng );
     }
     return tracks;
   }
@@ -71,44 +69,43 @@ namespace {
 
     // randomly divide two sets of tracks between two containers
     int offset = random_offset( tracks1[0] );
-    for ( auto tr: tracks1 ) {
+    for ( auto tr : tracks1 ) {
       splittracks[offset % 2].push_back( tr );
       offset++;
     }
     offset = random_offset( tracks2[0] );
-    for ( auto tr: tracks2 ) {
+    for ( auto tr : tracks2 ) {
       splittracks[offset % 2].push_back( tr );
       offset++;
     }
   }
-}
+} // namespace
 
 class PVSplitter : public base_t {
 
 public:
   PVSplitter( const std::string& name, ISvcLocator* pSvcLocator )
-      : base_t ( name, pSvcLocator,
-                 { KeyValue{"InputVeloTracks", ""},
-                   KeyValue{"StandardGeometryTop", LHCb::standard_geometry_top} },
-                 { KeyValue{"OutputPVs", "Rec/Vertex/SplitPVs/PVs"}, 
-                   KeyValue{"OutputSplitPVs1", "Rec/Vertex/SplitPVs/SplitPVs1"}, 
-                   KeyValue{"OutputSplitPVs2", "Rec/Vertex/SplitPVs/SplitPVs2"} }) {}
+      : base_t( name, pSvcLocator,
+                { KeyValue{ "InputVeloTracks", "" }, KeyValue{ "StandardGeometryTop", LHCb::standard_geometry_top } },
+                { KeyValue{ "OutputPVs", "Rec/Vertex/SplitPVs/PVs" },
+                  KeyValue{ "OutputSplitPVs1", "Rec/Vertex/SplitPVs/SplitPVs1" },
+                  KeyValue{ "OutputSplitPVs2", "Rec/Vertex/SplitPVs/SplitPVs2" } } ) {}
 
   OutputPVs operator()( const Tracks&, LHCb::Detector::DeLHCb const& ) const override;
 
 private:
-  ToolHandle<IPVOfflineTool> m_toolpv{this, "PVOfflineTool", "PVOfflineTool"};
-  Gaudi::Property<std::string> m_splitMethod{this, "SplitMethod", "random"};
+  ToolHandle<IPVOfflineTool>   m_toolpv{ this, "PVOfflineTool", "PVOfflineTool" };
+  Gaudi::Property<std::string> m_splitMethod{ this, "SplitMethod", "random" };
 
   StatusCode split_pv( const RecPV, RecPV*, LHCb::Detector::DeLHCb const& ) const;
 
   typedef void ( PVSplitter::*SplitTracksFunc )( const TrackVec, TrackVec* ) const;
   SplitTracksFunc m_splitFunc;
-  void splitTracksRandomly( const TrackVec, TrackVec* ) const;
-  void splitTracksByVeloHalf( const TrackVec, TrackVec* ) const;
-  void splitTracksEqualVeloHalf( const TrackVec, TrackVec* ) const;
-  void splitTracksByTopBottom( const TrackVec, TrackVec* ) const;
-  void splitTracksEqualTopBottom( const TrackVec, TrackVec* ) const;
+  void            splitTracksRandomly( const TrackVec, TrackVec* ) const;
+  void            splitTracksByVeloHalf( const TrackVec, TrackVec* ) const;
+  void            splitTracksEqualVeloHalf( const TrackVec, TrackVec* ) const;
+  void            splitTracksByTopBottom( const TrackVec, TrackVec* ) const;
+  void            splitTracksEqualTopBottom( const TrackVec, TrackVec* ) const;
 
   StatusCode initialize() override;
 };
@@ -133,26 +130,26 @@ StatusCode PVSplitter::initialize() {
 }
 
 OutputPVs PVSplitter::operator()( const Tracks& _tracks, LHCb::Detector::DeLHCb const& lhcb ) const {
-  std::vector<RecPV> pvs;
+  std::vector<RecPV>        pvs;
   std::vector<const Track*> tracks;
   std::copy( _tracks.begin(), _tracks.end(), std::back_inserter( tracks ) );
   m_toolpv->reconstructMultiPVFromTracks( tracks, pvs, *lhcb.geometry() ).ignore();
 
-  RecPVs retpvs;
-  RecPVs splitpvs1;
-  RecPVs splitpvs2;
+  RecPVs     retpvs;
+  RecPVs     splitpvs1;
+  RecPVs     splitpvs2;
   StatusCode sc;
-  for ( auto pv: pvs ) {
+  for ( auto pv : pvs ) {
     // require 5 tracks / split pv => 10 total
-    if (pv.tracks().size() < 10) continue;
+    if ( pv.tracks().size() < 10 ) continue;
 
     RecPV splitpvs[2];
     sc = split_pv( pv, splitpvs, lhcb );
     if ( sc.isFailure() ) continue;
 
-    retpvs.insert( new RecPV{pv} );
-    splitpvs1.insert( new RecPV{splitpvs[0]} );
-    splitpvs2.insert( new RecPV{splitpvs[1]} );
+    retpvs.insert( new RecPV{ pv } );
+    splitpvs1.insert( new RecPV{ splitpvs[0] } );
+    splitpvs2.insert( new RecPV{ splitpvs[1] } );
   }
 
   return OutputPVs{ std::move( retpvs ), std::move( splitpvs1 ), std::move( splitpvs2 ) };
@@ -164,7 +161,7 @@ StatusCode PVSplitter::split_pv( const RecPV pv, RecPV* splitpvs, LHCb::Detector
   ( this->*m_splitFunc )( tracks, splittracks );
 
   StatusCode sc;
-  for ( int i = 0; i < 2; i++ ){
+  for ( int i = 0; i < 2; i++ ) {
     sc = m_toolpv->reconstructSinglePVFromTracks( pv.position(), splittracks[i], splitpvs[i], *lhcb.geometry() );
     if ( sc.isFailure() ) return sc;
   }
@@ -174,14 +171,14 @@ StatusCode PVSplitter::split_pv( const RecPV pv, RecPV* splitpvs, LHCb::Detector
 void PVSplitter::splitTracksRandomly( const TrackVec tracks, TrackVec* splittracks ) const {
   // randomly 0 or 1, to avoid first split pv always having >= ntracks in second split pv
   int offset = random_offset( tracks[0] );
-  for ( auto tr: tracks ) {
+  for ( auto tr : tracks ) {
     splittracks[offset % 2].push_back( tr );
     offset++;
   }
 }
 
 void PVSplitter::splitTracksByVeloHalf( const TrackVec tracks, TrackVec* splittracks ) const {
-  for (auto tr: tracks ) {
+  for ( auto tr : tracks ) {
     if ( is_left_track( tr ) )
       splittracks[0].push_back( tr );
     else
@@ -191,7 +188,7 @@ void PVSplitter::splitTracksByVeloHalf( const TrackVec tracks, TrackVec* splittr
 
 void PVSplitter::splitTracksEqualVeloHalf( const TrackVec tracks, TrackVec* splittracks ) const {
   TrackVec left, right;
-  for( auto tr: tracks ) {
+  for ( auto tr : tracks ) {
     if ( is_left_track( tr ) )
       left.push_back( tr );
     else
@@ -201,7 +198,7 @@ void PVSplitter::splitTracksEqualVeloHalf( const TrackVec tracks, TrackVec* spli
 }
 
 void PVSplitter::splitTracksByTopBottom( const TrackVec tracks, TrackVec* splittracks ) const {
-  for (auto tr: tracks ) {
+  for ( auto tr : tracks ) {
     if ( is_top_track( tr ) )
       splittracks[0].push_back( tr );
     else
@@ -210,13 +207,12 @@ void PVSplitter::splitTracksByTopBottom( const TrackVec tracks, TrackVec* splitt
 }
 
 void PVSplitter::splitTracksEqualTopBottom( const TrackVec tracks, TrackVec* splittracks ) const {
-    TrackVec top, bottom;
-    for( auto tr: tracks ) {
-      if ( is_top_track( tr ) )
-        top.push_back( tr );
-      else
-        bottom.push_back( tr );
-    }
+  TrackVec top, bottom;
+  for ( auto tr : tracks ) {
+    if ( is_top_track( tr ) )
+      top.push_back( tr );
+    else
+      bottom.push_back( tr );
+  }
   random_split_subsets( top, bottom, splittracks );
 }
-
-- 
GitLab