From 7c9e270273f00dbf95f1f91aedb1fb55b0b3e5eb Mon Sep 17 00:00:00 2001
From: gligorov <vladimir.gligorov@cern.ch>
Date: Fri, 21 Jun 2019 14:47:01 +0200
Subject: [PATCH 1/8] Get rid of PrForward in cuda, refactor the remaining
 useful components

---
 CMakeLists.txt                                |   3 +-
 checker/tracking/CMakeLists.txt               |   1 -
 cuda/SciFi/CMakeLists.txt                     |   9 +-
 cuda/SciFi/PrForward/.gitignore               |   1 -
 cuda/SciFi/PrForward/README.md                |   1 -
 .../PrForward/include/FindStereoHits.cuh      |  49 --
 cuda/SciFi/PrForward/include/FindXHits.cuh    | 120 ---
 cuda/SciFi/PrForward/include/HitUtils.cuh     | 220 -----
 .../SciFi/PrForward/include/LinearFitting.cuh |  77 --
 .../PrForward/include/ParabolaFitting.cuh     |  18 -
 cuda/SciFi/PrForward/include/PrForward.cuh    |  59 --
 .../PrForward/include/PrForwardConstants.cuh  | 236 -----
 .../PrForward/include/PrForwardTools.cuh      |  88 --
 .../include/ReferencePlaneProjection.cuh      |  27 -
 cuda/SciFi/PrForward/include/TrackUtils.cuh   |  74 --
 cuda/SciFi/PrForward/src/FindStereoHits.cu    | 247 ------
 cuda/SciFi/PrForward/src/FindXHits.cu         | 830 ------------------
 cuda/SciFi/PrForward/src/HitUtils.cu          | 324 -------
 cuda/SciFi/PrForward/src/LinearFitting.cu     | 179 ----
 cuda/SciFi/PrForward/src/ParabolaFitting.cu   |  59 --
 cuda/SciFi/PrForward/src/PrForward.cu         | 195 ----
 cuda/SciFi/PrForward/src/PrForwardTools.cu    | 398 ---------
 .../PrForward/src/ReferencePlaneProjection.cu |  40 -
 cuda/SciFi/PrForward/src/TrackUtils.cu        | 264 ------
 cuda/SciFi/classifiers/README.md              |   1 +
 .../include/TMVA_Forward.cuh                  |   2 -
 .../include/TMVA_Forward_1.cuh                |   0
 .../include/TMVA_Forward_2.cuh                |   0
 .../src/TMVA_Forward.cu                       |   0
 .../SciFi/common/include/SciFiDefinitions.cuh |  92 +-
 .../consolidate/include/ConsolidateSciFi.cuh  |   1 -
 .../include/LFCollectCandidates.cuh           |   1 -
 .../include/LFSearchInitialWindows.cuh        |   2 +-
 .../include/LFSearchInitialWindowsImpl.cuh    |   6 +-
 .../include/LFTripletKeepBest.cuh             |   1 -
 .../include/LFTripletSeeding.cuh              |   1 -
 .../triplet_seeding/src/LFTripletSeeding.cu   |   1 -
 cuda/SciFi/utils/README.md                    |   1 +
 cuda/SciFi/utils/include/HitUtils.cuh         |  28 +
 cuda/SciFi/utils/include/TrackUtils.cuh       |  35 +
 cuda/SciFi/utils/src/HitUtils.cu              |  17 +
 cuda/SciFi/utils/src/TrackUtils.cu            | 108 +++
 cuda/associate/CMakeLists.txt                 |   1 -
 cuda/global_event_cut/CMakeLists.txt          |   1 -
 cuda/kalman/CMakeLists.txt                    |   1 -
 cuda/muon/CMakeLists.txt                      |   1 -
 cuda/selections/CMakeLists.txt                |   1 -
 cuda/utils/CMakeLists.txt                     |   1 -
 cuda/vertex_fit/CMakeLists.txt                |   1 -
 integration/non_event_data/CMakeLists.txt     |   2 +-
 mdf/CMakeLists.txt                            |   1 -
 stream/CMakeLists.txt                         |   5 +-
 .../include/SciFiSequenceCheckers_impl.cuh    |   3 +-
 .../include/UTSequenceCheckers_impl.cuh       |   1 +
 .../include/VeloSequenceCheckers_impl.cuh     |   1 +
 stream/sequence/include/Constants.cuh         |   1 -
 stream/setup/include/ConfiguredSequence.cuh   |   2 -
 .../src/CpuSciFiMomentumForwardVisitor.cu     |   1 -
 .../SciFi/src/CpuSciFiPrForwardVisitor.cu     |  90 --
 .../SciFi/src/SciFiPrForwardVisitor.cu        |  48 -
 x86/SciFi/CMakeLists.txt                      |   1 -
 x86/SciFi/LookingForward/CMakeLists.txt       |   3 +-
 .../include/LookingForwardConstants.h         |   2 +-
 .../include/LookingForwardSbt.h               |   2 +-
 .../include/LookingForwardStudies.h           |   1 +
 .../include/LookingForwardUtils.h             |  17 +-
 .../src/LookingForwardStudies.cpp             |   2 -
 .../src/LookingForwardUtils.cpp               | 158 ++++
 x86/SciFi/MomentumForward/CMakeLists.txt      |   4 +-
 .../include/MomentumForwardConstants.h        |   2 +-
 x86/SciFi/PrForward/CMakeLists.txt            |  40 -
 .../PrForward/include/PrForwardWrapper.h      |  17 -
 x86/SciFi/PrForward/include/RunForwardCPU.h   |  47 -
 x86/SciFi/PrForward/src/PrForwardWrapper.cpp  |  39 -
 x86/SciFi/PrForward/src/RunForwardCPU.cpp     | 158 ----
 x86/global_event_cut/CMakeLists.txt           |   1 -
 76 files changed, 477 insertions(+), 3995 deletions(-)
 delete mode 100644 cuda/SciFi/PrForward/.gitignore
 delete mode 100644 cuda/SciFi/PrForward/README.md
 delete mode 100644 cuda/SciFi/PrForward/include/FindStereoHits.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/FindXHits.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/HitUtils.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/LinearFitting.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/ParabolaFitting.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/PrForward.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/PrForwardConstants.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/PrForwardTools.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/TrackUtils.cuh
 delete mode 100644 cuda/SciFi/PrForward/src/FindStereoHits.cu
 delete mode 100644 cuda/SciFi/PrForward/src/FindXHits.cu
 delete mode 100644 cuda/SciFi/PrForward/src/HitUtils.cu
 delete mode 100644 cuda/SciFi/PrForward/src/LinearFitting.cu
 delete mode 100644 cuda/SciFi/PrForward/src/ParabolaFitting.cu
 delete mode 100644 cuda/SciFi/PrForward/src/PrForward.cu
 delete mode 100644 cuda/SciFi/PrForward/src/PrForwardTools.cu
 delete mode 100644 cuda/SciFi/PrForward/src/ReferencePlaneProjection.cu
 delete mode 100644 cuda/SciFi/PrForward/src/TrackUtils.cu
 create mode 100644 cuda/SciFi/classifiers/README.md
 rename cuda/SciFi/{PrForward => classifiers}/include/TMVA_Forward.cuh (96%)
 rename cuda/SciFi/{PrForward => classifiers}/include/TMVA_Forward_1.cuh (100%)
 rename cuda/SciFi/{PrForward => classifiers}/include/TMVA_Forward_2.cuh (100%)
 rename cuda/SciFi/{PrForward => classifiers}/src/TMVA_Forward.cu (100%)
 create mode 100644 cuda/SciFi/utils/README.md
 create mode 100644 cuda/SciFi/utils/include/HitUtils.cuh
 create mode 100644 cuda/SciFi/utils/include/TrackUtils.cuh
 create mode 100644 cuda/SciFi/utils/src/HitUtils.cu
 create mode 100644 cuda/SciFi/utils/src/TrackUtils.cu
 delete mode 100644 stream/visitors/SciFi/src/CpuSciFiPrForwardVisitor.cu
 delete mode 100644 stream/visitors/SciFi/src/SciFiPrForwardVisitor.cu
 delete mode 100644 x86/SciFi/PrForward/CMakeLists.txt
 delete mode 100644 x86/SciFi/PrForward/include/PrForwardWrapper.h
 delete mode 100644 x86/SciFi/PrForward/include/RunForwardCPU.h
 delete mode 100644 x86/SciFi/PrForward/src/PrForwardWrapper.cpp
 delete mode 100644 x86/SciFi/PrForward/src/RunForwardCPU.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ffeb915be4f..06ac84cf195 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -215,7 +215,7 @@ include_directories(cuda/SciFi/looking_forward_sbt/extend_tracks_uv/include)
 include_directories(cuda/SciFi/looking_forward_sbt/quality_filter/include)
 include_directories(cuda/SciFi/looking_forward_sbt/quality_filter_x/include)
 include_directories(cuda/SciFi/looking_forward_sbt/search_uv_windows/include)
-include_directories(cuda/SciFi/PrForward/include)
+include_directories(cuda/SciFi/classifiers/include)
 include_directories(cuda/SciFi/consolidate/include)
 include_directories(cuda/muon/common/include)
 include_directories(cuda/utils/prefix_sum/include)
@@ -227,7 +227,6 @@ include_directories(checker/tracking/include)
 include_directories(checker/pv/include)
 include_directories(checker/selections/include)
 include_directories(stream/sequence/include)
-include_directories(x86/SciFi/PrForward/include)
 include_directories(x86/SciFi/LookingForward/include)
 include_directories(x86/SciFi/MomentumForward/include)
 include_directories(cuda/UT/UTDecoding/include)
diff --git a/checker/tracking/CMakeLists.txt b/checker/tracking/CMakeLists.txt
index fa931478c6a..7ff1dcecfc3 100644
--- a/checker/tracking/CMakeLists.txt
+++ b/checker/tracking/CMakeLists.txt
@@ -9,7 +9,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/kalman/ParKalman/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/beamlinePV/include)
diff --git a/cuda/SciFi/CMakeLists.txt b/cuda/SciFi/CMakeLists.txt
index a387c9b8156..fcffc61c06c 100644
--- a/cuda/SciFi/CMakeLists.txt
+++ b/cuda/SciFi/CMakeLists.txt
@@ -19,7 +19,8 @@ file(GLOB scifi_lf_quality_filter "looking_forward_sbt/quality_filter/src/*cu")
 file(GLOB scifi_lf_quality_filter_x "looking_forward_sbt/quality_filter_x/src/*cu")
 file(GLOB scifi_lf_search_uv_windows "looking_forward_sbt/search_uv_windows/src/*cu")
 file(GLOB scifi_lf_fit "looking_forward_sbt/fit/src/*cu")
-file(GLOB scifi_prforward "PrForward/src/*cu")
+file(GLOB scifi_utils "utils/src/*cu")
+file(GLOB scifi_classifiers "classifiers/src/*cu")
 file(GLOB scifi_consolidate "consolidate/src/*cu")
 
 include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
@@ -61,12 +62,14 @@ include_directories(looking_forward_sbt/quality_filter/include)
 include_directories(looking_forward_sbt/quality_filter_x/include)
 include_directories(looking_forward_sbt/search_uv_windows/include)
 include_directories(looking_forward_sbt/fit/include)
-include_directories(PrForward/include)
+include_directories(utils/include)
+include_directories(classifiers/include)
 include_directories(consolidate/include)
 
 add_library(SciFi STATIC
   ${scifi_common}
   ${scifi_preprocessing}
+  ${scifi_utils}
   ${scifi_lf_common}
   ${scifi_lf_calculate_first_layer_window}
   ${scifi_lf_calculate_second_layer_window}
@@ -86,7 +89,7 @@ add_library(SciFi STATIC
   ${scifi_lf_quality_filter_x}
   ${scifi_lf_search_uv_windows}
   ${scifi_lf_fit}
-  ${scifi_prforward}
+  ${scifi_classifiers}
   ${scifi_consolidate}
 )
 
diff --git a/cuda/SciFi/PrForward/.gitignore b/cuda/SciFi/PrForward/.gitignore
deleted file mode 100644
index 378eac25d31..00000000000
--- a/cuda/SciFi/PrForward/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/cuda/SciFi/PrForward/README.md b/cuda/SciFi/PrForward/README.md
deleted file mode 100644
index cc8a2c28798..00000000000
--- a/cuda/SciFi/PrForward/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Implementation of the forward based on Rec v23r3
diff --git a/cuda/SciFi/PrForward/include/FindStereoHits.cuh b/cuda/SciFi/PrForward/include/FindStereoHits.cuh
deleted file mode 100644
index c14347c5657..00000000000
--- a/cuda/SciFi/PrForward/include/FindStereoHits.cuh
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-#include "SciFiDefinitions.cuh"
-#include "SciFiEventModel.cuh"
-#include "TrackUtils.cuh"
-#include "HitUtils.cuh"
-
-/**
-   Functions related to selecting hits on the uv planes,
-   which match to the VeloUT input track
- */
-
-__host__ __device__ void collectStereoHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::Arrays* constArrays,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits);
-
-__host__ __device__ bool selectStereoHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  const SciFi::Tracking::Arrays* constArrays,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
-
-__host__ __device__ bool addHitsOnEmptyStereoLayers(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  const SciFi::Tracking::Arrays* constArrays,
-  PlaneCounter& planeCounter,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
diff --git a/cuda/SciFi/PrForward/include/FindXHits.cuh b/cuda/SciFi/PrForward/include/FindXHits.cuh
deleted file mode 100644
index ff17e8e3eb3..00000000000
--- a/cuda/SciFi/PrForward/include/FindXHits.cuh
+++ /dev/null
@@ -1,120 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-#include "SciFiDefinitions.cuh"
-#include "PrForwardConstants.cuh"
-#include "UTDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "HitUtils.cuh"
-#include "LinearFitting.cuh"
-#include "ReferencePlaneProjection.cuh"
-#include "SciFiEventModel.cuh"
-
-#include "LookingForwardUtils.h"
-
-/**
-   Functions related to selecting hits on the x planes,
-   which match to the VeloUT input track
- */
-__host__ void collectAllXHits_proto_p(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const MiniState& UT_state,
-  const float qOverP,
-  int side, 
-  std::array<int, 2 * 6>& windows_x,
-  std::array<int, 2 * 6>& windows_uv,
-  std::array<float, 4 * 6>& parameters_uv,
-  const SciFiWindowsParams& window_params,
-  const std::array<int, 12> true_scifi_indices_per_layer);
-
-__host__ void x_limits_from_dxRef( 
-  const SciFi::Tracking::Arrays* constArrays,
-  const MiniState& velo_state,
-  const float InvPz,
-  const float p,
-  const float tx2,
-  const float ty2, 
-  const bool wSignTreatment, 
-  float& xBoundOnRef,
-  float& xBoundOnRefWS); 
-
-__host__ void collectAllXHits_proto(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& UT_state,
-  const float qOverP,
-  int side,
-  std::array<int, 2 * 6>& windows_x,
-  std::array<int, 2 * 6>& windows_uv,
-  std::array<float, 4 * 6>& parameters_uv);
-  
-__host__ __device__ void collectAllXHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int& n_x_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const float qop,
-  int side);
-
-__host__ __device__ void improveXCluster(
-  int& it2,
-  const int it1,
-  const int itEnd,
-  const int n_x_hits,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const float xWindow,
-  const SciFi::Tracking::HitSearchCuts& pars,
-  PlaneCounter& planeCounter,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ void selectXCandidates(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int& n_x_hits,
-  bool usedHits[SciFi::Tracking::max_x_hits],
-  float coordX[SciFi::Tracking::max_x_hits],
-  SciFi::Tracking::Track candidate_tracks[SciFi::Constants::max_tracks],
-  int& n_candidate_tracks,
-  const float zRef_track,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::Arrays* constArrays,
-  int side,
-  const bool secondLoop);
-
-__host__ __device__ bool addHitsOnEmptyXLayers(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  bool fullFit,
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  const SciFi::Tracking::Arrays* constArrays,
-  PlaneCounter& planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars_cur,
-  int side);
diff --git a/cuda/SciFi/PrForward/include/HitUtils.cuh b/cuda/SciFi/PrForward/include/HitUtils.cuh
deleted file mode 100644
index dad26033d92..00000000000
--- a/cuda/SciFi/PrForward/include/HitUtils.cuh
+++ /dev/null
@@ -1,220 +0,0 @@
-#pragma once
-
-#include "SciFiDefinitions.cuh"
-#include "PrForwardConstants.cuh"
-#include "SciFiEventModel.cuh"
-
-/**
-   Helper functions related to properties of hits on planes
- */
-
-// Helper used to keep track of how many x / stereo hits per lane have
-// been added to a candidate track
-struct PlaneCounter {
-  int planeList[SciFi::Constants::n_layers] = {0};
-  unsigned int nbDifferent = 0;
-
-  __host__ __device__ inline void addHit(int plane)
-  {
-    assert(plane < SciFi::Constants::n_layers);
-    nbDifferent += (int) ((planeList[plane] += 1) == 1);
-  }
-
-  __host__ __device__ inline void removeHit(int plane)
-  {
-    assert(plane < SciFi::Constants::n_layers);
-    nbDifferent -= ((int) ((planeList[plane] -= 1) == 0));
-  }
-
-  __host__ __device__ inline int nbInPlane(int plane) const
-  {
-    assert(plane < SciFi::Constants::n_layers);
-    return planeList[plane];
-  }
-
-  __host__ __device__ inline int nbSingle() const
-  {
-    int single = 0;
-    for (int i = 0; i < SciFi::Constants::n_layers; ++i) {
-      single += planeList[i] == 1 ? 1 : 0;
-    }
-    return single;
-  }
-
-  __host__ __device__ inline void clear()
-  {
-    nbDifferent = 0;
-    for (int i = 0; i < SciFi::Constants::n_layers; ++i) {
-      planeList[i] = 0;
-    }
-  }
-};
-
-__host__ __device__ void countPlanesOfXHits(
-  PlaneCounter& planeCounter,
-  const int it1,
-  const int it2,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ void countUnusedXHitsOnPlanes(
-  PlaneCounter& lplaneCounter,
-  const int itWindowStart,
-  const int itWindowEnd,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ void addXHitsForCandidateWithTooFewPlanes(
-  int& itWindowStart,
-  int& itWindowEnd,
-  const int it2,
-  const int itEnd,
-  float& minInterval,
-  PlaneCounter& lplaneCounter,
-  const int nPlanes,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  int& best,
-  int& bestEnd,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ void collectXHitsToFit(
-  const int it1,
-  const int it2,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  bool usedHits[SciFi::Tracking::max_x_hits],
-  int coordToFit[SciFi::Tracking::max_x_hits],
-  int& n_coordToFit,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  float& xAtRef);
-
-__host__ __device__ int findBestXHitOnEmptyLayer(
-  const int itEnd,
-  const int itH,
-  const SciFi::Hits& scifi_hits,
-  const float maxX,
-  const float xPred);
-
-template<int N>
-__host__ __device__ void sortHitsByKey(float* keys, int n, int* hits)
-{
-  // find permutations
-  uint permutations[N];
-  assert(n <= N);
-  for (int i = 0; i < n; ++i) {
-    uint position = 0;
-    for (int j = 0; j < n; ++j) {
-      // sort keys in ascending order
-      int sort_result = -1;
-      if (keys[i] > keys[j]) sort_result = 1;
-      if (keys[i] == keys[j]) sort_result = 0;
-      position += sort_result > 0 || (sort_result == 0 && i > j);
-    }
-    permutations[position] = i;
-  }
-
-  // apply permutations, store hits in temporary container
-  int hits_tmp[N];
-  float keys_tmp[N];
-  for (int i = 0; i < n; ++i) {
-    const int index = permutations[i];
-    hits_tmp[i] = hits[index];
-    keys_tmp[i] = keys[index];
-  }
-
-  // copy hits back to original container
-  for (int i = 0; i < n; ++i) {
-    hits[i] = hits_tmp[i];
-    keys[i] = keys_tmp[i];
-  }
-}
-
-// check that val is within [min, max]
-__host__ __device__ inline bool isInside(float val, const float min, const float max)
-{
-  return (val > min) && (val < max);
-}
-
-// get lowest index where range[index] > value, within [start,end] of range
-__host__ __device__ inline int getLowerBound(float range[], float value, int start, int end)
-{
-  int i = start;
-  for (; i < end; i++) {
-    if (range[i] > value) break;
-  }
-  return i;
-}
-
-// match stereo hits to x hits
-__host__ __device__ bool matchStereoHit(
-  const int itUV1,
-  const int uv_zone_offset_end,
-  const SciFi::Hits& scifi_hits,
-  const float xMinUV,
-  const float xMaxUV);
-
-__host__ __device__ bool matchStereoHitWithTriangle(
-  const int itUV2,
-  const int triangle_zone_offset_end,
-  const float yInZone,
-  const SciFi::Hits& scifi_hits,
-  const float xMinUV,
-  const float xMaxUV,
-  const int side);
-
-__host__ __device__ void removeOutlier(
-  const SciFi::Hits& scifi_hits,
-  PlaneCounter& planeCounter,
-  int* coordToFit,
-  int& n_coordToFit,
-  const int worst);
-
-__host__ __device__ void findStereoHitsWithinXTol(
-  const int itBegin,
-  const int itEnd,
-  const SciFi::Hits& scifi_hits,
-  const float yZone,
-  const float xPred,
-  const float dxTol,
-  const bool triangleSearch,
-  const float dxDySign,
-  int& n_stereoHits,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits]);
-
-__host__ __device__ void findStereoHitClusterByDx(
-  PlaneCounter& planeCounter,
-  int& endRange,
-  const SciFi::Tracking::HitSearchCuts& pars,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  const int n_stereoHits,
-  const SciFi::Hits& scifi_hits,
-  float& sumCoord,
-  int& first_hit);
-
-__host__ __device__ void cleanStereoHitCluster(
-  int& beginRange,
-  int& endRange,
-  const int n_stereoHits,
-  const int stereoHits[SciFi::Tracking::max_stereo_hits],
-  const float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  float& sumCoord,
-  PlaneCounter& planeCounter,
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ int findBestStereoHitOnEmptyLayer(
-  const int itBegin,
-  const int itEnd,
-  const SciFi::Hits& scifi_hits,
-  const float yZone,
-  const float xPred,
-  const float dxTol,
-  const bool triangleSearch);
diff --git a/cuda/SciFi/PrForward/include/LinearFitting.cuh b/cuda/SciFi/PrForward/include/LinearFitting.cuh
deleted file mode 100644
index 486f7b50905..00000000000
--- a/cuda/SciFi/PrForward/include/LinearFitting.cuh
+++ /dev/null
@@ -1,77 +0,0 @@
-#pragma once
-
-#include "SciFiDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "HitUtils.cuh"
-#include "SciFiEventModel.cuh"
-
-#include <cmath>
-
-namespace SciFi {
-  namespace Tracking {
-
-    struct LineFitterPars {
-      float m_z0 = 0.;
-      float m_c0 = 0.;
-      float m_tc = 0.;
-
-      float m_s0 = 0.;
-      float m_sz = 0.;
-      float m_sz2 = 0.;
-      float m_sc = 0.;
-      float m_scz = 0.;
-    };
-  } // namespace Tracking
-} // namespace SciFi
-
-__host__ __device__ void incrementLineFitParameters(
-  SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int it);
-
-__host__ __device__ void fitHitsFromSingleHitPlanes(
-  const int it1,
-  const int it2,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  const PlaneCounter planeCounter,
-  SciFi::Tracking::LineFitterPars& lineFitParameters,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits],
-  int nOtherHits[SciFi::Constants::n_layers]);
-
-__host__ __device__ void addAndFitHitsFromMultipleHitPlanes(
-  const int nOtherHits[SciFi::Constants::n_layers],
-  SciFi::Tracking::LineFitterPars& lineFitParameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits]);
-
-__host__ __device__ float getLineFitDistance(
-  SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int it);
-
-__host__ __device__ float getLineFitChi2(
-  SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int it);
-
-__host__ __device__ void solveLineFit(SciFi::Tracking::LineFitterPars& parameters);
-
-__host__ __device__ void fastLinearFit(
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  PlaneCounter planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
diff --git a/cuda/SciFi/PrForward/include/ParabolaFitting.cuh b/cuda/SciFi/PrForward/include/ParabolaFitting.cuh
deleted file mode 100644
index 0cfb8d66da7..00000000000
--- a/cuda/SciFi/PrForward/include/ParabolaFitting.cuh
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-
-#include "SciFiDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "SciFiEventModel.cuh"
-
-__host__ __device__ int fitParabola(
-  int* coordToFit,
-  const int n_coordToFit,
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  const bool xFit);
diff --git a/cuda/SciFi/PrForward/include/PrForward.cuh b/cuda/SciFi/PrForward/include/PrForward.cuh
deleted file mode 100644
index 376a16fe8fe..00000000000
--- a/cuda/SciFi/PrForward/include/PrForward.cuh
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma once
-
-#include "PrForwardTools.cuh"
-#include "Handler.cuh"
-// #include "ArgumentsCommon.cuh"
-#include "ArgumentsVelo.cuh"
-#include "ArgumentsUT.cuh"
-#include "ArgumentsSciFi.cuh"
-
-/** @class PrForward PrForward.h
- *
- *  - InputTracksName: Input location for VeloUT tracks
- *  - OutputTracksName: Output location for Forward tracks
- *  Based on code written by
- *  2012-03-20 : Olivier Callot
- *  2013-03-15 : Thomas Nikodem
- *  2015-02-13 : Sevda Esen [additional search in the triangles by Marian Stahl]
- *  2016-03-09 : Thomas Nikodem [complete restructuring]
- *  2018-08    : Vava Gligorov [extract code from Rec, make compile within GPU framework
- *  2018-09    : Dorothea vom Bruch [convert to CUDA, runs on GPU]
- */
-
-__global__ void scifi_pr_forward(
-  uint32_t* dev_scifi_hits,
-  const uint32_t* dev_scifi_hit_count,
-  const int* dev_atomics_velo,
-  const uint* dev_velo_track_hit_number,
-  const char* dev_velo_states,
-  const int* dev_atomics_ut,
-  const char* dev_ut_track_hits,
-  const uint* dev_ut_track_hit_number,
-  const float* dev_ut_qop,
-  const uint* dev_ut_track_velo_indices,
-  SciFi::TrackHits* dev_scifi_tracks,
-  int* dev_atomics_scifi,
-  const SciFi::Tracking::TMVA* dev_tmva1,
-  const SciFi::Tracking::TMVA* dev_tmva2,
-  const SciFi::Tracking::Arrays* dev_constArrays,
-  const float* dev_magnet_polarity,
-  const char* dev_scifi_geometry,
-  const float* dev_inv_clus_res);
-
-ALGORITHM(
-  scifi_pr_forward,
-  scifi_pr_forward_t,
-  ARGUMENTS(
-    dev_scifi_hits,
-    dev_scifi_hit_count,
-    dev_atomics_velo,
-    dev_velo_track_hit_number,
-    dev_velo_states,
-    dev_atomics_ut,
-    dev_ut_track_hits,
-    dev_ut_track_hit_number,
-    dev_ut_qop,
-    dev_ut_track_velo_indices,
-    dev_scifi_tracks,
-    dev_scifi_selected_track_indices,
-    dev_atomics_scifi))
diff --git a/cuda/SciFi/PrForward/include/PrForwardConstants.cuh b/cuda/SciFi/PrForward/include/PrForwardConstants.cuh
deleted file mode 100644
index c909c530190..00000000000
--- a/cuda/SciFi/PrForward/include/PrForwardConstants.cuh
+++ /dev/null
@@ -1,236 +0,0 @@
-#pragma once
-
-/**
-   Contains constants needed for the forward tracking
-   - cut values
-   - geometry descriptions
-   - parameterizations
-
-   12/09/2018: cut values are those defined in:
-   https://gitlab.cern.ch/lhcb/Rec/blob/master/Tf/TrackSys/python/TrackSys/Configuration.py
-   https://gitlab.cern.ch/lhcb/Rec/blob/master/Tf/TrackSys/python/TrackSys/RecoUpgradeTracking.py
-
-   for the RecoFastTrackingStage, using the default values of ConfigHLT1 (master branch of Rec)
-
- */
-
-#include "VeloEventModel.cuh"
-#include "SystemOfUnits.h"
-#include "SciFiDefinitions.cuh"
-#include <cassert>
-
-namespace SciFi {
-
-  namespace Tracking {
-
-    constexpr int max_candidate_tracks = 5;   // max # of candidate tracks from x hits only
-    constexpr int max_tracks_second_loop = 5; // same as above, but for second loop
-    constexpr int max_selected_tracks = max_candidate_tracks + max_tracks_second_loop;
-    constexpr int max_x_hits = 500;     // max # of hits in all x layers
-    constexpr int max_other_hits = 5;   // max # of hits from x planes with more than 1 hit
-    constexpr int max_stereo_hits = 25; // max # of hits in all stereo layers
-    constexpr int max_coordToFit = 15;  // only for x layers
-    constexpr int max_scifi_hits = 20;  // for x and u/v layers
-
-    constexpr int nTrackParams = 9;
-
-    constexpr int TMVA_Nvars = 7;
-    constexpr int TMVA_Nlayers = 5;
-
-    // Formerly PrParameters
-    struct HitSearchCuts {
-      __host__ __device__ HitSearchCuts(
-        unsigned int minXHits_,
-        float maxXWindow_,
-        float maxXWindowSlope_,
-        float maxXGap_,
-        unsigned int minStereoHits_) :
-        minXHits {minXHits_},
-        maxXWindow {maxXWindow_}, maxXWindowSlope {maxXWindowSlope_}, maxXGap {maxXGap_}, minStereoHits {minStereoHits_}
-      {}
-      const unsigned int minXHits;
-      const float maxXWindow;
-      const float maxXWindowSlope;
-      const float maxXGap;
-      unsigned int minStereoHits;
-    };
-
-    // dump a bunch of options here
-    constexpr float deltaQuality = 0.1; // Difference in quality btw two tracks which share hits when clone killing
-    constexpr float cloneFraction =
-      0.4; // The fraction of shared SciFi hits btw two tracks to trigger the clone killing
-
-    constexpr float yTolUVSearch = 11. * Gaudi::Units::mm;
-    constexpr float tolY = 5. * Gaudi::Units::mm;
-    constexpr float tolYSlope = 0.002 * Gaudi::Units::mm;
-    constexpr float maxChi2LinearFit = 100.;
-    constexpr float maxChi2XProjection = 15.;
-    constexpr float maxChi2PerDoF = 7.;
-
-    constexpr float tolYMag = 10. * Gaudi::Units::mm;
-    constexpr float tolYMagSlope = 0.015;
-    constexpr float minYGap = 0.4 * Gaudi::Units::mm;
-
-    constexpr unsigned int minTotalHits = 10;
-    constexpr float maxChi2StereoLinear = 60.;
-    constexpr float maxChi2Stereo = 4.5;
-
-    // first loop Hough Cluster search
-    constexpr unsigned int minXHits = 5;
-    constexpr float maxXWindow = 1. * Gaudi::Units::mm; // 1.2 * Gaudi::Units::mm  ;
-    constexpr float maxXWindowSlope = 0.002 * Gaudi::Units::mm;
-    constexpr float maxXGap = 1. * Gaudi::Units::mm; // 1.2 * Gaudi::Units::mm  ;
-    constexpr unsigned int minSingleHits = 2;
-
-    // second loop Hough Cluster search
-    constexpr bool secondLoop = true;
-    constexpr unsigned int minXHits_2nd = 4;
-    constexpr float maxXWindow_2nd = 1.5 * Gaudi::Units::mm;
-    constexpr float maxXWindowSlope_2nd = 0.002 * Gaudi::Units::mm;
-    constexpr float maxXGap_2nd = 0.5 * Gaudi::Units::mm;
-
-    // collectX search
-    constexpr float minPt = 400 * Gaudi::Units::MeV; // 500 * Gaudi::Units::MeV ;
-    // stereo hit matching
-    constexpr float tolYCollectX = 3.5 * Gaudi::Units::mm;        // 4.1* Gaudi::Units::mm ;
-    constexpr float tolYSlopeCollectX = 0.001 * Gaudi::Units::mm; // 0.0018 * Gaudi::Units::mm ;
-    constexpr float tolYTriangleSearch = 20.f;
-    // veloUT momentum estimate
-    constexpr bool useMomentumEstimate = true;
-    constexpr bool useWrongSignWindow = true;
-    constexpr float wrongSignPT = 2000. * Gaudi::Units::MeV;
-    // Track Quality NN
-    constexpr float maxQuality = 0.9;
-    constexpr float deltaQuality_NN = 0.1;
-
-    // parameterizations
-    constexpr float byParams = -0.667996;
-    constexpr float cyParams = -3.68424e-05;
-
-    // z Reference plane
-    constexpr float zReference = 8520. * Gaudi::Units::mm; // in T2
-    constexpr float zRefInv = 1.f / zReference;
-
-    // TODO: CHECK THESE VALUES USING FRAMEWORK
-    constexpr float xLim_Max = 3300.;
-    constexpr float yLim_Max = 2500.;
-    constexpr float xLim_Min = -3300.;
-    constexpr float yLim_Min = -25.;
-
-    // TO BE READ FROM XML EVENTUALLY
-    //constexpr float magscalefactor = -1;
-    constexpr int zoneoffsetpar = 6;
-
-    struct Arrays {
-      // Returns whether the current layer is an X plane
-      const bool is_x_plane [12] {1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1};
-
-      // the Magnet Parametrization
-      // parameterized in offset [0], (slope difference due to kick)^2 [1],
-      // tx^2 [2], ty^2 [3]
-      const float zMagnetParams[4] = {5212.38, 406.609, -1102.35, -498.039};
-
-      // more Parametrizations
-      const float xParams[2] = {18.6195, -5.55793};
-
-      // momentum Parametrization
-      const float momentumParams[6] = {1.21014, 0.637339, -0.200292, 0.632298, 3.23793, -27.0259};
-
-      // covariance values
-      const float covarianceValues[5] = {4.0, 400.0, 4.e-6, 1.e-4, 0.1};
-
-      // definition of zones
-      // access upper with offset of 6
-      const int zoneoffsetpar = 6;
-      const int xZones[12] = {0, 6, 8, 14, 16, 22, 1, 7, 9, 15, 17, 23};
-      const int uvZones[12] = {2, 4, 10, 12, 18, 20, 3, 5, 11, 13, 19, 21};
-
-      // ASSORTED GEOMETRY VALUES, eventually read this from some xml
-      const float xZone_zPos[6] = {7826., 8036., 8508., 8718., 9193., 9403.};
-      const float uvZone_zPos[12] =
-        {7896., 7966., 8578., 8648., 9263., 9333., 7896., 7966., 8578., 8648., 9263., 9333.};
-      const float uvZone_dxdy[12] = {0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892};
-      const float Zone_dzdy[24] = {0.0036010};
-
-      // this is used by looking_forward_sbt maybe this is not the right place to put it
-      const float uv_dx[6] = {1.6739478541449213,
-                              1.6738495069872612,
-                              1.935683825160498,
-                              1.9529279746403518,
-                              2.246931985749485,
-                              2.2797556995480273};
-    };
-
-    // parameters for extrapolating from EndVelo to ZReference
-    constexpr float xExtParams[6] = {4.08934e+06f, 6.31187e+08f, 131.999f, -1433.64f, -325.055f, 3173.52f};
-    // Params for momentum dependent search window estimate
-    // upper window to include 98% of hits(can't be too greedy
-    // here or the window size would explode)
-    constexpr float pUp[3] = {1.46244e+02f, 5.15348e+02f, -4.17237e-05f};
-    // lower window, the same to include 98% of hits
-    constexpr float pLo[3] = {5.00000e+01f, 9.61409e+02f, -1.31317e-04f};
-
-    // Track object used for finding tracks, not the final container for storing the tracks
-    struct Track {
-      int hit_indices[max_scifi_hits];
-      float qop;
-      int hitsNum = 0;
-      float quality;
-      float chi2;
-      // [0]: xRef
-      // [1]: (xRef-xMag)/(zRef-zMag)
-      // [2]: xParams[0] * dSlope
-      // [3]: xParams[1] * dSlope
-      // [4]: y param
-      // [5]: y param
-      // [6]: y param
-      // [7]: chi2
-      // [8]: nDoF
-      float trackParams[SciFi::Tracking::nTrackParams];
-
-      __host__ __device__ void addHit(int hit)
-      {
-        assert(hitsNum < max_scifi_hits - 1);
-        hit_indices[hitsNum++] = hit;
-      }
-
-      __host__ __device__ void set_qop(float _qop) { qop = _qop; }
-
-      __host__ __device__ float x(const float z) const
-      {
-        float dz = z - zReference;
-        return trackParams[0] + dz * (trackParams[1] + dz * (trackParams[2] + dz * trackParams[3]));
-      }
-
-      __host__ __device__ float xSlope(const float z) const
-      {
-        float dz = z - zReference;
-        return trackParams[1] + dz * (2.f * trackParams[2] + 3.f * dz * trackParams[3]);
-      }
-
-      __host__ __device__ float y(const float z) const
-      {
-        float dz = z - zReference;
-        return trackParams[4] + dz * (trackParams[5] + dz * trackParams[6]);
-      }
-
-      __host__ __device__ float ySlope(const float z) const
-      {
-        float dz = z - zReference;
-        return trackParams[5] + dz * 2.f * trackParams[6];
-      }
-    };
-
-  } // namespace Tracking
-} // namespace SciFi
diff --git a/cuda/SciFi/PrForward/include/PrForwardTools.cuh b/cuda/SciFi/PrForward/include/PrForwardTools.cuh
deleted file mode 100644
index a4c924a45bf..00000000000
--- a/cuda/SciFi/PrForward/include/PrForwardTools.cuh
+++ /dev/null
@@ -1,88 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-
-#include <cassert>
-#include "Logger.h"
-#include "SystemOfUnits.h"
-#include "TMVA_Forward_1.cuh"
-#include "TMVA_Forward_2.cuh"
-#include "SciFiDefinitions.cuh"
-#include "VeloDefinitions.cuh"
-#include "UTDefinitions.cuh"
-#include "PrForwardConstants.cuh"
-#include "TrackUtils.cuh"
-#include "LinearFitting.cuh"
-#include "HitUtils.cuh"
-#include "FindXHits.cuh"
-#include "FindStereoHits.cuh"
-#include "VeloEventModel.cuh"
-#include "VeloConsolidated.cuh"
-#include "UTConsolidated.cuh"
-#include "SciFiEventModel.cuh"
-#include "States.cuh"
-
-__host__ __device__ void find_forward_tracks(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const float qop_ut,
-  const int i_veloUT_track,
-  SciFi::TrackHits* outputTracks,
-  uint* n_forward_tracks,
-  const int ut_event_number_of_tracks,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state);
-
-__host__ __device__ void selectFullCandidates(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track* candidate_tracks,
-  int& n_candidate_tracks,
-  SciFi::Tracking::Track* selected_tracks,
-  int& n_selected_tracks,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  MiniState velo_state,
-  const float VeloUT_qOverP,
-  SciFi::Tracking::HitSearchCuts& pars_cur,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const bool secondLoop);
-
-__host__ __device__ SciFi::TrackHits makeTrack(SciFi::Tracking::Track track);
-
-template<class T>
-__host__ __device__ void sort_tracks(SciFi::Tracking::Track* tracks, const int n, const T& sort_function)
-{
-  // find permutations based on sort_function
-  uint permutations[SciFi::Tracking::max_selected_tracks];
-  for (int i = 0; i < n; ++i) {
-    uint position = 0;
-    for (int j = 0; j < n; ++j) {
-      const int sort_result = sort_function(tracks[i], tracks[j]);
-      position += sort_result > 0 || (sort_result == 0 && i > j);
-    }
-    permutations[position] = i;
-  }
-
-  // apply permutations, store tracks in temporary container
-  SciFi::Tracking::Track tracks_tmp[SciFi::Tracking::max_selected_tracks];
-  for (int i = 0; i < n; ++i) {
-    const int index = permutations[i];
-    tracks_tmp[i] = tracks[index];
-  }
-
-  // copy tracks back to original container
-  for (int i = 0; i < n; ++i) {
-    tracks[i] = tracks_tmp[i];
-  }
-}
diff --git a/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh b/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
deleted file mode 100644
index b1e549f5948..00000000000
--- a/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-
-#include "SciFiDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "SciFiEventModel.cuh"
-
-/**
-   Project x hits onto reference plane
-*/
-
-__host__ __device__ void xAtRef_SamePlaneHits(
-  const SciFi::Hits& scifi_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  const float xParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  MiniState velo_state,
-  const float zMag,
-  int itH,
-  int itEnd);
diff --git a/cuda/SciFi/PrForward/include/TrackUtils.cuh b/cuda/SciFi/PrForward/include/TrackUtils.cuh
deleted file mode 100644
index fb3577f5a3c..00000000000
--- a/cuda/SciFi/PrForward/include/TrackUtils.cuh
+++ /dev/null
@@ -1,74 +0,0 @@
-#pragma once
-
-#include <cmath>
-
-#include "SciFiDefinitions.cuh"
-#include "PrForwardConstants.cuh"
-#include "HitUtils.cuh"
-#include "ParabolaFitting.cuh"
-#include "SciFiEventModel.cuh"
-
-/**
-   Helper functions related to track properties
- */
-
-// extrapolate x position from given state to z
-__host__ __device__ float xFromVelo(const float z, const MiniState& velo_state);
-
-// extrapolate y position from given state to z
-__host__ __device__ float yFromVelo(const float z, const MiniState& velo_state);
-
-__host__ __device__ float evalCubicParameterization(const float params[4], float z);
-
-__host__ __device__ float evalParameterizationX(const float* params, float z);
-
-__host__ __device__ float evalParameterizationY(const float* params, float z);
-
-__host__ __device__ bool lowerByQuality(SciFi::Tracking::Track t1, SciFi::Tracking::Track t2);
-
-__host__ __device__ inline float straightLinePropagationFromReferencePlane(const float params[4], float z)
-{
-  float dz = z - SciFi::Tracking::zReference;
-  return params[0] + params[1] * dz;
-} 
-
-__host__ __device__ inline float straightLinePropagationFromReferencePlane(const float x0, const float tx, float z)
-{
-  float dz = z - SciFi::Tracking::zReference;
-  return x0 + tx * dz;
-} 
-
-__host__ __device__ void getTrackParameters(
-  float xAtRef,
-  const MiniState& velo_state,
-  const SciFi::Tracking::Arrays* constArrays,
-  float trackParams[SciFi::Tracking::nTrackParams]);
-
-__host__ __device__ float calcqOverP(float bx, const SciFi::Tracking::Arrays* constArrays, const MiniState& velo_state, const float magnet_polarity);
-
-__host__ __device__ float zMagnet(const MiniState& velo_state, const SciFi::Tracking::Arrays* constArrays);
-
-__host__ __device__ float calcDxRef(float pt, const MiniState& velo_state);
-
-__host__ __device__ float
-trackToHitDistance(const float trackParameters[SciFi::Tracking::nTrackParams], const SciFi::Hits& scifi_hits, int hit);
-
-__host__ __device__ float chi2XHit(const float parsX[4], const SciFi::Hits& scifi_hits, const int hit);
-
-__host__ __device__ bool quadraticFitX(
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  PlaneCounter& planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
-
-__host__ __device__ bool fitYProjection(
-  const SciFi::Hits& scifi_hits,
-  SciFi::Tracking::Track& track,
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  PlaneCounter& planeCounter,
-  const MiniState& velo_state,
-  const SciFi::Tracking::Arrays* constArrays,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
diff --git a/cuda/SciFi/PrForward/src/FindStereoHits.cu b/cuda/SciFi/PrForward/src/FindStereoHits.cu
deleted file mode 100644
index ce5a89f300e..00000000000
--- a/cuda/SciFi/PrForward/src/FindStereoHits.cu
+++ /dev/null
@@ -1,247 +0,0 @@
-#include "FindStereoHits.cuh"
-
-//=========================================================================
-//  Collect all hits in the stereo planes compatible with the track
-//=========================================================================
-__host__ __device__ void collectStereoHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::Arrays* constArrays,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits)
-{
-  for (int zone = 0; zone < SciFi::Constants::n_layers; ++zone) {
-    // get yZone and xPred: x and y values at z of layer based on candidate track parameters
-    const float parsX[4] = {track.trackParams[0], track.trackParams[1], track.trackParams[2], track.trackParams[3]};
-    const float parsY[4] = {track.trackParams[4], track.trackParams[5], track.trackParams[6], 0.f};
-    float zZone = constArrays->uvZone_zPos[zone];
-    const float yZone = evalCubicParameterization(parsY, zZone);
-    assert(constArrays->uvZones[zone] < SciFi::Constants::n_zones);
-    zZone += constArrays->Zone_dzdy[constArrays->uvZones[zone]] * yZone; // Correct for dzDy
-    const float xPred = evalCubicParameterization(parsX, zZone);
-
-    const bool triangleSearch = fabsf(yZone) < SciFi::Tracking::tolYTriangleSearch;
-    // even zone number: if ( yZone > 0 ) continue;
-    // odd zone number: if ( -yZone > 0 ) continue;
-    // -> check for upper / lower half
-    // -> only continue if yZone is in the correct half
-    if (!triangleSearch && (2.f * float(((constArrays->uvZones[zone]) % 2) == 0) - 1.f) * yZone > 0.f) continue;
-
-    const float dxDySign = constArrays->uvZone_dxdy[zone] < 0.f ? -1.f : 1.f;
-    const float seed_x_at_zZone = xFromVelo(zZone, velo_state);
-    const float dxTol =
-      SciFi::Tracking::tolY + SciFi::Tracking::tolYSlope * (fabsf(xPred - seed_x_at_zZone) + fabsf(yZone));
-
-    // find stereo hits whose x coordinate is within xTol of the prediction
-    // from the candidate track
-    // This takes the y value (max, min) into account
-    const float lower_bound_at = -dxTol - yZone * constArrays->uvZone_dxdy[zone] + xPred;
-    int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[zone]);
-    int uv_zone_offset_end = uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[zone]);
-
-    int itBegin = getLowerBound(scifi_hits.x0, lower_bound_at, uv_zone_offset_begin, uv_zone_offset_end);
-    int itEnd = uv_zone_offset_end;
-
-    findStereoHitsWithinXTol(
-      itBegin,
-      itEnd,
-      scifi_hits,
-      yZone,
-      xPred,
-      dxTol,
-      triangleSearch,
-      dxDySign,
-      n_stereoHits,
-      stereoCoords,
-      stereoHits);
-
-    if (n_stereoHits >= SciFi::Tracking::max_stereo_hits) break;
-  }
-
-  // Sort hits by coord
-  // not using thrust::sort due to temporary_buffer::allocate:: get_temporary_buffer failed" error
-  // thrust::sort_by_key(thrust::seq, stereoCoords, stereoCoords + n_stereoHits, stereoHits);
-  sortHitsByKey<SciFi::Tracking::max_stereo_hits>(stereoCoords, n_stereoHits, stereoHits);
-}
-
-//=========================================================================
-//  Fit the stereo hits
-//=========================================================================
-__host__ __device__ bool selectStereoHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  const SciFi::Tracking::Arrays* constArrays,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-  int bestStereoHits[SciFi::Tracking::max_stereo_hits];
-  int n_bestStereoHits = 0;
-  float originalYParams[3] = {track.trackParams[4], track.trackParams[5], track.trackParams[6]};
-  float bestYParams[3];
-  float bestMeanDy = 1e9f;
-
-  if (pars.minStereoHits > n_stereoHits) return false;
-  int endLoop = n_stereoHits - pars.minStereoHits;
-
-  PlaneCounter planeCounter;
-  for (int beginRange = 0; beginRange < endLoop; ++beginRange) {
-    planeCounter.clear();
-    int endRange = beginRange;
-
-    float sumCoord = 0.;
-    // bad hack to reproduce itereator behavior from before: *(-1) = 0
-    int first_hit;
-    if (endRange == 0)
-      first_hit = 0;
-    else
-      first_hit = endRange - 1;
-
-    findStereoHitClusterByDx(
-      planeCounter, endRange, pars, stereoCoords, stereoHits, n_stereoHits, scifi_hits, sumCoord, first_hit);
-
-    cleanStereoHitCluster(
-      beginRange, endRange, n_stereoHits, stereoHits, stereoCoords, sumCoord, planeCounter, scifi_hits);
-
-    // Now we have a candidate, lets fit him
-    // track = original; //only yparams are changed
-    track.trackParams[4] = originalYParams[0];
-    track.trackParams[5] = originalYParams[1];
-    track.trackParams[6] = originalYParams[2];
-
-    int trackStereoHits[SciFi::Tracking::max_stereo_hits];
-    int n_trackStereoHits = 0;
-    assert(endRange < n_stereoHits);
-    for (int range = beginRange; range < endRange; ++range) {
-      trackStereoHits[n_trackStereoHits++] = stereoHits[range];
-    }
-
-    // fit Y Projection of track using stereo hits
-    if (!fitYProjection(
-          scifi_hits, track, trackStereoHits, n_trackStereoHits, planeCounter, velo_state, constArrays, pars))
-      continue;
-
-    if (!addHitsOnEmptyStereoLayers(
-          scifi_hits,
-          scifi_hit_count,
-          track,
-          trackStereoHits,
-          n_trackStereoHits,
-          constArrays,
-          planeCounter,
-          velo_state,
-          pars))
-      continue;
-
-    if (n_trackStereoHits < n_bestStereoHits) continue; // number of hits most important selection criteria!
-
-    //== Calculate  dy chi2 /ndf
-    float meanDy = 0.;
-    assert(n_trackStereoHits < n_stereoHits);
-    for (int i_hit = 0; i_hit < n_trackStereoHits; ++i_hit) {
-      const int hit = trackStereoHits[i_hit];
-      const float d = trackToHitDistance(track.trackParams, scifi_hits, hit) / scifi_hits.dxdy(hit);
-      meanDy += d * d;
-    }
-    meanDy /= float(n_trackStereoHits - 1);
-
-    if (n_trackStereoHits > n_bestStereoHits || meanDy < bestMeanDy) {
-      // if same number of hits take smaller chi2
-      bestYParams[0] = track.trackParams[4];
-      bestYParams[1] = track.trackParams[5];
-      bestYParams[2] = track.trackParams[6];
-      bestMeanDy = meanDy;
-
-      n_bestStereoHits = 0;
-      for (int i_hit = 0; i_hit < n_trackStereoHits; ++i_hit) {
-        assert(n_bestStereoHits < SciFi::Tracking::max_stereo_hits);
-        bestStereoHits[n_bestStereoHits++] = trackStereoHits[i_hit];
-      }
-    }
-
-  } // beginRange loop (<endLoop)
-
-  if (n_bestStereoHits > 0) {
-    track.trackParams[4] = bestYParams[0];
-    track.trackParams[5] = bestYParams[1];
-    track.trackParams[6] = bestYParams[2];
-    assert(n_bestStereoHits < n_stereoHits);
-
-    for (int i_hit = 0; i_hit < n_bestStereoHits; ++i_hit) {
-      int hit = bestStereoHits[i_hit];
-      if (track.hitsNum >= SciFi::Tracking::max_scifi_hits) break;
-      assert(track.hitsNum < SciFi::Tracking::max_scifi_hits);
-      track.addHit(hit);
-    }
-    return true;
-  }
-  return false;
-}
-
-//=========================================================================
-//  Add hits on empty stereo layers, and refit if something was added
-//=========================================================================
-__host__ __device__ bool addHitsOnEmptyStereoLayers(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  const SciFi::Tracking::Arrays* constArrays,
-  PlaneCounter& planeCounter,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-  // at this point pc is counting only stereo HITS!
-  if (planeCounter.nbDifferent > 5) return true;
-
-  bool added = false;
-  for (unsigned int zone = 0; zone < SciFi::Constants::n_layers; zone += 1) {
-    assert(constArrays->uvZones[zone] < SciFi::Constants::n_zones);
-    if (planeCounter.nbInPlane(constArrays->uvZones[zone] / 2) != 0) continue; // there is already one hit
-
-    float zZone = constArrays->uvZone_zPos[zone];
-
-    const float parsX[4] = {track.trackParams[0], track.trackParams[1], track.trackParams[2], track.trackParams[3]};
-    const float parsY[4] = {track.trackParams[4], track.trackParams[5], track.trackParams[6], 0.};
-
-    float yZone = evalCubicParameterization(parsY, zZone);
-    zZone = constArrays->Zone_dzdy[constArrays->uvZones[zone]] * yZone; // Correct for dzDy
-    yZone = evalCubicParameterization(parsY, zZone);
-    const float xPred = evalCubicParameterization(parsX, zZone);
-
-    const bool triangleSearch = fabsf(yZone) < SciFi::Tracking::tolYTriangleSearch;
-    // change sign of yZone depending on whether we are in the upper or lower half
-    if (!triangleSearch && (2.f * float((((constArrays->uvZones[zone]) % 2) == 0)) - 1.f) * yZone > 0.f) continue;
-
-    // only version without triangle search!
-    const float dxTol =
-      SciFi::Tracking::tolY + SciFi::Tracking::tolYSlope *
-                                (fabsf(xPred - velo_state.x + (zZone - velo_state.z) * velo_state.tx) + fabsf(yZone));
-    // -- Use a binary search to find the lower bound of the range of x values
-    // -- This takes the y value into account
-    const float lower_bound_at = -dxTol - yZone * constArrays->uvZone_dxdy[zone] + xPred;
-    int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[zone]);
-    int uv_zone_offset_end = uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[zone]);
-    int itBegin = getLowerBound(scifi_hits.x0, lower_bound_at, uv_zone_offset_begin, uv_zone_offset_end);
-    int itEnd = uv_zone_offset_end;
-
-    int best = findBestStereoHitOnEmptyLayer(itBegin, itEnd, scifi_hits, yZone, xPred, dxTol, triangleSearch);
-
-    if (-1 != best) {
-      assert(n_stereoHits < SciFi::Tracking::max_stereo_hits);
-      stereoHits[n_stereoHits++] = best;
-      planeCounter.addHit(scifi_hits.planeCode(best) / 2);
-      added = true;
-    }
-  }
-  if (!added) return true;
-  return fitYProjection(scifi_hits, track, stereoHits, n_stereoHits, planeCounter, velo_state, constArrays, pars);
-}
diff --git a/cuda/SciFi/PrForward/src/FindXHits.cu b/cuda/SciFi/PrForward/src/FindXHits.cu
deleted file mode 100644
index daa9b38016a..00000000000
--- a/cuda/SciFi/PrForward/src/FindXHits.cu
+++ /dev/null
@@ -1,830 +0,0 @@
-#include "FindXHits.cuh"
-#include "BinarySearch.cuh"
-
-__host__ void collectAllXHits_proto_p(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const MiniState& UT_state,
-  const float qOverP,
-  int side,
-  std::array<int, 2 * 6>& windows_x,
-  std::array<int, 2 * 6>& windows_uv,
-  std::array<float, 4 * 6>& parameters_uv,
-  const SciFiWindowsParams& window_params,
-  const std::array<int, 12> true_scifi_indices_per_layer)
-{
-  const float tx2 = velo_state.tx*velo_state.tx;
-  const float ty2 = velo_state.ty*velo_state.ty;
-  const float slope2 = tx2 + ty2;
-  const float pt = sqrtf(slope2 / (1.f + slope2) ) / fabsf(qOverP);
-  const float p = 1.f / std::abs(qOverP);
-
-  /* OPTIMIZE: possibly use these variables for wrong sign treatment */
-  // const float q = qOverP > 0.f ? 1.f : -1.f;
-  // const bool wSignTreatment = pt > SciFi::Tracking::wrongSignPT;
-  // float zMag = zMagnet(velo_state, constArrays);
-  // const float qop_WS = sqrtf(slope2 / (1.f + slope2) ) / pt;
-  // float dxRefWS = 0.f;
-  // if ( wSignTreatment ) {
-  //   dxRefWS = 0.9f * calcDxRef(SciFi::Tracking::wrongSignPT, velo_state);
-  // }
-  // const float dir = q * SciFi::Tracking::magscalefactor * (-1.f); // needed for wrong sign treatment
-  // const float xTolWS = dx_calc(velo_state, qop_WS, window_params);
-
-  //const float q = qOverP > 0.f ? 1.f : -1.f;
-  //const float dir = q * magnet_polarity * (-1.f);
-
-  //const bool wSignTreatment = pt > SciFi::Tracking::wrongSignPT;
-  float zMag = zMagnet(velo_state, constArrays);
-  const float qop_WS = sqrtf(slope2 / (1.f + slope2) ) / pt;
-  // float dxRefWS = 0.f;
-  // if ( wSignTreatment ) {
-  //   dxRefWS = 0.9f * calcDxRef(SciFi::Tracking::wrongSignPT, velo_state);
-  // }
-  const float xAtRef = xFromVelo(SciFi::Tracking::zReference, UT_state);
-  float xParams_seed[4] {xAtRef, UT_state.tx, 0, 0};
-
-  // use parametrization to propagate from UT to SciFi
-  const auto state_zRef = propagate_state_from_velo(UT_state, qOverP, 5);  // zRef is between layers 4 and 5
-  const float xTol = dx_calc(velo_state, qOverP, window_params);
-  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
-
-  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
-    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
-    assert(iZone - iZoneStartingPoint < 12);
-
-    const auto izone_rel = iZone - iZoneStartingPoint;
-    const float zZone = constArrays->xZone_zPos[izone_rel];
-
-    //const int layer = constArrays->xZones[iZone] / 2;
-    const float dz_x = (zZone - SciFi::Tracking::zReference);
-    const float xInZone = scifi_propagation(state_zRef.x, UT_state.tx, qOverP, dz_x);
-    const float yInZone = yFromVelo(zZone, velo_state);
-
-    const float xInZoneStraight = evalCubicParameterization(xParams_seed, zZone);
-
-    if (side > 0) {
-      if (
-        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-        !isInside(yInZone, SciFi::Tracking::yLim_Min, SciFi::Tracking::yLim_Max))
-        continue;
-    }
-    else {
-      if (
-        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-        !isInside(yInZone, side * SciFi::Tracking::yLim_Max, side * SciFi::Tracking::yLim_Min))
-        continue;
-    }
-
-    float xMin = xInZone - xTol;
-    float xMax = xInZone + xTol;
-
-    /* OPTIMIZE: how do we take care of wrong sign tracks with momentum windows? */
-    //float xTolWS = 0.0;
-    // if (wSignTreatment) {
-    //   // xTolWS = (zZone < SciFi::Tracking::zReference) ?
-    //   //   dxRefWS * zZone / SciFi::Tracking::zReference :
-    //   //   dxRefWS * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-    //   // if (dir > 0) {
-    //   //   xMin = xInZone - xTolWS;
-    //   // }
-    //   // else {
-    //   //   xMax = xInZone + xTolWS;
-    //   // }
-
-    //   debug_cout << "\t before WS treatment: xMin = " << xMin << ", xMax = " << xMax << ", WS = " << int(wSignTreatment) << ", pt = " << pt << std::endl;
-    //   if (dir > 0) {
-    //     xMin = -1.f * xInZone - xTolWS;
-    //   }
-    //   else {
-    //     xMax = xInZone + xTolWS;
-    //   }
-    //   debug_cout << "\t after WS treatment: xMin = " << xMin << ", xMax = " << xMax << std::endl;
-    // }
-
-    // Get the hits within the bounds
-    assert(iZone < SciFi::Constants::n_layers);
-    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
-    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
-    int x_zone_offset_end = x_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
-    const int itH = getLowerBound(scifi_hits.x0, xMin, x_zone_offset_begin, x_zone_offset_end);
-    const int itEnd = getLowerBound(scifi_hits.x0, xMax, x_zone_offset_begin, x_zone_offset_end);
-    assert(itH >= x_zone_offset_begin && itH <= x_zone_offset_end);
-    assert(itEnd >= x_zone_offset_begin && itEnd <= x_zone_offset_end);
-
-    windows_x[2*izone_rel] = itH;
-    windows_x[2*izone_rel+1] = itEnd - itH;
-
-    // Now match the stereo hits
-    const float this_uv_z = constArrays->uvZone_zPos[izone_rel];
-    const float dz_uv = this_uv_z - SciFi::Tracking::zReference;
-    const float yInUVZone = yFromVelo(this_uv_z, velo_state);
-    const float dx = yInUVZone * constArrays->uvZone_dxdy[izone_rel];
-    const float xPredUv = scifi_propagation(state_zRef.x, UT_state.tx, qOverP, dz_uv) - dx;
-    const int uv_layer = constArrays->uvZones[iZone] / 2;
-    // To Do: study this window
-    const float xBound = 70.f * window_params.extrapolation_stddev[uv_layer];
-    const float maxDx = xBound; // * ratio;
-
-    const float xMinUV = xPredUv - maxDx;
-    const float xMaxUV = xPredUv + maxDx;
-
-    // Get bounds in UV layers
-    // do one search on the same side as the x module
-    // if we are close to y = 0, also look within a region on the other side module ("triangle search")
-    assert(constArrays->uvZones[iZone] < SciFi::Constants::n_zones);
-    const int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[iZone]);
-    const int uv_zone_offset_end =
-      uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone]);
-    /* OPTIMIZE: check how large the effect on the efficiency is to include the triangle hits */
-    //    const int triangleOffset = side > 0 ? -1 : 1;
-    //assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
-    // const int triangle_zone_offset_begin =
-    //   scifi_hit_count.zone_offset(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
-    // assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
-    // const int triangle_zone_offset_end =
-    //   triangle_zone_offset_begin +
-    //   scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
-    int itUVStart = getLowerBound(scifi_hits.x0, xMinUV, uv_zone_offset_begin, uv_zone_offset_end);
-    int itUVEnd = getLowerBound(scifi_hits.x0, xMaxUV, uv_zone_offset_begin, uv_zone_offset_end);
-    //    int itUV2 = getLowerBound(scifi_hits.x0, xMinUV, triangle_zone_offset_begin, triangle_zone_offset_end);
-
-    windows_uv[2*izone_rel] = itUVStart;
-    windows_uv[2*izone_rel+1] = itUVEnd;
-
-  }
-}
-
-__host__ void collectAllXHits_proto(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const float qOverP,
-  int side,
-  std::array<int, 2 * 6>& windows_x,
-  std::array<int, 2 * 6>& windows_uv,
-  std::array<float, 4 * 6>& parameters_uv)
-{
-  // Find size of search window on reference plane, using Velo slopes and min pT as input
-  float dxRef = 0.9f * calcDxRef(SciFi::Tracking::minPt, velo_state);
-  // find position within magnet where bending happens
-  float zMag = zMagnet(velo_state, constArrays);
-
-  const float q = qOverP > 0.f ? 1.f : -1.f;
-  const float dir = q * magnet_polarity * (-1.f);
-
-  float slope2 = velo_state.tx * velo_state.tx + velo_state.ty * velo_state.ty;
-  const float pt = std::sqrt(slope2 / (1.f + slope2)) / std::abs(qOverP);
-  const bool wSignTreatment = SciFi::Tracking::useWrongSignWindow && pt > SciFi::Tracking::wrongSignPT;
-
-  float dxRefWS = 0.f;
-  if (wSignTreatment) {
-    dxRefWS = 0.9f * calcDxRef(
-                       SciFi::Tracking::wrongSignPT,
-                       velo_state); // make windows a bit too small - FIXME check effect of this, seems wrong
-  }
-
-  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
-
-  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
-    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
-    assert(iZone - iZoneStartingPoint < 12);
-
-    const auto izone_rel = iZone - iZoneStartingPoint;
-    const float zZone = constArrays->xZone_zPos[izone_rel];
-    const float xInZone = evalCubicParameterization(xParams_seed, zZone);
-    const float yInZone = evalCubicParameterization(yParams_seed, zZone);
-
-    // Now the code checks if the x and y are in the zone limits. I am really not sure
-    // why this is done here, surely could just check if within limits for the last zone
-    // in T3 and go from there? Need to think more about this.
-    //
-    // Here for now I assume the same min/max x and y for all stations, this again needs to
-    // be read from some file blablabla although actually I suspect having some general tolerances
-    // here is anyway good enough since we are doing a straight line extrapolation in the first place
-    // check (roughly) whether the extrapolated velo track is within the current zone
-    // if (side > 0) {
-    //   if (
-    //     !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-    //     !isInside(yInZone, SciFi::Tracking::yLim_Min, SciFi::Tracking::yLim_Max))
-    //     continue;
-    // }
-    // else {
-    //   if (
-    //     !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-    //     !isInside(yInZone, side * SciFi::Tracking::yLim_Max, side * SciFi::Tracking::yLim_Min))
-    //     continue;
-    // }
-
-    // extrapolate dxRef (x window on reference plane) to plane of current zone
-    const float xTol = (zZone < SciFi::Tracking::zReference) ?
-                         dxRef * zZone / SciFi::Tracking::zReference :
-                         dxRef * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-    float xMin = xInZone - xTol;
-    float xMax = xInZone + xTol;
-
-    if (SciFi::Tracking::useMomentumEstimate) { // For VeloUT tracks, suppress check if track actually has qOverP set,
-                                                // get the option right!
-      float xTolWS = 0.0;
-      if (wSignTreatment) {
-        xTolWS = (zZone < SciFi::Tracking::zReference) ?
-                   dxRefWS * zZone / SciFi::Tracking::zReference :
-                   dxRefWS * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-      }
-      if (dir > 0) {
-        xMin = xInZone - xTolWS;
-      }
-      else {
-        xMax = xInZone + xTolWS;
-      }
-    }
-
-    // Get the hits within the bounds
-    assert(iZone < SciFi::Constants::n_layers);
-    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
-    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
-    int x_zone_size = scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
-    int itH = binary_search_leftmost(scifi_hits.x0 + x_zone_offset_begin, x_zone_size, xMin);
-    const int itSize = binary_search_leftmost(scifi_hits.x0 + x_zone_offset_begin + itH, x_zone_size - itH, xMax);
-    itH += x_zone_offset_begin;
-
-    windows_x[2 * izone_rel] = itH;
-    windows_x[2 * izone_rel + 1] = itSize;
-
-    // Skip making range but continue if the size is zero
-    if (itSize == 0) continue;
-
-    // Now match the stereo hits
-    const float this_uv_z = constArrays->uvZone_zPos[iZone - iZoneStartingPoint];
-    const float xInUv = evalCubicParameterization(xParams_seed, this_uv_z);
-    const float zRatio = (this_uv_z - zMag) / (zZone - zMag);
-    const float dx = yInZone * constArrays->uvZone_dxdy[iZone - iZoneStartingPoint];
-    const float xCentral = xInZone + dx;
-    const float xPredUv = xInUv + (scifi_hits.x0[itH] - xInZone) * zRatio - dx;
-    const float maxDx = SciFi::Tracking::tolYCollectX +
-                        (fabsf(scifi_hits.x0[itH] - xCentral) + fabsf(yInZone)) * SciFi::Tracking::tolYSlopeCollectX;
-    const float xMinUV = xPredUv - maxDx;
-
-    // Get bounds in UV layers
-    // do one search on the same side as the x module
-    // if we are close to y = 0, also look within a region on the other side module ("triangle search")
-    assert(constArrays->uvZones[iZone] < SciFi::Constants::n_zones);
-    const int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[iZone]);
-    const int uv_zone_size = scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone]);
-    const int itUV1 = binary_search_leftmost(scifi_hits.x0 + uv_zone_offset_begin, uv_zone_size, xMinUV);
-
-    const float xPredUVProto = xInUv - xInZone * zRatio - dx;
-    const float maxDxProto = SciFi::Tracking::tolYCollectX + fabsf(yInZone) * SciFi::Tracking::tolYSlopeCollectX;
-
-    windows_uv[2 * izone_rel] = itUV1 + uv_zone_offset_begin;
-    windows_uv[2 * izone_rel + 1] = uv_zone_size - itUV1;
-
-    parameters_uv[4 * izone_rel] = xPredUVProto;
-    parameters_uv[4 * izone_rel + 1] = zRatio;
-    parameters_uv[4 * izone_rel + 2] = maxDxProto;
-    parameters_uv[4 * izone_rel + 3] = xCentral;
-  }
-}
-
-//=========================================================================
-// From LHCb Forward tracking description
-//
-// Collect all X hits, within a window defined by the minimum Pt.
-// Better restrictions possible, if we use the momentum of the input track.
-// Ask for the presence of a stereo hit in the same biLayer compatible.
-// This reduces the efficiency. X-alone hits to be re-added later in the processing
-//
-// side = 1  -> upper y half
-// side = -1 -> lower y half
-//=========================================================================
-//
-__host__ __device__ void collectAllXHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int& n_x_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const float qOverP,
-  int side)
-{
-  // Find size of search window on reference plane, using Velo slopes and min pT as input
-  float dxRef = 0.9f * calcDxRef(SciFi::Tracking::minPt, velo_state);
-  // find position within magnet where bending happens
-  float zMag = zMagnet(velo_state, constArrays);
-
-  const float q = qOverP > 0.f ? 1.f : -1.f;
-  const float dir = q * magnet_polarity * (-1.f);
-
-  float slope2 = velo_state.tx * velo_state.tx + velo_state.ty * velo_state.ty;
-  const float pt = std::sqrt(slope2 / (1.f + slope2)) / std::abs(qOverP);
-  const bool wSignTreatment = SciFi::Tracking::useWrongSignWindow && pt > SciFi::Tracking::wrongSignPT;
-
-  float dxRefWS = 0.f;
-  if (wSignTreatment) {
-    // DvB: what happens if we use the actual momentum from VeloUT here instead of a constant?
-    dxRefWS = 0.9f * calcDxRef(
-                       SciFi::Tracking::wrongSignPT,
-                       velo_state); // make windows a bit too small - FIXME check effect of this, seems wrong
-  }
-
-  int iZoneEnd[7]; // 6 x planes
-  iZoneEnd[0] = 0;
-  int cptZone = 1;
-
-  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
-
-  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
-    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
-    assert(iZone - iZoneStartingPoint < 12);
-    const float zZone = constArrays->xZone_zPos[iZone - iZoneStartingPoint];
-    const float xInZone = evalCubicParameterization(xParams_seed, zZone);
-    const float yInZone = evalCubicParameterization(yParams_seed, zZone);
-
-    // Now the code checks if the x and y are in the zone limits. I am really not sure
-    // why this is done here, surely could just check if within limits for the last zone
-    // in T3 and go from there? Need to think more about this.
-    //
-    // Here for now I assume the same min/max x and y for all stations, this again needs to
-    // be read from some file blablabla although actually I suspect having some general tolerances
-    // here is anyway good enough since we are doing a straight line extrapolation in the first place
-    // check (roughly) whether the extrapolated velo track is within the current zone
-    if (side > 0) {
-      if (
-        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-        !isInside(yInZone, SciFi::Tracking::yLim_Min, SciFi::Tracking::yLim_Max))
-        continue;
-    }
-    else {
-      if (
-        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-        !isInside(yInZone, side * SciFi::Tracking::yLim_Max, side * SciFi::Tracking::yLim_Min))
-        continue;
-    }
-
-    // extrapolate dxRef (x window on reference plane) to plane of current zone
-    const float xTol = (zZone < SciFi::Tracking::zReference) ?
-                         dxRef * zZone / SciFi::Tracking::zReference :
-                         dxRef * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-    float xMin = xInZone - xTol;
-    float xMax = xInZone + xTol;
-
-    if (SciFi::Tracking::useMomentumEstimate) { // For VeloUT tracks, suppress check if track actually has qOverP set,
-                                                // get the option right!
-      float xTolWS = 0.0;
-      if (wSignTreatment) {
-        xTolWS = (zZone < SciFi::Tracking::zReference) ?
-                   dxRefWS * zZone / SciFi::Tracking::zReference :
-                   dxRefWS * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-      }
-      if (dir > 0) {
-        xMin = xInZone - xTolWS;
-      }
-      else {
-        xMax = xInZone + xTolWS;
-      }
-    }
-
-    // Get the hits within the bounds
-    assert(iZone < SciFi::Constants::n_layers);
-    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
-    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
-    int x_zone_offset_end = x_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
-    const int itH = getLowerBound(scifi_hits.x0, xMin, x_zone_offset_begin, x_zone_offset_end);
-    const int itEnd = getLowerBound(scifi_hits.x0, xMax, x_zone_offset_begin, x_zone_offset_end);
-    assert(itH >= x_zone_offset_begin && itH <= x_zone_offset_end);
-    assert(itEnd >= x_zone_offset_begin && itEnd <= x_zone_offset_end);
-
-    // Skip making range but continue if the end is before or equal to the start
-    if (!(itEnd > itH)) continue;
-
-    // Now match the stereo hits
-    const float this_uv_z = constArrays->uvZone_zPos[iZone - iZoneStartingPoint];
-    const float xInUv = evalCubicParameterization(xParams_seed, this_uv_z);
-    const float zRatio = (this_uv_z - zMag) / (zZone - zMag);
-    const float dx = yInZone * constArrays->uvZone_dxdy[iZone - iZoneStartingPoint];
-    const float xCentral = xInZone + dx;
-    const float xPredUv = xInUv + (scifi_hits.x0[itH] - xInZone) * zRatio - dx;
-    const float maxDx = SciFi::Tracking::tolYCollectX +
-                        (fabsf(scifi_hits.x0[itH] - xCentral) + fabsf(yInZone)) * SciFi::Tracking::tolYSlopeCollectX;
-    const float xMinUV = xPredUv - maxDx;
-
-    // Get bounds in UV layers
-    // do one search on the same side as the x module
-    // if we are close to y = 0, also look within a region on the other side module ("triangle search")
-    assert(constArrays->uvZones[iZone] < SciFi::Constants::n_zones);
-    const int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[iZone]);
-    const int uv_zone_offset_end =
-      uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone]);
-    const int triangleOffset = side > 0 ? -1 : 1;
-    assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
-    const int triangle_zone_offset_begin =
-      scifi_hit_count.zone_offset(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
-    assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
-    const int triangle_zone_offset_end =
-      triangle_zone_offset_begin +
-      scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
-    int itUV1 = getLowerBound(scifi_hits.x0, xMinUV, uv_zone_offset_begin, uv_zone_offset_end);
-    int itUV2 = getLowerBound(scifi_hits.x0, xMinUV, triangle_zone_offset_begin, triangle_zone_offset_end);
-
-    const float xPredUVProto = xInUv - xInZone * zRatio - dx;
-    const float maxDxProto = SciFi::Tracking::tolYCollectX + fabsf(yInZone) * SciFi::Tracking::tolYSlopeCollectX;
-
-    const bool withTriangleSearch = fabsf(yInZone) < SciFi::Tracking::tolYTriangleSearch;
-    for (int xHit = itH; xHit < itEnd; ++xHit) { // loop over all xHits in a layer between xMin and xMax
-      const float xPredUv = xPredUVProto + scifi_hits.x0[xHit] * zRatio;
-      const float maxDx = maxDxProto + fabsf(scifi_hits.x0[xHit] - xCentral) * SciFi::Tracking::tolYSlopeCollectX;
-      const float xMinUV = xPredUv - maxDx;
-      const float xMaxUV = xPredUv + maxDx;
-
-      if (
-        matchStereoHit(itUV1, uv_zone_offset_end, scifi_hits, xMinUV, xMaxUV) //) {
-        || (withTriangleSearch &&
-            matchStereoHitWithTriangle(itUV2, triangle_zone_offset_end, yInZone, scifi_hits, xMinUV, xMaxUV, side))) {
-        if (n_x_hits >= SciFi::Tracking::max_x_hits) break;
-        assert(n_x_hits < SciFi::Tracking::max_x_hits);
-        allXHits[n_x_hits++] = xHit;
-      }
-    }
-
-    const int iStart = iZoneEnd[cptZone - 1];
-    const int iEnd = n_x_hits;
-
-    assert(cptZone < 7);
-    iZoneEnd[cptZone++] = iEnd;
-
-    // project x of all hits to reference plane
-    // save it in coordX
-    // -> first step of 1D Hough transform,
-    // select clusters of x hits on reference plane in selectXCandidates
-    if (iStart < iEnd) {
-      xAtRef_SamePlaneHits(
-        scifi_hits, allXHits, n_x_hits, coordX, xParams_seed, constArrays, velo_state, zMag, iStart, iEnd);
-    }
-    if (n_x_hits >= SciFi::Tracking::max_x_hits) break;
-  }
-
-  // Sort hits by x on reference plane
-  // not using thrust::sort due to "temporary_buffer::allocate: get_temporary_buffer failed" error
-  // every time thrust::sort is called, cudaMalloc is called, apparently there can be trouble
-  // doing this many times
-  // thrust::sort_by_key(thrust::seq, coordX, coordX + n_x_hits, allXHits);
-  sortHitsByKey<SciFi::Tracking::max_x_hits>(coordX, n_x_hits, allXHits);
-}
-
-__host__ __device__ void improveXCluster(
-  int& it2,
-  const int it1,
-  const int itEnd,
-  const int n_x_hits,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const float xWindow,
-  const SciFi::Tracking::HitSearchCuts& pars,
-  PlaneCounter& planeCounter,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits)
-{
-
-  int itLast = it2 - 1;
-  while (it2 < itEnd) {
-    assert(it2 < n_x_hits);
-    if (usedHits[it2]) {
-      ++it2;
-      continue;
-    }
-    // now  the first and last+1 hit exist and are not used!
-
-    // Add next hit,
-    // if there is only a small gap between the hits
-    //    or inside window and plane is still empty
-    assert(it2 < itEnd);
-    if (
-      (coordX[it2] < coordX[itLast] + pars.maxXGap) ||
-      ((coordX[it2] - coordX[it1] < xWindow) &&
-       (planeCounter.nbInPlane(scifi_hits.planeCode(allXHits[it2]) / 2) == 0))) {
-      planeCounter.addHit(scifi_hits.planeCode(allXHits[it2]) / 2);
-      itLast = it2;
-      ++it2;
-      continue;
-    }
-    // Found nothing to improve
-    else {
-      break;
-    }
-  }
-}
-
-//=========================================================================
-//  Select the zones in the allXHits array where we can have a track
-//=========================================================================
-__host__ __device__ void selectXCandidates(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int& n_x_hits,
-  bool usedHits[SciFi::Tracking::max_x_hits],
-  float coordX[SciFi::Tracking::max_x_hits],
-  SciFi::Tracking::Track candidate_tracks[SciFi::Tracking::max_candidate_tracks],
-  int& n_candidate_tracks,
-  const float zRef_track,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::Arrays* constArrays,
-  int side,
-  const bool secondLoop)
-{
-  if (n_x_hits < pars.minXHits) return;
-  if (secondLoop)
-    if (n_candidate_tracks >= SciFi::Tracking::max_tracks_second_loop) return;
-  if (!secondLoop)
-    if (n_candidate_tracks >= SciFi::Tracking::max_candidate_tracks) return;
-
-  int itEnd = n_x_hits;
-  const float xTrack = evalCubicParameterization(xParams_seed, SciFi::Tracking::zReference);
-  int it1 = 0;
-  int it2 = 0;
-  pars.minStereoHits = 0;
-
-  PlaneCounter planeCounter;
-
-  while (it1 < itEnd) {
-    // find next unused Hits
-    assert(it1 < n_x_hits);
-    while (it1 + pars.minXHits - 1 < itEnd && usedHits[it1]) {
-      ++it1;
-    }
-
-    it2 = it1 + pars.minXHits;
-    if (it2 > itEnd) break;
-    assert(it2 - 1 < n_x_hits);
-    while (it2 <= itEnd && usedHits[it2 - 1])
-      ++it2;
-    if (it2 > itEnd) break;
-
-    // Second part of 1D Hough transform:
-    // find a cluster of x positions on the reference plane that are close to each other
-    // TODO better xWindow calculation?? how to tune this???
-    const float xWindow = pars.maxXWindow + (fabsf(coordX[it1]) + fabsf(coordX[it1] - xTrack)) * pars.maxXWindowSlope;
-
-    if ((coordX[it2 - 1] - coordX[it1]) > xWindow) {
-      ++it1;
-      continue;
-    }
-
-    // find out which planes are present in the cluster
-    countPlanesOfXHits(planeCounter, it1, it2, n_x_hits, allXHits, usedHits, scifi_hits);
-
-    // Improve cluster (at the moment only add hits to the right)
-    // to recover inefficiencies from requiring a stereo hit to
-    // be matched to an x-hit in the collectXHits step
-    improveXCluster(it2, it1, itEnd, n_x_hits, usedHits, coordX, xWindow, pars, planeCounter, allXHits, scifi_hits);
-
-    // if not enough different planes, start again from the very beginning with next right hit
-    if (planeCounter.nbDifferent < pars.minXHits) {
-      ++it1;
-      continue;
-    }
-
-    //  Now we have a (rather) clean candidate, do best hit selection
-    SciFi::Tracking::LineFitterPars lineFitParameters;
-    lineFitParameters.m_z0 = SciFi::Tracking::zReference;
-    float xAtRef = 0.;
-    const unsigned int nbSingle = planeCounter.nbSingle();
-    int coordToFit[SciFi::Tracking::max_coordToFit];
-    int n_coordToFit = 0;
-    // 1) If there are enough planes with only one hit, do a straight
-    //    line fit through these and select good matching others
-    if (nbSingle >= SciFi::Tracking::minSingleHits && nbSingle != planeCounter.nbDifferent) {
-      // 1) we have enough single planes (thus two) to make a straight line fit
-      int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits] = {0};
-      int nOtherHits[SciFi::Constants::n_layers] = {0};
-
-      // fit hits on planes with only one hit
-      // save the other hits in separate array
-      fitHitsFromSingleHitPlanes(
-        it1,
-        it2,
-        usedHits,
-        scifi_hits,
-        allXHits,
-        n_x_hits,
-        planeCounter,
-        lineFitParameters,
-        coordX,
-        otherHits,
-        nOtherHits);
-
-      // select best other hits (only best other hit is enough!)
-      // include them in fit
-      addAndFitHitsFromMultipleHitPlanes(nOtherHits, lineFitParameters, scifi_hits, coordX, allXHits, otherHits);
-
-      xAtRef = lineFitParameters.m_c0;
-    }
-    //  2) Try to find a cluster on the reference plane with a maximal
-    //     spread and from a minimum # of different planes
-    else {
-      // 2) Try to find a small distance containing at least 5(4) different planes
-      //    Most of the time do nothing
-      const unsigned int nPlanes = fminf(planeCounter.nbDifferent, uint {5});
-      int itWindowStart = it1;
-      int itWindowEnd = it1 + nPlanes; // pointing at last+1
-      // Hit is used, go to next unused one
-      while (itWindowEnd <= it2 && usedHits[itWindowEnd - 1] && (itWindowEnd - 1) < n_x_hits)
-        ++itWindowEnd;
-      int best = itWindowStart;
-      int bestEnd = itWindowEnd;
-
-      PlaneCounter lplaneCounter;
-      countUnusedXHitsOnPlanes(lplaneCounter, itWindowStart, itWindowEnd, n_x_hits, allXHits, usedHits, scifi_hits);
-
-      // modify itWindowStart and itWindowEnd while adding more x hits
-      // set best and bestEnd to include cluster of x hits on reference plane within minInterval
-      float minInterval = 1.f;
-      addXHitsForCandidateWithTooFewPlanes(
-        itWindowStart,
-        itWindowEnd,
-        it2,
-        itEnd,
-        minInterval,
-        lplaneCounter,
-        nPlanes,
-        coordX,
-        best,
-        bestEnd,
-        usedHits,
-        n_x_hits,
-        allXHits,
-        scifi_hits);
-
-      // TODO tune minInterval cut value
-      if (minInterval < 1.f) {
-        it1 = best;
-        it2 = bestEnd;
-      }
-
-      // Fill coordToFit and compute xAtRef (average x position on reference plane)
-      collectXHitsToFit(it1, it2, n_x_hits, allXHits, usedHits, coordToFit, n_coordToFit, coordX, xAtRef);
-
-    } // end of magical second part
-    //=== We have a candidate :)
-
-    planeCounter.clear();
-    for (int j = 0; j < n_coordToFit; ++j) {
-      planeCounter.addHit(scifi_hits.planeCode(coordToFit[j]) / 2);
-    }
-
-    // Only unused(!) hits in coordToFit now
-    bool ok = planeCounter.nbDifferent > 3;
-    float trackParameters[SciFi::Tracking::nTrackParams];
-    if (ok) {
-      getTrackParameters(xAtRef, velo_state, constArrays, trackParameters);
-      // Track described by cubic function in (z-zRef), but only first two terms are adjusted
-      // during fitting procedure -> linear fit
-      // nb: usedHits are currently not un-marked when removing ourliers
-      fastLinearFit(scifi_hits, trackParameters, coordToFit, n_coordToFit, planeCounter, pars);
-      // to do: do we have to mark these as used as well?
-      addHitsOnEmptyXLayers(
-        scifi_hits,
-        scifi_hit_count,
-        trackParameters,
-        xParams_seed,
-        yParams_seed,
-        false,
-        coordToFit,
-        n_coordToFit,
-        constArrays,
-        planeCounter,
-        pars,
-        side);
-
-      ok = planeCounter.nbDifferent > 3;
-    }
-    // == Fit and remove hits...
-    // track described by cubic function, but fitting only first three parameters here
-    // -> quadratic fit
-    // to do: remove outlier from usedHits
-    if (ok) ok = quadraticFitX(scifi_hits, trackParameters, coordToFit, n_coordToFit, planeCounter, pars);
-    if (ok) ok = trackParameters[7] / trackParameters[8] < SciFi::Tracking::maxChi2PerDoF;
-    if (ok)
-      ok = addHitsOnEmptyXLayers(
-        scifi_hits,
-        scifi_hit_count,
-        trackParameters,
-        xParams_seed,
-        yParams_seed,
-        true,
-        coordToFit,
-        n_coordToFit,
-        constArrays,
-        planeCounter,
-        pars,
-        side);
-    if (ok) {
-      // save track properties in track object
-      SciFi::Tracking::Track track;
-      track.chi2 = trackParameters[7];
-      for (int k = 0; k < 7; ++k) {
-        track.trackParams[k] = trackParameters[k];
-      }
-
-      for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-        int hit = coordToFit[i_hit];
-        assert(track.hitsNum < SciFi::Tracking::max_scifi_hits);
-        track.addHit(hit);
-      }
-      if (!secondLoop) {
-        assert(n_candidate_tracks < SciFi::Tracking::max_candidate_tracks);
-        candidate_tracks[n_candidate_tracks++] = track;
-      }
-      else if (secondLoop) {
-        assert(n_candidate_tracks < SciFi::Tracking::max_tracks_second_loop);
-        candidate_tracks[n_candidate_tracks++] = track;
-      }
-    }
-    if (secondLoop) {
-      if (n_candidate_tracks >= SciFi::Tracking::max_tracks_second_loop) break;
-      assert(n_candidate_tracks < SciFi::Tracking::max_tracks_second_loop);
-    }
-    else if (!secondLoop) {
-      if (n_candidate_tracks >= SciFi::Tracking::max_candidate_tracks) break;
-      assert(n_candidate_tracks < SciFi::Tracking::max_candidate_tracks);
-    }
-
-    ++it1;
-  }
-}
-
-__host__ __device__ bool addHitsOnEmptyXLayers(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  bool fullFit,
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  const SciFi::Tracking::Arrays* constArrays,
-  PlaneCounter& planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars,
-  int side)
-{
-  // is there an empty plane? otherwise skip here!
-  if (planeCounter.nbDifferent > 11) return true;
-  bool added = false;
-  const float x1 = trackParameters[0]; // mean xRef of this candidate
-  const float xAtRefFromSeed = evalCubicParameterization(xParams_seed, SciFi::Tracking::zReference);
-  const float xWindow = pars.maxXWindow + (fabsf(x1) + fabsf(x1 - xAtRefFromSeed)) * pars.maxXWindowSlope;
-
-  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
-
-  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
-    assert(constArrays->xZones[iZone] / 2 < SciFi::Constants::n_layers);
-    if (planeCounter.nbInPlane(constArrays->xZones[iZone] / 2) != 0) continue;
-
-    const float parsX[4] = {trackParameters[0], trackParameters[1], trackParameters[2], trackParameters[3]};
-
-    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
-    const float zZone = constArrays->xZone_zPos[iZone - iZoneStartingPoint];
-    // predicted x position on this plane based on current candidate
-    const float xPred = evalCubicParameterization(parsX, zZone);
-    const float minX = xPred - xWindow;
-    const float maxX = xPred + xWindow;
-
-    // -- Use a search to find the lower bound of the range of x values
-    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
-    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
-    int x_zone_offset_end = x_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
-    int itH = getLowerBound(scifi_hits.x0, minX, x_zone_offset_begin, x_zone_offset_end);
-    int itEnd = x_zone_offset_end;
-
-    int best = findBestXHitOnEmptyLayer(itEnd, itH, scifi_hits, maxX, xPred);
-
-    if (best > -1) {
-      if (n_coordToFit >= SciFi::Tracking::max_coordToFit) break;
-      assert(n_coordToFit < SciFi::Tracking::max_coordToFit);
-      coordToFit[n_coordToFit++] = best; // add the best hit here
-      planeCounter.addHit(scifi_hits.planeCode(best) / 2);
-      added = true;
-    }
-  }
-  if (!added) return true;
-  if (fullFit) {
-    return quadraticFitX(scifi_hits, trackParameters, coordToFit, n_coordToFit, planeCounter, pars);
-  }
-  fastLinearFit(scifi_hits, trackParameters, coordToFit, n_coordToFit, planeCounter, pars);
-  return true;
-}
diff --git a/cuda/SciFi/PrForward/src/HitUtils.cu b/cuda/SciFi/PrForward/src/HitUtils.cu
deleted file mode 100644
index d0de6e2d17d..00000000000
--- a/cuda/SciFi/PrForward/src/HitUtils.cu
+++ /dev/null
@@ -1,324 +0,0 @@
-#include "HitUtils.cuh"
-
-// match stereo hits to x hits
-__host__ __device__ bool matchStereoHit(
-  const int itUV1,
-  const int uv_zone_offset_end,
-  const SciFi::Hits& scifi_hits,
-  const float xMinUV,
-  const float xMaxUV)
-{
-  for (int stereoHit = itUV1; stereoHit != uv_zone_offset_end; ++stereoHit) {
-    if (scifi_hits.x0[stereoHit] > xMinUV) {
-      return (scifi_hits.x0[stereoHit] < xMaxUV);
-    }
-  }
-  return false;
-}
-
-// match stereo hits to x hits using triangle method
-__host__ __device__ bool matchStereoHitWithTriangle(
-  const int itUV2,
-  const int triangle_zone_offset_end,
-  const float yInZone,
-  const SciFi::Hits& scifi_hits,
-  const float xMinUV,
-  const float xMaxUV,
-  const int side)
-{
-
-  for (int stereoHit = itUV2; stereoHit != triangle_zone_offset_end; ++stereoHit) {
-    if (scifi_hits.x0[stereoHit] > xMinUV) {
-      // Triangle search condition depends on side
-      if (side > 0) { // upper
-        if (scifi_hits.yMax(stereoHit) > yInZone - SciFi::Tracking::yTolUVSearch) {
-          return true;
-        }
-      }
-      else { // lower
-        if (scifi_hits.yMin(stereoHit) < yInZone + SciFi::Tracking::yTolUVSearch) {
-          return true;
-        }
-      }
-    }
-  }
-  return false;
-}
-
-__host__ __device__ void removeOutlier(
-  const SciFi::Hits& scifi_hits,
-  PlaneCounter& planeCounter,
-  int* coordToFit,
-  int& n_coordToFit,
-  const int worst)
-{
-  planeCounter.removeHit(scifi_hits.planeCode(worst) / 2);
-  int coordToFit_temp[SciFi::Tracking::max_stereo_hits];
-  int i_hit_temp = 0;
-  for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-    int hit = coordToFit[i_hit];
-    if (hit != worst) coordToFit_temp[i_hit_temp++] = hit;
-  }
-  n_coordToFit = i_hit_temp;
-  for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-    coordToFit[i_hit] = coordToFit_temp[i_hit];
-  }
-}
-
-__host__ __device__ void countPlanesOfXHits(
-  PlaneCounter& planeCounter,
-  const int it1,
-  const int it2,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits)
-{
-
-  planeCounter.clear();
-  for (int itH = it1; itH != it2; ++itH) {
-    assert(itH < n_x_hits);
-    if (!usedHits[itH]) {
-      const int plane = scifi_hits.planeCode(allXHits[itH]) / 2;
-      planeCounter.addHit(plane);
-    }
-  }
-}
-
-__host__ __device__ void countUnusedXHitsOnPlanes(
-  PlaneCounter& lplaneCounter,
-  const int itWindowStart,
-  const int itWindowEnd,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits)
-{
-  for (int itH = itWindowStart; itH != itWindowEnd; ++itH) {
-    assert(itH < n_x_hits);
-    if (!usedHits[itH]) {
-      lplaneCounter.addHit(scifi_hits.planeCode(allXHits[itH]) / 2);
-    }
-  }
-}
-
-__host__ __device__ void addXHitsForCandidateWithTooFewPlanes(
-  int& itWindowStart,
-  int& itWindowEnd,
-  const int it2,
-  const int itEnd,
-  float& minInterval,
-  PlaneCounter& lplaneCounter,
-  const int nPlanes,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  int& best,
-  int& bestEnd,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits)
-{
-
-  while (itWindowEnd <= it2) {
-    if (lplaneCounter.nbDifferent >= nPlanes) {
-      // have nPlanes, check x distance
-      assert(itWindowEnd - 1 < SciFi::Tracking::max_x_hits);
-      assert(itWindowStart < SciFi::Tracking::max_x_hits);
-      const float dist = coordX[itWindowEnd - 1] - coordX[itWindowStart];
-      if (dist < minInterval) {
-        minInterval = dist;
-        best = itWindowStart;
-        bestEnd = itWindowEnd;
-      }
-    }
-    else {
-      // too few planes, add one hit
-      ++itWindowEnd;
-      if (itWindowEnd > it2) break;
-      assert(itWindowEnd <= n_x_hits);
-      while (itWindowEnd <= it2 && usedHits[itWindowEnd - 1] && itWindowEnd <= n_x_hits)
-        ++itWindowEnd;
-      lplaneCounter.addHit(scifi_hits.planeCode(allXHits[itWindowEnd - 1]) / 2);
-      continue;
-    }
-    // move on to the right
-
-    lplaneCounter.removeHit(scifi_hits.planeCode(allXHits[itWindowStart]) / 2);
-    ++itWindowStart;
-    assert(itWindowStart < itEnd);
-    while (itWindowStart < itWindowEnd && usedHits[itWindowStart] && itWindowStart < n_x_hits)
-      ++itWindowStart;
-    // last hit guaranteed to be not used. Therefore there is always at least one hit to go to. No additional if
-    // required.
-  }
-}
-
-__host__ __device__ void collectXHitsToFit(
-  const int it1,
-  const int it2,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  bool usedHits[SciFi::Tracking::max_x_hits],
-  int coordToFit[SciFi::Tracking::max_x_hits],
-  int& n_coordToFit,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  float& xAtRef)
-{
-
-  for (int itH = it1; it2 != itH; ++itH) {
-    assert(itH < n_x_hits);
-    if (!usedHits[itH]) {
-      if (n_coordToFit >= SciFi::Tracking::max_coordToFit) break;
-      coordToFit[n_coordToFit++] = allXHits[itH];
-      usedHits[itH] = true;
-      xAtRef += coordX[itH];
-    }
-  }
-  xAtRef /= ((float) n_coordToFit);
-}
-
-__host__ __device__ int findBestXHitOnEmptyLayer(
-  const int itEnd,
-  const int itBegin,
-  const SciFi::Hits& scifi_hits,
-  const float maxX,
-  const float xPred)
-{
-
-  float bestChi2 = 1.e9f;
-  int best = -1;
-  for (int itH = itBegin; itEnd != itH; ++itH) {
-    if (scifi_hits.x0[itH] > maxX) break;
-    const float d = scifi_hits.x0[itH] - xPred; // fast distance good enough at this point (?!)
-    const float chi2 = d * d * scifi_hits.w(itH);
-    if (chi2 < bestChi2) {
-      bestChi2 = chi2;
-      best = itH;
-    }
-  }
-  return best;
-}
-
-__host__ __device__ void findStereoHitsWithinXTol(
-  const int itBegin,
-  const int itEnd,
-  const SciFi::Hits& scifi_hits,
-  const float yZone,
-  const float xPred,
-  const float dxTol,
-  const bool triangleSearch,
-  const float dxDySign,
-  int& n_stereoHits,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits])
-{
-
-  for (int itH = itBegin; itEnd != itH; ++itH) {
-    const float dx = scifi_hits.x0[itH] + yZone * scifi_hits.dxdy(itH) - xPred;
-    if (dx > dxTol) break;
-    if (triangleSearch) {
-      if (yZone > scifi_hits.yMax(itH) + SciFi::Tracking::yTolUVSearch) continue;
-      if (yZone < scifi_hits.yMin(itH) - SciFi::Tracking::yTolUVSearch) continue;
-    }
-    if (n_stereoHits >= SciFi::Tracking::max_stereo_hits) break;
-    assert(n_stereoHits < SciFi::Tracking::max_stereo_hits);
-    stereoHits[n_stereoHits] = itH;
-    stereoCoords[n_stereoHits++] = dx * dxDySign;
-  }
-}
-
-// find cluster of stereo hits with certain number of hits from different planes
-// and similar dx value (stored in stereoCoords)
-__host__ __device__ void findStereoHitClusterByDx(
-  PlaneCounter& planeCounter,
-  int& endRange,
-  const SciFi::Tracking::HitSearchCuts& pars,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  const int n_stereoHits,
-  const SciFi::Hits& scifi_hits,
-  float& sumCoord,
-  int& first_hit)
-{
-
-  while (planeCounter.nbDifferent < pars.minStereoHits ||
-         stereoCoords[endRange] < stereoCoords[first_hit] + SciFi::Tracking::minYGap && endRange < n_stereoHits - 1) {
-    planeCounter.addHit(scifi_hits.planeCode(stereoHits[endRange]) / 2);
-    sumCoord += stereoCoords[endRange];
-    ++endRange;
-    if (endRange == n_stereoHits - 1) break;
-    first_hit = endRange - 1;
-  }
-}
-
-// - remove hits on planes with more than one hit if
-//   the hit is farthest away from the mean
-// - add hit if no hit on that plane is present in the cluster yet
-//   and if the cluster spread is reduced by adding the hit
-__host__ __device__ void cleanStereoHitCluster(
-  int& beginRange,
-  int& endRange,
-  const int n_stereoHits,
-  const int stereoHits[SciFi::Tracking::max_stereo_hits],
-  const float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  float& sumCoord,
-  PlaneCounter& planeCounter,
-  const SciFi::Hits& scifi_hits)
-{
-
-  while (endRange < n_stereoHits - 1) {
-    const float averageCoord = sumCoord / float(endRange - beginRange);
-
-    // remove first if not single and farthest from mean
-    if (
-      planeCounter.nbInPlane(scifi_hits.planeCode(stereoHits[beginRange]) / 2) > 1 &&
-      ((averageCoord - stereoCoords[beginRange]) > 1.0f * (stereoCoords[endRange - 1] - averageCoord))) {
-
-      planeCounter.removeHit(scifi_hits.planeCode(stereoHits[beginRange]) / 2);
-      sumCoord -= stereoCoords[beginRange];
-      beginRange++;
-      continue;
-    }
-
-    if (endRange == n_stereoHits - 1) break; // already at end, cluster cannot be expanded anymore
-    // add next, if it decreases the range size and is empty
-    if ((planeCounter.nbInPlane(scifi_hits.planeCode(stereoHits[beginRange]) / 2) == 0)) {
-      if ((averageCoord - stereoCoords[beginRange] > stereoCoords[endRange] - averageCoord)) {
-        planeCounter.addHit(scifi_hits.planeCode(stereoHits[endRange]) / 2);
-        sumCoord += stereoCoords[endRange];
-        endRange++;
-        continue;
-      }
-    }
-
-    break;
-  }
-}
-
-__host__ __device__ int findBestStereoHitOnEmptyLayer(
-  const int itBegin,
-  const int itEnd,
-  const SciFi::Hits& scifi_hits,
-  const float yZone,
-  const float xPred,
-  const float dxTol,
-  const bool triangleSearch)
-{
-
-  int best = -1;
-  float bestChi2 = SciFi::Tracking::maxChi2Stereo;
-  for (int itH = itBegin; itEnd != itH; ++itH) {
-    const float dx = scifi_hits.x0[itH] + yZone * scifi_hits.dxdy(itH) - xPred;
-    if (dx > dxTol) break;
-    if (triangleSearch) {
-      if (yZone > scifi_hits.yMax(itH) + SciFi::Tracking::yTolUVSearch) continue;
-      if (yZone < scifi_hits.yMin(itH) - SciFi::Tracking::yTolUVSearch) continue;
-    }
-    const float chi2 = dx * dx * scifi_hits.w(itH);
-    if (chi2 < bestChi2) {
-      bestChi2 = chi2;
-      best = itH;
-    }
-  }
-  return best;
-}
diff --git a/cuda/SciFi/PrForward/src/LinearFitting.cu b/cuda/SciFi/PrForward/src/LinearFitting.cu
deleted file mode 100644
index f8d16309a97..00000000000
--- a/cuda/SciFi/PrForward/src/LinearFitting.cu
+++ /dev/null
@@ -1,179 +0,0 @@
-#include "LinearFitting.cuh"
-
-/**
-   Functions related to fitting a straight line
- */
-
-__host__ __device__ float getLineFitDistance(
-  const SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int it)
-{
-  return coordX[it] - (parameters.m_c0 + (scifi_hits.z0[allXHits[it]] - parameters.m_z0) * parameters.m_tc);
-}
-
-__host__ __device__ float getLineFitChi2(
-  const SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int it)
-{
-  float d = getLineFitDistance(parameters, scifi_hits, coordX, allXHits, it);
-  return d * d * coordX[it];
-}
-
-__host__ __device__ void solveLineFit(SciFi::Tracking::LineFitterPars& parameters)
-{
-  float den = (parameters.m_sz * parameters.m_sz - parameters.m_s0 * parameters.m_sz2);
-  parameters.m_c0 = (parameters.m_scz * parameters.m_sz - parameters.m_sc * parameters.m_sz2) / den;
-  parameters.m_tc = (parameters.m_sc * parameters.m_sz - parameters.m_s0 * parameters.m_scz) / den;
-}
-
-__host__ __device__ void incrementLineFitParameters(
-  SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int it)
-{
-  float c = coordX[it];
-  const int hit = allXHits[it];
-  float w = scifi_hits.w(hit);
-  float z = scifi_hits.z0[hit] - parameters.m_z0;
-  parameters.m_s0 += w;
-  parameters.m_sz += w * z;
-  parameters.m_sz2 += w * z * z;
-  parameters.m_sc += w * c;
-  parameters.m_scz += w * c * z;
-}
-
-__host__ __device__ void fitHitsFromSingleHitPlanes(
-  const int it1,
-  const int it2,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  const PlaneCounter planeCounter,
-  SciFi::Tracking::LineFitterPars& lineFitParameters,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits],
-  int nOtherHits[SciFi::Constants::n_layers])
-{
-
-  for (auto itH = it1; it2 > itH; ++itH) {
-    assert(itH < n_x_hits);
-    if (usedHits[itH]) continue;
-    int planeCode = scifi_hits.planeCode(allXHits[itH]) / 2;
-    if (planeCounter.nbInPlane(planeCode) == 1) {
-      incrementLineFitParameters(lineFitParameters, scifi_hits, coordX, allXHits, itH);
-    }
-    else {
-      if (nOtherHits[planeCode] < SciFi::Tracking::max_other_hits) {
-        assert(nOtherHits[planeCode] < SciFi::Tracking::max_other_hits);
-        otherHits[planeCode][nOtherHits[planeCode]++] = itH;
-      }
-    }
-  }
-  solveLineFit(lineFitParameters);
-}
-
-__host__ __device__ void addAndFitHitsFromMultipleHitPlanes(
-  const int nOtherHits[SciFi::Constants::n_layers],
-  SciFi::Tracking::LineFitterPars& lineFitParameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits])
-{
-
-  for (int i = 0; i < SciFi::Constants::n_layers; i++) {
-    if (nOtherHits[i] == 0) continue;
-
-    float bestChi2 = 1e9f;
-    int best = -1;
-    for (int hit = 0; hit < nOtherHits[i]; ++hit) {
-      const float chi2 = getLineFitChi2(lineFitParameters, scifi_hits, coordX, allXHits, otherHits[i][hit]);
-      if (chi2 < bestChi2) {
-        bestChi2 = chi2;
-        best = hit;
-      }
-    }
-    if (best > -1) {
-      incrementLineFitParameters(lineFitParameters, scifi_hits, coordX, allXHits, otherHits[i][best]);
-    }
-  }
-  solveLineFit(lineFitParameters);
-}
-
-// the track parameterization is cubic in (z-zRef),
-// however only the first two parametres are varied in this fit
-// -> this is a linear fit
-__host__ __device__ void fastLinearFit(
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  PlaneCounter planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-  // re-do fit every time an outlier was removed
-  bool fit = true;
-  while (fit) {
-    //== Fit a line
-    float s0 = 0.f;
-    float sz = 0.f;
-    float sz2 = 0.f;
-    float sd = 0.f;
-    float sdz = 0.f;
-
-    for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-      int hit = coordToFit[i_hit];
-      const float parsX[4] = {trackParameters[0], trackParameters[1], trackParameters[2], trackParameters[3]};
-      const float zHit = scifi_hits.z0[hit];
-      float track_x_at_zHit = evalCubicParameterization(parsX, zHit);
-      const float d = scifi_hits.x0[hit] - track_x_at_zHit;
-      const float w = scifi_hits.w(hit);
-      const float z = zHit - SciFi::Tracking::zReference;
-      s0 += w;
-      sz += w * z;
-      sz2 += w * z * z;
-      sd += w * d;
-      sdz += w * d * z;
-    }
-    float den = (sz * sz - s0 * sz2);
-    if (!(fabsf(den) > 1e-5f)) return;
-    const float da = (sdz * sz - sd * sz2) / den;
-    const float db = (sd * sz - s0 * sdz) / den;
-    trackParameters[0] += da;
-    trackParameters[1] += db;
-    fit = false;
-
-    if (n_coordToFit < pars.minXHits) return;
-
-    int worst = n_coordToFit;
-    float maxChi2 = 0.f;
-    const bool notMultiple = planeCounter.nbDifferent == n_coordToFit;
-    // TODO how many multiple hits do we normaly have?
-    // how often do we do the right thing here?
-    // delete two hits at same time?
-    for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-      int hit = coordToFit[i_hit];
-      // This could certainly be wrapped in some helper function with a lot
-      // of passing around or copying etc...
-      const float parsX[4] = {trackParameters[0], trackParameters[1], trackParameters[2], trackParameters[3]};
-      const float chi2 = chi2XHit(parsX, scifi_hits, hit);
-      if (chi2 > maxChi2 && (notMultiple || planeCounter.nbInPlane(scifi_hits.planeCode(hit) / 2) > 1)) {
-        maxChi2 = chi2;
-        worst = i_hit;
-      }
-    }
-    if (maxChi2 > SciFi::Tracking::maxChi2LinearFit || (!notMultiple && maxChi2 > 4.f)) {
-      removeOutlier(scifi_hits, planeCounter, coordToFit, n_coordToFit, coordToFit[worst]);
-      fit = true;
-    }
-  }
-}
diff --git a/cuda/SciFi/PrForward/src/ParabolaFitting.cu b/cuda/SciFi/PrForward/src/ParabolaFitting.cu
deleted file mode 100644
index e36c0d7afad..00000000000
--- a/cuda/SciFi/PrForward/src/ParabolaFitting.cu
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "ParabolaFitting.cuh"
-
-__host__ __device__ int fitParabola(
-  int* coordToFit,
-  const int n_coordToFit,
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  const bool xFit)
-{
-
-  //== Fit a cubic
-  float s0 = 0.f;
-  float sz = 0.f;
-  float sz2 = 0.f;
-  float sz3 = 0.f;
-  float sz4 = 0.f;
-  float sd = 0.f;
-  float sdz = 0.f;
-  float sdz2 = 0.f;
-
-  for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-    int hit = coordToFit[i_hit];
-    float d = trackToHitDistance(trackParameters, scifi_hits, hit);
-    if (!xFit) d *= -1.f / scifi_hits.dxdy(hit); // TODO multiplication much faster than division!
-    float w = scifi_hits.w(hit);
-    float z = .001f * (scifi_hits.z0[hit] - SciFi::Tracking::zReference);
-    s0 += w;
-    sz += w * z;
-    sz2 += w * z * z;
-    sz3 += w * z * z * z;
-    sz4 += w * z * z * z * z;
-    sd += w * d;
-    sdz += w * d * z;
-    sdz2 += w * d * z * z;
-  }
-  const float b1 = sz * sz - s0 * sz2;
-  const float c1 = sz2 * sz - s0 * sz3;
-  const float d1 = sd * sz - s0 * sdz;
-  const float b2 = sz2 * sz2 - sz * sz3;
-  const float c2 = sz3 * sz2 - sz * sz4;
-  const float d2 = sdz * sz2 - sz * sdz2;
-  const float den = (b1 * c2 - b2 * c1);
-  if (!(fabsf(den) > 1e-5f)) return false;
-  const float db = (d1 * c2 - d2 * c1) / den;
-  const float dc = (d2 * b1 - d1 * b2) / den;
-  const float da = (sd - db * sz - dc * sz2) / s0;
-  if (xFit) {
-    trackParameters[0] += da;
-    trackParameters[1] += db * 1.e-3f;
-    trackParameters[2] += dc * 1.e-6f;
-  }
-  else {
-    trackParameters[4] += da;
-    trackParameters[5] += db * 1.e-3f;
-    trackParameters[6] += dc * 1.e-6f;
-  }
-
-  return true;
-}
diff --git a/cuda/SciFi/PrForward/src/PrForward.cu b/cuda/SciFi/PrForward/src/PrForward.cu
deleted file mode 100644
index 3a7962d3af3..00000000000
--- a/cuda/SciFi/PrForward/src/PrForward.cu
+++ /dev/null
@@ -1,195 +0,0 @@
-// *********************************************************************************
-// ************************ Introduction to Forward Tracking **********************
-// *********************************************************************************
-//
-//  A detailed introduction in Forward tracking (with real pictures!) can be
-//  found here:
-//  (2002) http://cds.cern.ch/record/684710/files/lhcb-2002-008.pdf
-//  (2007) http://cds.cern.ch/record/1033584/files/lhcb-2007-015.pdf
-//  (2014) http://cds.cern.ch/record/1641927/files/LHCb-PUB-2014-001.pdf
-//
-// *** Short Introduction in geometry:
-//
-// The SciFi Tracker Detector, or simple Fibre Tracker (FT) consits out of 3 stations.
-// Each station consists out of 4 planes/layers. Thus there are in total 12 layers,
-// in which a particle can leave a hit. The reasonable maximum number of hits a track
-// can have is thus also 12 (sometimes 2 hits per layer are picked up).
-//
-// Each layer consists out of several Fibre mats. A fibre has a diameter of below a mm.(FIXME)
-// Several fibres are glued alongside each other to form a mat.
-// A Scintilating Fibre produces light, if a particle traverses. This light is then
-// detected on the outside of the Fibre mat.
-//
-// Looking from the collision point, one (X-)layer looks like the following:
-//
-//                    y       6m
-//                    ^  ||||||||||||| Upper side
-//                    |  ||||||||||||| 2.5m
-//                    |  |||||||||||||
-//                   -|--||||||o||||||----> -x
-//                       |||||||||||||
-//                       ||||||||||||| Lower side
-//                       ||||||||||||| 2.5m
-//
-// All fibres are aranged parallel to the y-axis. There are three different
-// kinds of layers, denoted by X,U,V. The U/V layers are rotated with respect to
-// the X-layers by +/- 5 degrees, to also get a handle of the y position of the
-// particle. As due to the magnetic field particles are only deflected in
-// x-direction, this configuration offers the best resolution.
-// The layer structure in the FT is XUVX-XUVX-XUVX.
-//
-// The detector is divided into an upeer and a lower side (>/< y=0). As particles
-// are only deflected in x direction there are only very(!) few particles that go
-// from the lower to the upper side, or vice versa. The reconstruction algorithm
-// can therefore be split into two independent steps: First track reconstruction
-// for tracks in the upper side, and afterwards for tracks in the lower side.
-//
-// Due to construction issues this is NOT true for U/V layers. In these layers the
-// complete(!) fibre modules are rotated, producing a zic-zac pattern at y=0, also
-// called  "the triangles". Therefore for U/V layers it must be explicetly also
-// searched for these hit on the "other side", if the track is close to y=0.
-// Sketch (rotation exagerated!):
-//                                          _.*
-//     y ^   _.*                         _.*
-//       | .*._      Upper side       _.*._
-//       |     *._                 _.*     *._
-//       |--------*._           _.*           *._----------------> x
-//       |           *._     _.*                 *._     _.*
-//                      *._.*       Lower side      *._.*
-//
-//
-//
-//
-//
-//       Zone ordering defined on PrKernel/PrFTInfo.h
-//
-//     y ^
-//       |    1  3  5  7     9 11 13 15    17 19 21 23
-//       |    |  |  |  |     |  |  |  |     |  |  |  |
-//       |    x  u  v  x     x  u  v  x     x  u  v  x   <-- type of layer
-//       |    |  |  |  |     |  |  |  |     |  |  |  |
-//       |------------------------------------------------> z
-//       |    |  |  |  |     |  |  |  |     |  |  |  |
-//       |    |  |  |  |     |  |  |  |     |  |  |  |
-//       |    0  2  4  6     8 10 12 14    16 18 20 22
-//
-//
-// *** Short introduction in the Forward Tracking algorithm
-//
-// The track reconstruction is seperated into several steps:
-//
-// 1) Using only X-hits
-//    1.1) Preselection: collectAllXHits()
-//    1.2) Hough Transformation: xAtRef_SamePlaneHits()
-//    1.3) Cluster search: selectXCandidates()
-//    1.4) Linear and than Cubic Fit of X-Projection
-// 2) Introducing U/V hits or also called stereo hits
-//    2.1) Preselection: collectStereoHits
-//    2.2) Cluster search: selectStereoHits
-//    2.3) Fit Y-Projection
-// 3) Using all (U+V+X) hits
-//    3.1) Fitting X-Projection
-//    3.2) calculating track quality with a Neural Net
-//    3.3) final clone+ghost killing
-//
-// *****************************************************************
-
-#include "PrForward.cuh"
-
-//-----------------------------------------------------------------------------
-// Implementation file for class : PrForward
-//
-// Based on code written by :
-// 2012-03-20 : Olivier Callot
-// 2013-03-15 : Thomas Nikodem
-// 2015-02-13 : Sevda Esen [additional search in the triangles by Marian Stahl]
-// 2016-03-09 : Thomas Nikodem [complete restructuring]
-// 2018-08    : Vava Gligorov [extract code from Rec, make compile within GPU framework
-// 2018-09    : Dorothea vom Bruch [convert to CUDA, runs on GPU]
-//-----------------------------------------------------------------------------
-
-//=============================================================================
-
-// Kernel to call Forward tracking on GPU
-// Loop over veloUT input tracks using threadIdx.x
-__global__ void scifi_pr_forward(
-  uint32_t* dev_scifi_hits,
-  const uint32_t* dev_scifi_hit_count,
-  const int* dev_atomics_velo,
-  const uint* dev_velo_track_hit_number,
-  const char* dev_velo_states,
-  const int* dev_atomics_ut,
-  const char* dev_ut_track_hits,
-  const uint* dev_ut_track_hit_number,
-  const float* dev_ut_qop,
-  const uint* dev_ut_track_velo_indices,
-  SciFi::TrackHits* dev_scifi_tracks,
-  int* dev_atomics_scifi,
-  const SciFi::Tracking::TMVA* dev_tmva1,
-  const SciFi::Tracking::TMVA* dev_tmva2,
-  const SciFi::Tracking::Arrays* dev_constArrays,
-  const float* dev_magnet_polarity,
-  const char* dev_scifi_geometry,
-  const float* dev_inv_clus_res)
-{
-  const uint number_of_events = gridDim.x;
-  const uint event_number = blockIdx.x;
-
-  // Velo consolidated types
-  const Velo::Consolidated::Tracks velo_tracks {
-    (uint*) dev_atomics_velo, (uint*) dev_velo_track_hit_number, event_number, number_of_events};
-  const Velo::Consolidated::States velo_states {(char*) dev_velo_states, velo_tracks.total_number_of_tracks};
-  const uint velo_tracks_offset_event = velo_tracks.tracks_offset(event_number);
-
-  // UT consolidated tracks
-  UT::Consolidated::Tracks ut_tracks {(uint*) dev_atomics_ut,
-                                      (uint*) dev_ut_track_hit_number,
-                                      (float*) dev_ut_qop,
-                                      (uint*) dev_ut_track_velo_indices,
-                                      event_number,
-                                      number_of_events};
-  const int n_veloUT_tracks_event = ut_tracks.number_of_tracks(event_number);
-  const int ut_event_tracks_offset = ut_tracks.tracks_offset(event_number);
-
-  // SciFi un-consolidated track types
-  SciFi::TrackHits* scifi_tracks_event = dev_scifi_tracks + ut_event_tracks_offset * SciFi::Constants::max_SciFi_tracks_per_UT_track;
-  int* atomics_scifi_event = dev_atomics_scifi + event_number;
-
-  // SciFi hits
-  const uint total_number_of_hits = dev_scifi_hit_count[number_of_events * SciFi::Constants::n_mat_groups_and_mats];
-  const SciFi::HitCount scifi_hit_count {(uint32_t*) dev_scifi_hit_count, event_number};
-  const SciFi::SciFiGeometry scifi_geometry {dev_scifi_geometry};
-  SciFi::Hits scifi_hits(dev_scifi_hits, total_number_of_hits, &scifi_geometry, dev_inv_clus_res);
-
-  // initialize atomic SciFi tracks counter
-  if (threadIdx.x == 0) {
-    *atomics_scifi_event = 0;
-  }
-  __syncthreads();
-
-  // Loop over the veloUT input tracks
-  for (int i = 0; i < (n_veloUT_tracks_event + blockDim.x - 1) / blockDim.x; ++i) {
-    const int i_veloUT_track = i * blockDim.x + threadIdx.x;
-    if (i_veloUT_track < n_veloUT_tracks_event) {
-      const float qop_ut = ut_tracks.qop[i_veloUT_track];
-
-      const int i_velo_track = ut_tracks.velo_track[i_veloUT_track];
-      const uint velo_states_index = velo_tracks_offset_event + i_velo_track;
-      const MiniState velo_state = velo_states.getMiniState(velo_states_index);
-
-      find_forward_tracks(
-        scifi_hits,
-        scifi_hit_count,
-        qop_ut,
-        i_veloUT_track,
-        scifi_tracks_event,
-        (uint*) atomics_scifi_event,
-        n_veloUT_tracks_event,
-        dev_tmva1,
-        dev_tmva2,
-        dev_constArrays,
-        dev_magnet_polarity[0],
-        velo_state);
-    }
-  }
-}
diff --git a/cuda/SciFi/PrForward/src/PrForwardTools.cu b/cuda/SciFi/PrForward/src/PrForwardTools.cu
deleted file mode 100644
index a79620c9a79..00000000000
--- a/cuda/SciFi/PrForward/src/PrForwardTools.cu
+++ /dev/null
@@ -1,398 +0,0 @@
-#include "PrForwardTools.cuh"
-
-/* Look first in x layers, then in stereo layers for hits
-   do 1D Hough transform for x- and stereo hits
-   do global 1D Hough transform
-   use TMVAs to obtain track quality */
-__host__ __device__ void find_forward_tracks(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const float qop_ut,
-  const int i_veloUT_track,
-  SciFi::TrackHits* outputTracks,
-  uint* n_forward_tracks,
-  const int ut_event_number_of_tracks,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state)
-{
-
-  // The LHCb framework code had a PT preselection for the VeloUT tracks
-  // here, which I am removing because this should be done explicitly through
-  // track selectors if we do it at all, not hacked inside the tracking code
-
-  const float zRef_track = SciFi::Tracking::zReference;
-  const float xAtRef = xFromVelo(zRef_track, velo_state);
-  const float xParams_seed[4] = {xAtRef, velo_state.tx, 0.f, 0.f};
-  const float yAtRef = yFromVelo(zRef_track, velo_state);
-  const float yParams_seed[4] = {yAtRef, velo_state.ty, 0.f, 0.f};
-
-  // First loop Hough cluster search, set initial search windows
-  SciFi::Tracking::HitSearchCuts pars_first {SciFi::Tracking::minXHits,
-                                             SciFi::Tracking::maxXWindow,
-                                             SciFi::Tracking::maxXWindowSlope,
-                                             SciFi::Tracking::maxXGap,
-                                             4u};
-  SciFi::Tracking::HitSearchCuts pars_second {SciFi::Tracking::minXHits_2nd,
-                                              SciFi::Tracking::maxXWindow_2nd,
-                                              SciFi::Tracking::maxXWindowSlope_2nd,
-                                              SciFi::Tracking::maxXGap_2nd,
-                                              4u};
-
-  int allXHits[2][SciFi::Tracking::max_x_hits];
-  int n_x_hits[2] = {0};
-  float coordX[2][SciFi::Tracking::max_x_hits];
-
-  if (yAtRef > -5.f)
-    collectAllXHits(
-      scifi_hits,
-      scifi_hit_count,
-      allXHits[1],
-      n_x_hits[1],
-      coordX[1],
-      xParams_seed,
-      yParams_seed,
-      constArrays,
-      magnet_polarity,
-      velo_state,
-      qop_ut,
-      1);
-  if (yAtRef < 5.f)
-    collectAllXHits(
-      scifi_hits,
-      scifi_hit_count,
-      allXHits[0],
-      n_x_hits[0],
-      coordX[0],
-      xParams_seed,
-      yParams_seed,
-      constArrays,
-      magnet_polarity,
-      velo_state,
-      qop_ut,
-      -1);
-
-  SciFi::Tracking::Track candidate_tracks[SciFi::Tracking::max_candidate_tracks];
-  int n_candidate_tracks = 0;
-  bool usedHits[2][SciFi::Tracking::max_x_hits] = {false};
-
-  if (yAtRef > -5.f)
-    selectXCandidates(
-      scifi_hits,
-      scifi_hit_count,
-      allXHits[1],
-      n_x_hits[1],
-      usedHits[1],
-      coordX[1],
-      candidate_tracks,
-      n_candidate_tracks,
-      zRef_track,
-      xParams_seed,
-      yParams_seed,
-      velo_state,
-      pars_first,
-      constArrays,
-      1,
-      false);
-  if (yAtRef < 5.f)
-    selectXCandidates(
-      scifi_hits,
-      scifi_hit_count,
-      allXHits[0],
-      n_x_hits[0],
-      usedHits[0],
-      coordX[0],
-      candidate_tracks,
-      n_candidate_tracks,
-      zRef_track,
-      xParams_seed,
-      yParams_seed,
-      velo_state,
-      pars_first,
-      constArrays,
-      -1,
-      false);
-
-  SciFi::Tracking::Track selected_tracks[SciFi::Tracking::max_selected_tracks];
-  int n_selected_tracks = 0;
-
-  selectFullCandidates(
-    scifi_hits,
-    scifi_hit_count,
-    candidate_tracks,
-    n_candidate_tracks,
-    selected_tracks,
-    n_selected_tracks,
-    xParams_seed,
-    yParams_seed,
-    velo_state,
-    qop_ut,
-    pars_first,
-    tmva1,
-    tmva2,
-    constArrays,
-    magnet_polarity,
-    false);
-
-  bool ok = false;
-  for (int i_track = 0; i_track < n_selected_tracks; ++i_track) {
-    if (selected_tracks[i_track].hitsNum > 10) ok = true;
-  }
-  assert(n_selected_tracks < SciFi::Tracking::max_selected_tracks);
-
-  SciFi::Tracking::Track candidate_tracks2[SciFi::Tracking::max_tracks_second_loop];
-  int n_candidate_tracks2 = 0;
-
-  if (!ok && SciFi::Tracking::secondLoop) { // If you found nothing begin the 2nd loop
-    if (yAtRef > -5.f)
-      selectXCandidates(
-        scifi_hits,
-        scifi_hit_count,
-        allXHits[1],
-        n_x_hits[1],
-        usedHits[1],
-        coordX[1],
-        candidate_tracks2,
-        n_candidate_tracks2,
-        zRef_track,
-        xParams_seed,
-        yParams_seed,
-        velo_state,
-        pars_second,
-        constArrays,
-        1,
-        true);
-    if (yAtRef < 5.f)
-      selectXCandidates(
-        scifi_hits,
-        scifi_hit_count,
-        allXHits[0],
-        n_x_hits[0],
-        usedHits[0],
-        coordX[0],
-        candidate_tracks2,
-        n_candidate_tracks2,
-        zRef_track,
-        xParams_seed,
-        yParams_seed,
-        velo_state,
-        pars_second,
-        constArrays,
-        -1,
-        true);
-
-    SciFi::Tracking::Track selected_tracks2[SciFi::Tracking::max_tracks_second_loop];
-    int n_selected_tracks2 = 0;
-
-    selectFullCandidates(
-      scifi_hits,
-      scifi_hit_count,
-      candidate_tracks2,
-      n_candidate_tracks2,
-      selected_tracks2,
-      n_selected_tracks2,
-      xParams_seed,
-      yParams_seed,
-      velo_state,
-      qop_ut,
-      pars_second,
-      tmva1,
-      tmva2,
-      constArrays,
-      magnet_polarity,
-      true);
-
-    for (int i_track = 0; i_track < n_selected_tracks2; ++i_track) {
-      assert(n_selected_tracks < SciFi::Tracking::max_selected_tracks);
-      selected_tracks[n_selected_tracks++] = selected_tracks2[i_track];
-    }
-
-    ok = (n_selected_tracks > 0);
-  }
-
-  if (ok || !SciFi::Tracking::secondLoop) {
-
-    if (n_selected_tracks > 1) {
-      // not using thrust::sort due to temporary_buffer::allocate:: get_temporary_buffer failed" error
-      // thrust::sort( thrust::seq, selected_tracks, selected_tracks + n_selected_tracks, lowerByQuality);
-      sort_tracks(selected_tracks, n_selected_tracks, [](SciFi::Tracking::Track t1, SciFi::Tracking::Track t2) {
-        if (t1.quality < t2.quality) return -1;
-        if (t1.quality == t2.quality) return 0;
-        return 1;
-      });
-    }
-
-    const uint event_hit_offset = scifi_hit_count.event_offset();
-    float minQuality = SciFi::Tracking::maxQuality;
-    for (int i_track = 0; i_track < n_selected_tracks; ++i_track) {
-      SciFi::Tracking::Track& track = selected_tracks[i_track];
-
-      // TODO: We would have to work out a way for the Prforward to have max 12 hits
-      if (track.hitsNum > 12) {
-        track.hitsNum = 12;
-      }
-
-      if (track.quality + SciFi::Tracking::deltaQuality < minQuality)
-        minQuality = track.quality + SciFi::Tracking::deltaQuality;
-      if (!(track.quality > minQuality)) {
-
-        SciFi::TrackHits tr = makeTrack(track);
-        tr.ut_track_index = i_veloUT_track;
-
-        // state at end of SciFi
-        const float z = SciFi::Constants::ZEndT;
-        MiniState scifi_state(track.x(z), track.y(z), z, track.xSlope(z), track.ySlope(z));
-
-        // add LHCbIDs from SciFi part of the track
-        for (int i_hit = 0; i_hit < track.hitsNum; ++i_hit) {
-          // save local hit index within event to be able to use short
-          const int local_hit_index = track.hit_indices[i_hit] - event_hit_offset;
-          tr.add_hit(local_hit_index);
-        }
-
-        if (*n_forward_tracks >= ut_event_number_of_tracks * SciFi::Constants::max_SciFi_tracks_per_UT_track) printf("n_forward_tracks = %u \n", *n_forward_tracks);
-        assert(*n_forward_tracks < ut_event_number_of_tracks * SciFi::Constants::max_SciFi_tracks_per_UT_track);
-#ifndef __CUDA_ARCH__
-        outputTracks[(*n_forward_tracks)++] = tr;
-#else
-        uint n_tracks = atomicAdd(n_forward_tracks, 1);
-        assert(n_tracks < ut_event_number_of_tracks * SciFi::Constants::max_SciFi_tracks_per_UT_track);
-        outputTracks[n_tracks] = tr;
-#endif
-      }
-    }
-  }
-}
-
-// Turn SciFi::Tracking::Track into a SciFi::Track
-__host__ __device__ SciFi::TrackHits makeTrack(SciFi::Tracking::Track track)
-{
-  SciFi::TrackHits tr;
-  tr.qop = track.qop;
-  tr.quality = track.quality;
-
-  return tr;
-}
-
-//=========================================================================
-//  Create Full candidates out of xCandidates
-//  Searching for stereo hits
-//  Fit of all hits
-//  save everything in track candidate folder
-//=========================================================================
-__host__ __device__ void selectFullCandidates(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track* candidate_tracks,
-  int& n_candidate_tracks,
-  SciFi::Tracking::Track* selected_tracks,
-  int& n_selected_tracks,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  MiniState velo_state,
-  const float VeloUT_qOverP,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const bool secondLoop)
-{
-
-  PlaneCounter planeCounter;
-  planeCounter.clear();
-  float mlpInput[7] = {0};
-
-  for (int i_track = 0; i_track < n_candidate_tracks; ++i_track) {
-    SciFi::Tracking::Track* cand = candidate_tracks + i_track;
-
-    pars.minStereoHits = 4;
-
-    if (cand->hitsNum + pars.minStereoHits < SciFi::Tracking::minTotalHits) {
-      pars.minStereoHits = SciFi::Tracking::minTotalHits - cand->hitsNum;
-    }
-
-    int stereoHits[SciFi::Tracking::max_stereo_hits];
-    int n_stereoHits = 0;
-    float stereoCoords[SciFi::Tracking::max_stereo_hits];
-    collectStereoHits(
-      scifi_hits, scifi_hit_count, *cand, velo_state, pars, constArrays, stereoCoords, stereoHits, n_stereoHits);
-
-    if (n_stereoHits < pars.minStereoHits) continue;
-
-    if (!selectStereoHits(
-          scifi_hits, scifi_hit_count, *cand, constArrays, stereoCoords, stereoHits, n_stereoHits, velo_state, pars))
-      continue;
-
-    planeCounter.clear();
-    for (int i_hit = 0; i_hit < cand->hitsNum; ++i_hit) {
-      int hit = cand->hit_indices[i_hit];
-      planeCounter.addHit(scifi_hits.planeCode(hit) / 2);
-    }
-
-    // make a fit of ALL hits using their x coordinate
-    if (!quadraticFitX(scifi_hits, cand->trackParams, cand->hit_indices, cand->hitsNum, planeCounter, pars)) continue;
-
-    // track has enough hits, calcualte quality and save if good enough
-    if (planeCounter.nbDifferent >= SciFi::Tracking::minTotalHits) {
-
-      const float qOverP = calcqOverP(cand->trackParams[1], constArrays, velo_state, magnet_polarity);
-      // orig params before fitting , TODO faster if only calc once?? mem usage?
-      const float xAtRef = cand->trackParams[0];
-      float dSlope = (velo_state.x + (SciFi::Tracking::zReference - velo_state.z) * velo_state.tx - xAtRef) /
-                     (SciFi::Tracking::zReference - constArrays->zMagnetParams[0]);
-      const float zMagSlope =
-        constArrays->zMagnetParams[2] * pow(velo_state.tx, 2) + constArrays->zMagnetParams[3] * pow(velo_state.ty, 2);
-      const float zMag = constArrays->zMagnetParams[0] + constArrays->zMagnetParams[1] * dSlope * dSlope + zMagSlope;
-      const float xMag = velo_state.x + (zMag - velo_state.z) * velo_state.tx;
-      const float slopeT = (xAtRef - xMag) / (SciFi::Tracking::zReference - zMag);
-      dSlope = slopeT - velo_state.tx;
-      const float dyCoef = dSlope * dSlope * velo_state.ty;
-
-      float bx = slopeT;
-      float ay = velo_state.y + (SciFi::Tracking::zReference - velo_state.z) * velo_state.ty;
-      float by = velo_state.ty + dyCoef * SciFi::Tracking::byParams;
-
-      // ay,by,bx params
-      const float ay1 = cand->trackParams[4];
-      const float by1 = cand->trackParams[5];
-      const float bx1 = cand->trackParams[1];
-
-      mlpInput[0] = planeCounter.nbDifferent;
-      mlpInput[1] = qOverP;
-      mlpInput[2] = VeloUT_qOverP - qOverP;                // veloUT - scifi
-      if (fabsf(VeloUT_qOverP) < 1e-9f) mlpInput[2] = 0.f; // no momentum estiamte
-      mlpInput[3] = pow(velo_state.tx, 2) + pow(velo_state.ty, 2);
-      mlpInput[4] = by - by1;
-      mlpInput[5] = bx - bx1;
-      mlpInput[6] = ay - ay1;
-
-      float quality = 0.f;
-      /// WARNING: if the NN classes straight out of TMVA are used, put a mutex here!
-      if (pars.minXHits > 4)
-        quality = GetMvaValue(mlpInput, tmva1); // 1st loop NN
-      else
-        quality = GetMvaValue(mlpInput, tmva2); // 2nd loop NN
-
-      quality = 1.f - quality; // backward compability
-
-      if (quality < SciFi::Tracking::maxQuality) {
-        cand->quality = quality;
-        cand->qop = qOverP;
-        if (!secondLoop)
-          assert(n_selected_tracks < SciFi::Tracking::max_selected_tracks);
-        else if (secondLoop)
-          assert(n_selected_tracks < SciFi::Tracking::max_tracks_second_loop);
-        selected_tracks[n_selected_tracks++] = *cand;
-        if (!secondLoop) {
-          if (n_selected_tracks >= SciFi::Tracking::max_selected_tracks) break;
-        }
-        else if (secondLoop) {
-          if (n_selected_tracks >= SciFi::Tracking::max_tracks_second_loop) break;
-        }
-      }
-    }
-  }
-}
diff --git a/cuda/SciFi/PrForward/src/ReferencePlaneProjection.cu b/cuda/SciFi/PrForward/src/ReferencePlaneProjection.cu
deleted file mode 100644
index 98328b72f59..00000000000
--- a/cuda/SciFi/PrForward/src/ReferencePlaneProjection.cu
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "ReferencePlaneProjection.cuh"
-
-// project x position of hits from one plane onto the reference plane
-// save it in coordX
-// in the c++ this is vectorized, undoing because no point before CUDA (but vectorization is obvious)
-__host__ __device__ void xAtRef_SamePlaneHits(
-  const SciFi::Hits& scifi_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  const float xParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  MiniState velo_state,
-  const float zMagSlope,
-  int itH,
-  int itEnd)
-{
-  // this is quite computationally expensive mind, should take care when porting
-  assert(itH < SciFi::Tracking::max_x_hits);
-  const float zHit = scifi_hits.z0[allXHits[itH]]; // all hits in same layer
-  const float xFromVelo_Hit = evalCubicParameterization(xParams_seed, zHit);
-  const float dSlopeDivPart = 1.f / (zHit - constArrays->zMagnetParams[0]);
-  const float dz = 1.e-3f * (zHit - SciFi::Tracking::zReference);
-
-  while (itEnd > itH) {
-    float xHit = scifi_hits.x0[allXHits[itH]];
-    // difference in slope before and after the kick
-    float dSlope = (xFromVelo_Hit - xHit) * dSlopeDivPart;
-    // update zMag now that dSlope is known
-    float zMag = zMagSlope + constArrays->zMagnetParams[1] * dSlope * dSlope;
-    float xMag = xFromVelo_Hit + velo_state.tx * (zMag - zHit);
-    // calculate x position on reference plane (save in coodX)
-    // dxCoef: account for additional bending of track due to fringe field in first station
-    // expressed by quadratic and cubic term in z
-    float dxCoef = dz * dz * (constArrays->xParams[0] + dz * constArrays->xParams[1]) * dSlope;
-    float ratio = (SciFi::Tracking::zReference - zMag) / (zHit - zMag);
-    coordX[itH] = xMag + ratio * (xHit + dxCoef - xMag);
-    itH++;
-  }
-}
diff --git a/cuda/SciFi/PrForward/src/TrackUtils.cu b/cuda/SciFi/PrForward/src/TrackUtils.cu
deleted file mode 100644
index 4114e33d0b9..00000000000
--- a/cuda/SciFi/PrForward/src/TrackUtils.cu
+++ /dev/null
@@ -1,264 +0,0 @@
-#include "TrackUtils.cuh"
-
-// extrapolate x position from given state to z
-__host__ __device__ float xFromVelo(const float z, const MiniState& velo_state)
-{
-  return velo_state.x + (z - velo_state.z) * velo_state.tx;
-}
-
-// extrapolate y position from given state to z
-__host__ __device__ float yFromVelo(const float z, const MiniState& velo_state)
-{
-  return velo_state.y + (z - velo_state.z) * velo_state.ty;
-}
-
-__host__ __device__ float evalCubicParameterization(const float params[4], float z)
-{
-  float dz = z - SciFi::Tracking::zReference;
-  return params[0] + (params[1] + (params[2] + params[3] * dz) * dz) * dz;
-}
-
-__host__ __device__ float evalParameterizationX(const float* params, float z)
-{
-  const float dz = z - SciFi::Tracking::zReference;
-  return params[0] + (params[1] + (params[2] + params[3] * dz) * dz) * dz;
-}
-
-__host__ __device__ float evalParameterizationY(const float* params, float z)
-{
-  const float dz = z - SciFi::Tracking::zReference;
-  return params[0] + (params[1] + params[2] * dz) * dz;
-}
-
-__host__ __device__ bool lowerByQuality(SciFi::Tracking::Track t1, SciFi::Tracking::Track t2)
-{
-  return t1.quality < t2.quality;
-}
-
-__host__ __device__ void getTrackParameters(
-  float xAtRef,
-  const MiniState& velo_state,
-  const SciFi::Tracking::Arrays* constArrays,
-  float trackParams[SciFi::Tracking::nTrackParams])
-{
-  float dSlope = (xFromVelo(SciFi::Tracking::zReference, velo_state) - xAtRef) /
-                 (SciFi::Tracking::zReference - constArrays->zMagnetParams[0]);
-  const float zMagSlope = constArrays->zMagnetParams[2] * velo_state.tx * velo_state.tx +
-                          constArrays->zMagnetParams[3] * velo_state.ty * velo_state.ty;
-  const float zMag = constArrays->zMagnetParams[0] + constArrays->zMagnetParams[1] * dSlope * dSlope + zMagSlope;
-  const float xMag = xFromVelo(zMag, velo_state);
-  const float slopeT = (xAtRef - xMag) / (SciFi::Tracking::zReference - zMag);
-  dSlope = slopeT - velo_state.tx;
-  const float dyCoef = dSlope * dSlope * velo_state.ty;
-
-  trackParams[0] = xAtRef;
-  trackParams[1] = slopeT;
-  trackParams[2] = 1.e-6f * constArrays->xParams[0] * dSlope;
-  trackParams[3] = 1.e-9f * constArrays->xParams[1] * dSlope;
-  trackParams[4] = yFromVelo(SciFi::Tracking::zReference, velo_state);
-  trackParams[5] = velo_state.ty + dyCoef * SciFi::Tracking::byParams;
-  trackParams[6] = dyCoef * SciFi::Tracking::cyParams;
-  trackParams[7] = 0.0f;
-  trackParams[8] = 0.0f; // last elements are chi2 and ndof, as float
-}
-
-__host__ __device__ float calcqOverP(float bx, const SciFi::Tracking::Arrays* constArrays, const MiniState& velo_state, const float magnet_polarity)
-{
-
-  float qop = 1.0f / Gaudi::Units::GeV;
-  const float bx2 = bx * bx;
-  const float ty2 = velo_state.ty * velo_state.ty;
-  const float coef =
-    (constArrays->momentumParams[0] + constArrays->momentumParams[1] * bx2 +
-     constArrays->momentumParams[2] * bx2 * bx2 + constArrays->momentumParams[3] * bx * velo_state.tx +
-     constArrays->momentumParams[4] * ty2 + constArrays->momentumParams[5] * ty2 * ty2);
-  const float tx2 = velo_state.tx * velo_state.tx;
-  float m_slope2 = tx2 + ty2;
-  float proj = sqrtf((1.f + m_slope2) / (1.f + tx2));
-  qop = (velo_state.tx - bx) / (coef * Gaudi::Units::GeV * proj * magnet_polarity);
-  return qop;
-}
-
-// Find z zMag position within the magnet at which the bending ("kick") occurs
-// this is parameterized based on MC
-// the second parameter([1]) is multiplied by the difference in slope before and
-// after the kick, this slope is calculated from zMag and the x position of the track
-// at the reference plane -> it is calculated iteratively later
-__host__ __device__ float zMagnet(const MiniState& velo_state, const SciFi::Tracking::Arrays* constArrays)
-{
-
-  return (
-    constArrays->zMagnetParams[0] + constArrays->zMagnetParams[2] * velo_state.tx * velo_state.tx +
-    constArrays->zMagnetParams[3] * velo_state.ty * velo_state.ty);
-}
-
-// calculate difference between straight line extrapolation and
-// where a track with wrongSignPT (2 GeV) would be on the reference plane (?)
-__host__ __device__ float calcDxRef(float pt, const MiniState& velo_state)
-{
-  const float tx2 = velo_state.tx * velo_state.tx;
-  const float ty2 = velo_state.ty * velo_state.ty;
-  float m_slope2 = tx2 + ty2;
-  return 3973000.f * sqrtf(m_slope2) / pt - 2200.f * ty2 - 1000.f * tx2; // tune this window
-}
-
-__host__ __device__ float
-trackToHitDistance(const float trackParameters[SciFi::Tracking::nTrackParams], const SciFi::Hits& scifi_hits, int hit)
-{
-  const float z_Hit = scifi_hits.z0[hit] + scifi_hits.dzdy(hit) * evalParameterizationY(trackParameters + 4, scifi_hits.z0[hit]);
-  const float x_track = evalParameterizationX(trackParameters, z_Hit);
-  const float y_track = evalParameterizationY(trackParameters + 4, z_Hit);
-  return scifi_hits.x0[hit] + y_track * scifi_hits.dxdy(hit) - x_track;
-}
-
-__host__ __device__ float chi2XHit(const float parsX[4], const SciFi::Hits& scifi_hits, const int hit)
-{
-  float track_x_at_zHit = evalCubicParameterization(parsX, scifi_hits.z0[hit]);
-  float hitdist = scifi_hits.x0[hit] - track_x_at_zHit;
-  return hitdist * hitdist * scifi_hits.w(hit);
-}
-
-// the track parameterization is cubic in (z-zRef),
-// however only the first three parametres are varied in this fit only
-// -> this is a quadratic fit
-__host__ __device__ bool quadraticFitX(
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  PlaneCounter& planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-
-  if (planeCounter.nbDifferent < pars.minXHits) return false;
-  bool doFit = true;
-  while (doFit) {
-
-    fitParabola(coordToFit, n_coordToFit, scifi_hits, trackParameters, true);
-
-    float maxChi2 = 0.f;
-    float totChi2 = 0.f;
-    int nDoF = -3; // fitted 3 parameters
-    const bool notMultiple = planeCounter.nbDifferent == n_coordToFit;
-
-    int worst = n_coordToFit;
-    for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-      int hit = coordToFit[i_hit];
-      float d = trackToHitDistance(trackParameters, scifi_hits, hit);
-      float chi2 = d * d * scifi_hits.w(hit);
-      totChi2 += chi2;
-      ++nDoF;
-      if (chi2 > maxChi2 && (notMultiple || planeCounter.nbInPlane(scifi_hits.planeCode(hit) / 2) > 1)) {
-        maxChi2 = chi2;
-        worst = i_hit;
-      }
-    }
-    if (nDoF < 1) return false;
-    trackParameters[7] = totChi2;
-    trackParameters[8] = (float) nDoF;
-
-    if (worst == n_coordToFit) {
-      return true;
-    }
-    doFit = false;
-    if (totChi2 / nDoF > SciFi::Tracking::maxChi2PerDoF || maxChi2 > SciFi::Tracking::maxChi2XProjection) {
-      removeOutlier(scifi_hits, planeCounter, coordToFit, n_coordToFit, coordToFit[worst]);
-      if (planeCounter.nbDifferent < pars.minXHits + pars.minStereoHits) return false;
-      doFit = true;
-    }
-  }
-  return true;
-}
-
-__host__ __device__ bool fitYProjection(
-  const SciFi::Hits& scifi_hits,
-  SciFi::Tracking::Track& track,
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  PlaneCounter& planeCounter,
-  const MiniState& velo_state,
-  const SciFi::Tracking::Arrays* constArrays,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-
-  float maxChi2 = 1.e9f;
-  bool parabola = false; // first linear than parabola
-  //== Fit a line
-  const float txs = track.trackParams[0]; // simplify overgeneral c++ calculation
-  const float tsxz = velo_state.x + (SciFi::Tracking::zReference - velo_state.z) * velo_state.tx;
-  const float tolYMag = SciFi::Tracking::tolYMag + SciFi::Tracking::tolYMagSlope * fabsf(txs - tsxz);
-  const float wMag = 1.f / (tolYMag * tolYMag);
-
-  bool doFit = true;
-  while (doFit) {
-    // Use position in magnet as constrain in fit
-    // although because wMag is quite small only little influence...
-    float zMag = zMagnet(velo_state, constArrays);
-    const float tys = track.trackParams[4] + (zMag - SciFi::Tracking::zReference) * track.trackParams[5];
-    const float tsyz = velo_state.y + (zMag - velo_state.z) * velo_state.ty;
-    const float dyMag = tys - tsyz;
-    zMag -= SciFi::Tracking::zReference;
-    float s0 = wMag;
-    float sz = wMag * zMag;
-    float sz2 = wMag * zMag * zMag;
-    float sd = wMag * dyMag;
-    float sdz = wMag * dyMag * zMag;
-
-    if (parabola) {
-
-      // position in magnet not used for parabola fit, hardly any influence on efficiency
-      fitParabola(stereoHits, n_stereoHits, scifi_hits, track.trackParams, false);
-    }
-    else { // straight line fit
-
-      for (int i_hit = 0; i_hit < n_stereoHits; ++i_hit) {
-        int hit = stereoHits[i_hit];
-        const float d = -trackToHitDistance(track.trackParams, scifi_hits, hit) /
-                        scifi_hits.dxdy(hit); // TODO multiplication much faster than division!
-        const float w = scifi_hits.w(hit);
-        const float z = scifi_hits.z0[hit] - SciFi::Tracking::zReference;
-        s0 += w;
-        sz += w * z;
-        sz2 += w * z * z;
-        sd += w * d;
-        sdz += w * d * z;
-      }
-      const float den = (s0 * sz2 - sz * sz);
-      if (!(fabsf(den) > 1e-5)) {
-        return false;
-      }
-      const float da = (sd * sz2 - sdz * sz) / den;
-      const float db = (sdz * s0 - sd * sz) / den;
-      track.trackParams[4] += da;
-      track.trackParams[5] += db;
-    } // fit end, now doing outlier removal
-
-    int worst = n_stereoHits;
-    maxChi2 = 0.;
-    for (int i_hit = 0; i_hit < n_stereoHits; ++i_hit) {
-      int hit = stereoHits[i_hit];
-      float d = trackToHitDistance(track.trackParams, scifi_hits, hit);
-      float chi2 = d * d * scifi_hits.w(hit);
-      if (chi2 > maxChi2) {
-        maxChi2 = chi2;
-        worst = i_hit;
-      }
-    }
-
-    if (maxChi2 < SciFi::Tracking::maxChi2StereoLinear && !parabola) {
-      parabola = true;
-      maxChi2 = 1.e9f;
-      continue;
-    }
-
-    if (maxChi2 > SciFi::Tracking::maxChi2Stereo) {
-      removeOutlier(scifi_hits, planeCounter, stereoHits, n_stereoHits, stereoHits[worst]);
-      if (planeCounter.nbDifferent < pars.minStereoHits) {
-        return false;
-      }
-      continue;
-    }
-    break;
-  }
-  return true;
-} 
diff --git a/cuda/SciFi/classifiers/README.md b/cuda/SciFi/classifiers/README.md
new file mode 100644
index 00000000000..74ef5519a4e
--- /dev/null
+++ b/cuda/SciFi/classifiers/README.md
@@ -0,0 +1 @@
+# Contains all the classifiers used to discriminate between real and fake tracks after the SciFi reconstruction
diff --git a/cuda/SciFi/PrForward/include/TMVA_Forward.cuh b/cuda/SciFi/classifiers/include/TMVA_Forward.cuh
similarity index 96%
rename from cuda/SciFi/PrForward/include/TMVA_Forward.cuh
rename to cuda/SciFi/classifiers/include/TMVA_Forward.cuh
index 1488f5b71f4..acf2f13ee06 100644
--- a/cuda/SciFi/PrForward/include/TMVA_Forward.cuh
+++ b/cuda/SciFi/classifiers/include/TMVA_Forward.cuh
@@ -5,8 +5,6 @@
 #include <string>
 #include <iostream>
 
-#include "PrForwardConstants.cuh"
-
 namespace SciFi {
 
   namespace Tracking {
diff --git a/cuda/SciFi/PrForward/include/TMVA_Forward_1.cuh b/cuda/SciFi/classifiers/include/TMVA_Forward_1.cuh
similarity index 100%
rename from cuda/SciFi/PrForward/include/TMVA_Forward_1.cuh
rename to cuda/SciFi/classifiers/include/TMVA_Forward_1.cuh
diff --git a/cuda/SciFi/PrForward/include/TMVA_Forward_2.cuh b/cuda/SciFi/classifiers/include/TMVA_Forward_2.cuh
similarity index 100%
rename from cuda/SciFi/PrForward/include/TMVA_Forward_2.cuh
rename to cuda/SciFi/classifiers/include/TMVA_Forward_2.cuh
diff --git a/cuda/SciFi/PrForward/src/TMVA_Forward.cu b/cuda/SciFi/classifiers/src/TMVA_Forward.cu
similarity index 100%
rename from cuda/SciFi/PrForward/src/TMVA_Forward.cu
rename to cuda/SciFi/classifiers/src/TMVA_Forward.cu
diff --git a/cuda/SciFi/common/include/SciFiDefinitions.cuh b/cuda/SciFi/common/include/SciFiDefinitions.cuh
index 52089e76461..506f493f3b3 100644
--- a/cuda/SciFi/common/include/SciFiDefinitions.cuh
+++ b/cuda/SciFi/common/include/SciFiDefinitions.cuh
@@ -8,7 +8,6 @@
 #include "device_launch_parameters.h"
 #include "Common.h"
 #include "Logger.h"
-#include "PrForwardConstants.cuh"
 #include "States.cuh"
 #include "SciFiRaw.cuh"
 
@@ -19,6 +18,97 @@ namespace SciFi {
   // need 3 arrays (size: number_of_events) for copy_and_prefix_sum_scifi_t
   static constexpr int num_atomics = 3;
 
+  namespace Tracking {
+
+    // The base PT threshold which is common to all algorithms
+    constexpr float minPt = 500 * Gaudi::Units::MeV; 
+
+    constexpr int max_scifi_hits = 20;  // for x and u/v layers
+    constexpr int nTrackParams = 9;
+
+    constexpr float tolYMag = 10. * Gaudi::Units::mm;
+    constexpr float tolYMagSlope = 0.015;
+
+    // parameterizations
+    constexpr float byParams = -0.667996;
+    constexpr float cyParams = -3.68424e-05;
+
+    // stereo hit matching
+    constexpr float tolYCollectX = 3.5 * Gaudi::Units::mm;        // 4.1* Gaudi::Units::mm ;
+    constexpr float tolYSlopeCollectX = 0.001 * Gaudi::Units::mm; // 0.0018 * Gaudi::Units::mm ;
+
+    // veloUT momentum estimate
+    constexpr bool useMomentumEstimate = true;
+    constexpr bool useWrongSignWindow = true;
+    constexpr float wrongSignPT = 2000. * Gaudi::Units::MeV;
+
+    // z Reference plane
+    constexpr float zReference = 8520. * Gaudi::Units::mm; // in T2
+    constexpr float zRefInv = 1.f / zReference; 
+
+    // TODO: CHECK THESE VALUES USING FRAMEWORK
+    constexpr float xLim_Max = 3300.;
+    constexpr float yLim_Max = 2500.;
+    constexpr float xLim_Min = -3300.;
+    constexpr float yLim_Min = -25.;
+
+    // TO BE READ FROM XML EVENTUALLY
+    //constexpr float magscalefactor = -1;
+    constexpr int zoneoffsetpar = 6;
+
+    struct Arrays {
+      // Returns whether the current layer is an X plane
+      const bool is_x_plane [12] {1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1};
+
+      // the Magnet Parametrization
+      // parameterized in offset [0], (slope difference due to kick)^2 [1],
+      // tx^2 [2], ty^2 [3]
+      const float zMagnetParams[4] = {5212.38, 406.609, -1102.35, -498.039};
+
+      // more Parametrizations
+      const float xParams[2] = {18.6195, -5.55793};
+
+      // momentum Parametrization
+      const float momentumParams[6] = {1.21014, 0.637339, -0.200292, 0.632298, 3.23793, -27.0259};
+
+      // covariance values
+      const float covarianceValues[5] = {4.0, 400.0, 4.e-6, 1.e-4, 0.1};
+
+      // definition of zones
+      // access upper with offset of 6
+      const int zoneoffsetpar = 6;
+      const int xZones[12] = {0, 6, 8, 14, 16, 22, 1, 7, 9, 15, 17, 23};
+      const int uvZones[12] = {2, 4, 10, 12, 18, 20, 3, 5, 11, 13, 19, 21};
+
+      // ASSORTED GEOMETRY VALUES, eventually read this from some xml
+      const float xZone_zPos[6] = {7826., 8036., 8508., 8718., 9193., 9403.};
+      const float uvZone_zPos[12] =
+        {7896., 7966., 8578., 8648., 9263., 9333., 7896., 7966., 8578., 8648., 9263., 9333.};
+      const float uvZone_dxdy[12] = {0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892};
+      const float Zone_dzdy[24] = {0.0036010};
+
+      // this is used by looking_forward_sbt maybe this is not the right place to put it
+      const float uv_dx[6] = {1.6739478541449213,
+                              1.6738495069872612,
+                              1.935683825160498,
+                              1.9529279746403518,
+                              2.246931985749485,
+                              2.2797556995480273};
+    };
+ 
+  } // namespace Tracking
+
   namespace Constants {
     // Detector description
     // There are three stations with four layers each
diff --git a/cuda/SciFi/consolidate/include/ConsolidateSciFi.cuh b/cuda/SciFi/consolidate/include/ConsolidateSciFi.cuh
index 5b0e020bf04..a1c667931fe 100644
--- a/cuda/SciFi/consolidate/include/ConsolidateSciFi.cuh
+++ b/cuda/SciFi/consolidate/include/ConsolidateSciFi.cuh
@@ -8,7 +8,6 @@
 #include "ArgumentsSciFi.cuh"
 #include "ArgumentsUT.cuh"
 #include "LFFitTools.cuh"
-#include "PrForwardConstants.cuh"
 #include "LookingForwardConstants.cuh"
 
 __global__ void consolidate_scifi_tracks(
diff --git a/cuda/SciFi/looking_forward_sbt/collect_candidates/include/LFCollectCandidates.cuh b/cuda/SciFi/looking_forward_sbt/collect_candidates/include/LFCollectCandidates.cuh
index 714fbdefea2..ea380fe634c 100644
--- a/cuda/SciFi/looking_forward_sbt/collect_candidates/include/LFCollectCandidates.cuh
+++ b/cuda/SciFi/looking_forward_sbt/collect_candidates/include/LFCollectCandidates.cuh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "PrForwardConstants.cuh"
 #include "VeloConsolidated.cuh"
 #include "UTConsolidated.cuh"
 #include "SciFiEventModel.cuh"
diff --git a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindows.cuh b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindows.cuh
index 7d9cfc74da2..bea4cd10a88 100644
--- a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindows.cuh
+++ b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindows.cuh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "PrForwardConstants.cuh"
 #include "VeloConsolidated.cuh"
 #include "UTConsolidated.cuh"
 #include "SciFiEventModel.cuh"
@@ -11,6 +10,7 @@
 #include "ArgumentsSciFi.cuh"
 #include "LookingForwardConstants.cuh"
 #include "LookingForwardTools.cuh"
+#include "TrackUtils.cuh"
 
 __global__ void lf_search_initial_windows(
   uint32_t* dev_scifi_hits,
diff --git a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
index 1e9f9fb7dd2..648593a11c1 100644
--- a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
+++ b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
@@ -6,14 +6,10 @@
 #include <algorithm>
 #include <fstream>
 #include "SciFiDefinitions.cuh"
-#include "PrForwardConstants.cuh"
 #include "UTDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "HitUtils.cuh"
-#include "LinearFitting.cuh"
-#include "ReferencePlaneProjection.cuh"
 #include "SciFiEventModel.cuh"
 #include "LookingForwardUtils.h"
+#include "TrackUtils.cuh"
 
 __device__ inline float evalCubicParameterization(
   const float value_at_ref,
diff --git a/cuda/SciFi/looking_forward_sbt/triplet_keep_best/include/LFTripletKeepBest.cuh b/cuda/SciFi/looking_forward_sbt/triplet_keep_best/include/LFTripletKeepBest.cuh
index db399acff6c..7ed714930fa 100644
--- a/cuda/SciFi/looking_forward_sbt/triplet_keep_best/include/LFTripletKeepBest.cuh
+++ b/cuda/SciFi/looking_forward_sbt/triplet_keep_best/include/LFTripletKeepBest.cuh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "PrForwardConstants.cuh"
 #include "VeloConsolidated.cuh"
 #include "UTConsolidated.cuh"
 #include "SciFiEventModel.cuh"
diff --git a/cuda/SciFi/looking_forward_sbt/triplet_seeding/include/LFTripletSeeding.cuh b/cuda/SciFi/looking_forward_sbt/triplet_seeding/include/LFTripletSeeding.cuh
index 3d7473cb80e..f5ff86367b6 100644
--- a/cuda/SciFi/looking_forward_sbt/triplet_seeding/include/LFTripletSeeding.cuh
+++ b/cuda/SciFi/looking_forward_sbt/triplet_seeding/include/LFTripletSeeding.cuh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "PrForwardConstants.cuh"
 #include "VeloConsolidated.cuh"
 #include "UTConsolidated.cuh"
 #include "SciFiEventModel.cuh"
diff --git a/cuda/SciFi/looking_forward_sbt/triplet_seeding/src/LFTripletSeeding.cu b/cuda/SciFi/looking_forward_sbt/triplet_seeding/src/LFTripletSeeding.cu
index 89c5be42c4c..53e60f89895 100644
--- a/cuda/SciFi/looking_forward_sbt/triplet_seeding/src/LFTripletSeeding.cu
+++ b/cuda/SciFi/looking_forward_sbt/triplet_seeding/src/LFTripletSeeding.cu
@@ -1,6 +1,5 @@
 #include "LFTripletSeeding.cuh"
 #include "LFTripletSeedingImpl.cuh"
-#include "TrackUtils.cuh"
 #include "LookingForwardTools.cuh"
 
 __global__ void lf_triplet_seeding(
diff --git a/cuda/SciFi/utils/README.md b/cuda/SciFi/utils/README.md
new file mode 100644
index 00000000000..18a329b1a23
--- /dev/null
+++ b/cuda/SciFi/utils/README.md
@@ -0,0 +1 @@
+# Contains utility functions useful in the SciFi reconstruction
diff --git a/cuda/SciFi/utils/include/HitUtils.cuh b/cuda/SciFi/utils/include/HitUtils.cuh
new file mode 100644
index 00000000000..f6c4f004917
--- /dev/null
+++ b/cuda/SciFi/utils/include/HitUtils.cuh
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "SciFiDefinitions.cuh"
+#include "SciFiEventModel.cuh"
+
+// match stereo hits to x hits
+__host__ __device__ bool matchStereoHit(
+  const int itUV1,
+  const int uv_zone_offset_end,
+  const SciFi::Hits& scifi_hits,
+  const float xMinUV,
+  const float xMaxUV);
+
+// check that val is within [min, max]
+__host__ __device__ inline bool isInside(float val, const float min, const float max)
+{
+  return (val > min) && (val < max);
+}
+
+// get lowest index where range[index] > value, within [start,end] of range
+__host__ __device__ inline int getLowerBound(float range[], float value, int start, int end)
+{
+  int i = start;
+  for (; i < end; i++) {
+    if (range[i] > value) break;
+  }
+  return i;
+}
diff --git a/cuda/SciFi/utils/include/TrackUtils.cuh b/cuda/SciFi/utils/include/TrackUtils.cuh
new file mode 100644
index 00000000000..d50dbeaf262
--- /dev/null
+++ b/cuda/SciFi/utils/include/TrackUtils.cuh
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <cmath>
+#include "SciFiEventModel.cuh"
+#
+/**
+   Helper functions related to track properties
+ */
+
+// extrapolate x position from given state to z
+__host__ __device__ float xFromVelo(const float z, const MiniState& velo_state);
+
+// extrapolate y position from given state to z
+__host__ __device__ float yFromVelo(const float z, const MiniState& velo_state);
+
+__host__ __device__ float evalCubicParameterization(const float params[4], float z);
+
+__host__ __device__ float zMagnet(const MiniState& velo_state, const SciFi::Tracking::Arrays* constArrays);
+
+__host__ __device__ float calcDxRef(float pt, const MiniState& velo_state);
+
+__host__ __device__ float calcqOverP(float bx, const SciFi::Tracking::Arrays* constArrays, const MiniState& velo_state, const float magnet_polarity);
+
+__host__ __device__ float evalParameterizationX(const float* params, float z);
+
+__host__ __device__ float evalParameterizationY(const float* params, float z);
+
+__host__ __device__ void getTrackParameters(
+  float xAtRef,
+  const MiniState& velo_state,
+  const SciFi::Tracking::Arrays* constArrays,
+  float trackParams[SciFi::Tracking::nTrackParams]);
+
+__host__ __device__ float
+trackToHitDistance(const float trackParameters[SciFi::Tracking::nTrackParams], const SciFi::Hits& scifi_hits, int hit);
diff --git a/cuda/SciFi/utils/src/HitUtils.cu b/cuda/SciFi/utils/src/HitUtils.cu
new file mode 100644
index 00000000000..722efa6bad2
--- /dev/null
+++ b/cuda/SciFi/utils/src/HitUtils.cu
@@ -0,0 +1,17 @@
+#include "HitUtils.cuh"
+
+// match stereo hits to x hits
+__host__ __device__ bool matchStereoHit(
+  const int itUV1,
+  const int uv_zone_offset_end,
+  const SciFi::Hits& scifi_hits,
+  const float xMinUV,
+  const float xMaxUV)
+{
+  for (int stereoHit = itUV1; stereoHit != uv_zone_offset_end; ++stereoHit) {
+    if (scifi_hits.x0[stereoHit] > xMinUV) {
+      return (scifi_hits.x0[stereoHit] < xMaxUV);
+    }
+  }
+  return false;
+}
diff --git a/cuda/SciFi/utils/src/TrackUtils.cu b/cuda/SciFi/utils/src/TrackUtils.cu
new file mode 100644
index 00000000000..69c0066c00b
--- /dev/null
+++ b/cuda/SciFi/utils/src/TrackUtils.cu
@@ -0,0 +1,108 @@
+#include "TrackUtils.cuh"
+
+// extrapolate x position from given state to z
+__host__ __device__ float xFromVelo(const float z, const MiniState& velo_state)
+{
+  return velo_state.x + (z - velo_state.z) * velo_state.tx;
+}
+
+// extrapolate y position from given state to z
+__host__ __device__ float yFromVelo(const float z, const MiniState& velo_state)
+{
+  return velo_state.y + (z - velo_state.z) * velo_state.ty;
+}
+
+__host__ __device__ float evalCubicParameterization(const float params[4], float z)
+{
+  float dz = z - SciFi::Tracking::zReference;
+  return params[0] + (params[1] + (params[2] + params[3] * dz) * dz) * dz;
+}
+
+// Find z zMag position within the magnet at which the bending ("kick") occurs
+// this is parameterized based on MC
+// the second parameter([1]) is multiplied by the difference in slope before and
+// after the kick, this slope is calculated from zMag and the x position of the track
+// at the reference plane -> it is calculated iteratively later
+__host__ __device__ float zMagnet(const MiniState& velo_state, const SciFi::Tracking::Arrays* constArrays)
+{
+
+  return (
+    constArrays->zMagnetParams[0] + constArrays->zMagnetParams[2] * velo_state.tx * velo_state.tx +
+    constArrays->zMagnetParams[3] * velo_state.ty * velo_state.ty);
+}
+
+// calculate difference between straight line extrapolation and
+// where a track with wrongSignPT (2 GeV) would be on the reference plane (?)
+__host__ __device__ float calcDxRef(float pt, const MiniState& velo_state)
+{
+  const float tx2 = velo_state.tx * velo_state.tx;
+  const float ty2 = velo_state.ty * velo_state.ty;
+  float m_slope2 = tx2 + ty2;
+  return 3973000.f * sqrtf(m_slope2) / pt - 2200.f * ty2 - 1000.f * tx2; // tune this window
+}
+
+__host__ __device__ float calcqOverP(float bx, const SciFi::Tracking::Arrays* constArrays, const MiniState& velo_state, const float magnet_polarity)
+{
+
+  float qop = 1.0f / Gaudi::Units::GeV;
+  const float bx2 = bx * bx;
+  const float ty2 = velo_state.ty * velo_state.ty;
+  const float coef =
+    (constArrays->momentumParams[0] + constArrays->momentumParams[1] * bx2 +
+     constArrays->momentumParams[2] * bx2 * bx2 + constArrays->momentumParams[3] * bx * velo_state.tx +
+     constArrays->momentumParams[4] * ty2 + constArrays->momentumParams[5] * ty2 * ty2);
+  const float tx2 = velo_state.tx * velo_state.tx;
+  float m_slope2 = tx2 + ty2;
+  float proj = sqrtf((1.f + m_slope2) / (1.f + tx2));
+  qop = (velo_state.tx - bx) / (coef * Gaudi::Units::GeV * proj * magnet_polarity);
+  return qop;
+}
+
+__host__ __device__ float evalParameterizationX(const float* params, float z)
+{
+  const float dz = z - SciFi::Tracking::zReference;
+  return params[0] + (params[1] + (params[2] + params[3] * dz) * dz) * dz;
+}
+
+__host__ __device__ float evalParameterizationY(const float* params, float z)
+{
+  const float dz = z - SciFi::Tracking::zReference;
+  return params[0] + (params[1] + params[2] * dz) * dz;
+}
+
+__host__ __device__ void getTrackParameters(
+  float xAtRef,
+  const MiniState& velo_state,
+  const SciFi::Tracking::Arrays* constArrays,
+  float trackParams[SciFi::Tracking::nTrackParams])
+{
+  float dSlope = (xFromVelo(SciFi::Tracking::zReference, velo_state) - xAtRef) /
+                 (SciFi::Tracking::zReference - constArrays->zMagnetParams[0]);
+  const float zMagSlope = constArrays->zMagnetParams[2] * velo_state.tx * velo_state.tx +
+                          constArrays->zMagnetParams[3] * velo_state.ty * velo_state.ty;
+  const float zMag = constArrays->zMagnetParams[0] + constArrays->zMagnetParams[1] * dSlope * dSlope + zMagSlope;
+  const float xMag = xFromVelo(zMag, velo_state);
+  const float slopeT = (xAtRef - xMag) / (SciFi::Tracking::zReference - zMag);
+  dSlope = slopeT - velo_state.tx;
+  const float dyCoef = dSlope * dSlope * velo_state.ty;
+
+  trackParams[0] = xAtRef;
+  trackParams[1] = slopeT;
+  trackParams[2] = 1.e-6f * constArrays->xParams[0] * dSlope;
+  trackParams[3] = 1.e-9f * constArrays->xParams[1] * dSlope;
+  trackParams[4] = yFromVelo(SciFi::Tracking::zReference, velo_state);
+  trackParams[5] = velo_state.ty + dyCoef * SciFi::Tracking::byParams;
+  trackParams[6] = dyCoef * SciFi::Tracking::cyParams;
+  trackParams[7] = 0.0f;
+  trackParams[8] = 0.0f; // last elements are chi2 and ndof, as float
+}
+
+__host__ __device__ float
+trackToHitDistance(const float trackParameters[SciFi::Tracking::nTrackParams], const SciFi::Hits& scifi_hits, int hit)
+{
+  const float z_Hit = scifi_hits.z0[hit] + scifi_hits.dzdy(hit) * evalParameterizationY(trackParameters + 4, scifi_hits.z0[hit]);
+  const float x_track = evalParameterizationX(trackParameters, z_Hit);
+  const float y_track = evalParameterizationY(trackParameters + 4, z_Hit);
+  return scifi_hits.x0[hit] + y_track * scifi_hits.dxdy(hit) - x_track;
+}
+
diff --git a/cuda/associate/CMakeLists.txt b/cuda/associate/CMakeLists.txt
index 76f5d2e27f5..b1575b153dd 100644
--- a/cuda/associate/CMakeLists.txt
+++ b/cuda/associate/CMakeLists.txt
@@ -3,7 +3,6 @@ include_directories(include)
 include_directories(${CMAKE_SOURCE_DIR}/main/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/associate/include)
diff --git a/cuda/global_event_cut/CMakeLists.txt b/cuda/global_event_cut/CMakeLists.txt
index 83074cb4f61..3bc76e4076c 100644
--- a/cuda/global_event_cut/CMakeLists.txt
+++ b/cuda/global_event_cut/CMakeLists.txt
@@ -7,7 +7,6 @@ include_directories(include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 
 add_library(GlobalEventCut STATIC
   ${global_event_cut}
diff --git a/cuda/kalman/CMakeLists.txt b/cuda/kalman/CMakeLists.txt
index 0bc451b61a8..74984fa38de 100644
--- a/cuda/kalman/CMakeLists.txt
+++ b/cuda/kalman/CMakeLists.txt
@@ -3,7 +3,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/PrVeloUT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
diff --git a/cuda/muon/CMakeLists.txt b/cuda/muon/CMakeLists.txt
index cbc307e0873..883b67a6a10 100644
--- a/cuda/muon/CMakeLists.txt
+++ b/cuda/muon/CMakeLists.txt
@@ -13,7 +13,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/main/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/utils/sorting/include)
diff --git a/cuda/selections/CMakeLists.txt b/cuda/selections/CMakeLists.txt
index b8d89779947..2f217ccbb0e 100644
--- a/cuda/selections/CMakeLists.txt
+++ b/cuda/selections/CMakeLists.txt
@@ -6,7 +6,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/beamlinePV/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/vertex_fit/common/include)
diff --git a/cuda/utils/CMakeLists.txt b/cuda/utils/CMakeLists.txt
index 9abefb046fd..172e35a1b19 100644
--- a/cuda/utils/CMakeLists.txt
+++ b/cuda/utils/CMakeLists.txt
@@ -14,7 +14,6 @@ include_directories(${CMAKE_SOURCE_DIR}/stream/gear/include)
 include_directories(${CMAKE_SOURCE_DIR}/stream/setup/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/muon/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/muon/decoding/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/kalman/ParKalman/include)
diff --git a/cuda/vertex_fit/CMakeLists.txt b/cuda/vertex_fit/CMakeLists.txt
index eb692eea66f..46dd03486d4 100644
--- a/cuda/vertex_fit/CMakeLists.txt
+++ b/cuda/vertex_fit/CMakeLists.txt
@@ -7,7 +7,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/beamlinePV/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/main/include)
diff --git a/integration/non_event_data/CMakeLists.txt b/integration/non_event_data/CMakeLists.txt
index f71b3d37713..fc4d404fce2 100644
--- a/integration/non_event_data/CMakeLists.txt
+++ b/integration/non_event_data/CMakeLists.txt
@@ -11,7 +11,7 @@ target_include_directories(NonEventData PUBLIC
   ${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include
   ${CMAKE_SOURCE_DIR}/cuda/muon/common/include
   ${CMAKE_SOURCE_DIR}/cuda/muon/decoding/include
-  ${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include
+  ${CMAKE_SOURCE_DIR}/cuda/SciFi/classifiers/include
   ${CMAKE_SOURCE_DIR}/cuda/UT/common/include
   ${CMAKE_SOURCE_DIR}/stream/sequence/include
   ${CMAKE_SOURCE_DIR}/checker/tracking/include
diff --git a/mdf/CMakeLists.txt b/mdf/CMakeLists.txt
index 3530c43f690..fa2a3beff39 100644
--- a/mdf/CMakeLists.txt
+++ b/mdf/CMakeLists.txt
@@ -58,7 +58,6 @@ target_include_directories(${name} PUBLIC
   ${CMAKE_SOURCE_DIR}/cuda/velo/common/include
   ${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include
   ${CMAKE_SOURCE_DIR}/cuda/muon/common/include
-  ${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include
   ${CMAKE_SOURCE_DIR}/cuda/UT/common/include
   ${CMAKE_SOURCE_DIR}/cuda/UT/PrVeloUT/include
   ${CMAKE_SOURCE_DIR}/checker/tracking/include)
diff --git a/stream/CMakeLists.txt b/stream/CMakeLists.txt
index 6477e2a843f..6f5a2a053bd 100644
--- a/stream/CMakeLists.txt
+++ b/stream/CMakeLists.txt
@@ -29,7 +29,8 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/search_by_triplet/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/simplified_kalman_filter/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/preprocessing/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/classifiers/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/utils/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/calculate_first_layer_window/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/calculate_second_layer_window/include)
@@ -66,7 +67,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/muon/decoding/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/velo/clustering/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/UT/PrVeloUT/include)
-include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/LookingForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/MomentumForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/PV/beamlinePV/include)
@@ -145,7 +145,6 @@ target_link_libraries(Stream PRIVATE
   Hlt1
   SciFi
   x86MuonDecoding
-  x86Forward
   x86LookingForward
   x86MomentumForward
   x86VeloUT
diff --git a/stream/checkers/include/SciFiSequenceCheckers_impl.cuh b/stream/checkers/include/SciFiSequenceCheckers_impl.cuh
index a7c2dc91093..0e45cf34c66 100644
--- a/stream/checkers/include/SciFiSequenceCheckers_impl.cuh
+++ b/stream/checkers/include/SciFiSequenceCheckers_impl.cuh
@@ -1,5 +1,4 @@
-#include "PrForward.cuh"
-#include "RunForwardCPU.h"
+#include "PrepareTracks.h"
 
 /**
  * @brief Specialization when invoking scifi_pr_forward_t as last step.
diff --git a/stream/checkers/include/UTSequenceCheckers_impl.cuh b/stream/checkers/include/UTSequenceCheckers_impl.cuh
index 0e23020ac00..44912186e87 100644
--- a/stream/checkers/include/UTSequenceCheckers_impl.cuh
+++ b/stream/checkers/include/UTSequenceCheckers_impl.cuh
@@ -1,6 +1,7 @@
 #include "MomentumForwardStudies.h"
 #include "LookingForwardStudies.h"
 #include "TrackChecker.h"
+#include "PrepareTracks.h"
 
 /**
  * @brief Specialization for any Velo reconstruction algorithm invoking
diff --git a/stream/checkers/include/VeloSequenceCheckers_impl.cuh b/stream/checkers/include/VeloSequenceCheckers_impl.cuh
index 0e6473b07ed..e008f10635a 100644
--- a/stream/checkers/include/VeloSequenceCheckers_impl.cuh
+++ b/stream/checkers/include/VeloSequenceCheckers_impl.cuh
@@ -1,5 +1,6 @@
 #include "ConsolidateVelo.cuh"
 #include "TrackChecker.h"
+#include "PrepareTracks.h"
 
 /**
  * @brief Specialization for any Velo reconstruction algorithm invoking
diff --git a/stream/sequence/include/Constants.cuh b/stream/sequence/include/Constants.cuh
index ba0f286ea8a..420592d5a5a 100644
--- a/stream/sequence/include/Constants.cuh
+++ b/stream/sequence/include/Constants.cuh
@@ -8,7 +8,6 @@
 #include "VeloDefinitions.cuh"
 #include "ClusteringDefinitions.cuh"
 #include "ClusteringCommon.h"
-#include "PrForwardConstants.cuh"
 #include "TMVA_Forward_1.cuh"
 #include "TMVA_Forward_2.cuh"
 #include "UTDefinitions.cuh"
diff --git a/stream/setup/include/ConfiguredSequence.cuh b/stream/setup/include/ConfiguredSequence.cuh
index 343e9d16e75..e90f0c6f500 100644
--- a/stream/setup/include/ConfiguredSequence.cuh
+++ b/stream/setup/include/ConfiguredSequence.cuh
@@ -28,7 +28,6 @@
 #include "ConsolidateSciFi.cuh"
 #include "SearchWindows.cuh"
 #include "CompassUT.cuh"
-#include "PrForward.cuh"
 #include "VeloKalmanFilter.cuh"
 #include "GetSeeds.cuh"
 #include "FitSeeds.cuh"
@@ -37,7 +36,6 @@
 #include "pv_beamline_peak.cuh"
 #include "pv_beamline_multi_fitter.cuh"
 #include "pv_beamline_cleanup.cuh"
-#include "RunForwardCPU.h"
 #include "VeloPVIP.cuh"
 #include "RunMomentumForwardCPU.h"
 #include "RunBeamlinePVOnCPU.h"
diff --git a/stream/visitors/SciFi/src/CpuSciFiMomentumForwardVisitor.cu b/stream/visitors/SciFi/src/CpuSciFiMomentumForwardVisitor.cu
index 89d519545dd..3213fa293fe 100644
--- a/stream/visitors/SciFi/src/CpuSciFiMomentumForwardVisitor.cu
+++ b/stream/visitors/SciFi/src/CpuSciFiMomentumForwardVisitor.cu
@@ -1,5 +1,4 @@
 #include "SequenceVisitor.cuh"
-#include "RunForwardCPU.h"
 #include "RunMomentumForwardCPU.h"
 #include "Tools.h"
 
diff --git a/stream/visitors/SciFi/src/CpuSciFiPrForwardVisitor.cu b/stream/visitors/SciFi/src/CpuSciFiPrForwardVisitor.cu
deleted file mode 100644
index e3c32bb50bf..00000000000
--- a/stream/visitors/SciFi/src/CpuSciFiPrForwardVisitor.cu
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "SequenceVisitor.cuh"
-#include "RunForwardCPU.h"
-#include "Tools.h"
-
-template<>
-void SequenceVisitor::set_arguments_size<cpu_scifi_pr_forward_t>(
-  cpu_scifi_pr_forward_t::arguments_t arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  const HostBuffers& host_buffers)
-{
-  arguments.set_size<dev_scifi_tracks>(host_buffers.host_number_of_reconstructed_ut_tracks[0] * SciFi::Constants::max_SciFi_tracks_per_UT_track);
-  arguments.set_size<dev_atomics_scifi>(host_buffers.host_number_of_selected_events[0] * SciFi::num_atomics);
-}
-
-template<>
-void SequenceVisitor::visit<cpu_scifi_pr_forward_t>(
-  cpu_scifi_pr_forward_t& state,
-  const cpu_scifi_pr_forward_t::arguments_t& arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  HostBuffers& host_buffers,
-  cudaStream_t& cuda_stream,
-  cudaEvent_t& cuda_generic_event)
-{
-  // Synchronize previous CUDA transmissions
-  cudaEventRecord(cuda_generic_event, cuda_stream);
-  cudaEventSynchronize(cuda_generic_event);
-
-  // Run Forward on x86 architecture
-  // ATTENTION: when using SciFi raw bank version 5,
-  // need: 2*host_buffers.host_number_of_selected_events[0]*...
-  host_buffers.host_velo_states.resize(arguments.size<dev_velo_states>());
-  host_buffers.host_scifi_hits.resize(arguments.size<dev_scifi_hits>());
-  host_buffers.host_scifi_hit_count.resize(arguments.size<dev_scifi_hit_count>());
-
-  cudaCheck(cudaMemcpy(
-    host_buffers.host_scifi_hits.data(),
-    arguments.offset<dev_scifi_hits>(),
-    arguments.size<dev_scifi_hits>(),
-    cudaMemcpyDeviceToHost));
-
-  cudaCheck(cudaMemcpy(
-    host_buffers.host_scifi_hit_count.data(),
-    arguments.offset<dev_scifi_hit_count>(),
-    arguments.size<dev_scifi_hit_count>(),
-    cudaMemcpyDeviceToHost));
-
-  cudaCheck(cudaMemcpy(
-    host_buffers.host_velo_states.data(),
-    arguments.offset<dev_velo_states>(),
-    arguments.size<dev_velo_states>(),
-    cudaMemcpyDeviceToHost));
-
-  // TODO: Maybe use this rv somewhere?
-  int rv = state.invoke(
-    host_buffers.scifi_tracks_events.data(),
-    host_buffers.host_atomics_scifi,
-    host_buffers.host_scifi_hits.data(),
-    host_buffers.host_scifi_hit_count.data(),
-    constants.host_scifi_geometry.data(),
-    constants.host_inv_clus_res,
-    host_buffers.host_atomics_velo,
-    host_buffers.host_velo_track_hit_number,
-    host_buffers.host_velo_states.data(),
-    host_buffers.host_atomics_ut,
-    host_buffers.host_ut_track_hit_number,
-    host_buffers.host_ut_qop,
-    host_buffers.host_ut_track_velo_indices,
-    host_buffers.host_number_of_selected_events[0]);
-
-  if (logger::ll.verbosityLevel >= logger::debug) {
-    for (int i = 0; i < host_buffers.host_number_of_selected_events[0]; ++i) {
-      debug_cout << "Visitor: found " << host_buffers.host_atomics_scifi[i] << " tracks in event " << i << std::endl;
-    }
-  }
-
-  // copy SciFi track to device for consolidation
-  cudaCheck(cudaMemcpy(
-    arguments.offset<dev_atomics_scifi>(),
-    host_buffers.host_atomics_scifi,
-    arguments.size<dev_atomics_scifi>(),
-    cudaMemcpyHostToDevice));
-
-  cudaCheck(cudaMemcpy(
-    arguments.offset<dev_scifi_tracks>(),
-    host_buffers.scifi_tracks_events.data(),
-    arguments.size<dev_scifi_tracks>(),
-    cudaMemcpyHostToDevice));
-}
diff --git a/stream/visitors/SciFi/src/SciFiPrForwardVisitor.cu b/stream/visitors/SciFi/src/SciFiPrForwardVisitor.cu
deleted file mode 100644
index e9664d732fc..00000000000
--- a/stream/visitors/SciFi/src/SciFiPrForwardVisitor.cu
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "PrForward.cuh"
-#include "SequenceVisitor.cuh"
-
-template<>
-void SequenceVisitor::set_arguments_size<scifi_pr_forward_t>(
-  scifi_pr_forward_t::arguments_t arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  const HostBuffers& host_buffers)
-{
-  arguments.set_size<dev_scifi_tracks>(host_buffers.host_number_of_reconstructed_ut_tracks[0] * SciFi::Constants::max_SciFi_tracks_per_UT_track);
-  arguments.set_size<dev_atomics_scifi>(host_buffers.host_number_of_selected_events[0] * SciFi::num_atomics);
-}
-
-template<>
-void SequenceVisitor::visit<scifi_pr_forward_t>(
-  scifi_pr_forward_t& state,
-  const scifi_pr_forward_t::arguments_t& arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  HostBuffers& host_buffers,
-  cudaStream_t& cuda_stream,
-  cudaEvent_t& cuda_generic_event)
-{
-  state.set_opts(dim3(host_buffers.host_number_of_selected_events[0]), dim3(32), cuda_stream);
-  state.set_arguments(
-    arguments.offset<dev_scifi_hits>(),
-    arguments.offset<dev_scifi_hit_count>(),
-    arguments.offset<dev_atomics_velo>(),
-    arguments.offset<dev_velo_track_hit_number>(),
-    arguments.offset<dev_velo_states>(),
-    arguments.offset<dev_atomics_ut>(),
-    arguments.offset<dev_ut_track_hits>(),
-    arguments.offset<dev_ut_track_hit_number>(),
-    arguments.offset<dev_ut_qop>(),
-    arguments.offset<dev_ut_track_velo_indices>(),
-    arguments.offset<dev_scifi_tracks>(),
-    arguments.offset<dev_atomics_scifi>(),
-    constants.dev_scifi_tmva1,
-    constants.dev_scifi_tmva2,
-    constants.dev_scifi_constArrays,
-    constants.dev_magnet_polarity,
-    constants.dev_scifi_geometry,
-    constants.dev_inv_clus_res);
-
-  state.invoke();
-
-}
diff --git a/x86/SciFi/CMakeLists.txt b/x86/SciFi/CMakeLists.txt
index d0bfdc8dab9..22cebb5eb65 100644
--- a/x86/SciFi/CMakeLists.txt
+++ b/x86/SciFi/CMakeLists.txt
@@ -1,3 +1,2 @@
-add_subdirectory(PrForward)
 add_subdirectory(LookingForward)
 add_subdirectory(MomentumForward)
diff --git a/x86/SciFi/LookingForward/CMakeLists.txt b/x86/SciFi/LookingForward/CMakeLists.txt
index 7537e4ec159..340f5b4f9b0 100644
--- a/x86/SciFi/LookingForward/CMakeLists.txt
+++ b/x86/SciFi/LookingForward/CMakeLists.txt
@@ -12,7 +12,8 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/classifiers/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/utils/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/utils/binary_search/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/common/include)
 include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
diff --git a/x86/SciFi/LookingForward/include/LookingForwardConstants.h b/x86/SciFi/LookingForward/include/LookingForwardConstants.h
index 230c6dfe258..a28950c5dce 100644
--- a/x86/SciFi/LookingForward/include/LookingForwardConstants.h
+++ b/x86/SciFi/LookingForward/include/LookingForwardConstants.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "SystemOfUnits.h"
-#include "PrForwardConstants.cuh"
+#include "SciFiDefinitions.cuh"
 
 namespace SciFi {
   namespace LookingForward {
diff --git a/x86/SciFi/LookingForward/include/LookingForwardSbt.h b/x86/SciFi/LookingForward/include/LookingForwardSbt.h
index bfaca590320..c358457f18d 100644
--- a/x86/SciFi/LookingForward/include/LookingForwardSbt.h
+++ b/x86/SciFi/LookingForward/include/LookingForwardSbt.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "LookingForwardUtils.h"
-#include "FindXHits.cuh"
+#include "HitUtils.cuh"
 
 // Quick class for tracklets
 struct Tracklet {
diff --git a/x86/SciFi/LookingForward/include/LookingForwardStudies.h b/x86/SciFi/LookingForward/include/LookingForwardStudies.h
index d5c321362ff..5cd489bdf63 100644
--- a/x86/SciFi/LookingForward/include/LookingForwardStudies.h
+++ b/x86/SciFi/LookingForward/include/LookingForwardStudies.h
@@ -19,6 +19,7 @@
 #include "UTConsolidated.cuh"
 #include "SciFiDefinitions.cuh"
 #include "SciFiParametrization.h"
+#include "TrackUtils.cuh"
 
 #include "LookingForwardUtils.h"
 #include "LookingForwardConstants.h"
diff --git a/x86/SciFi/LookingForward/include/LookingForwardUtils.h b/x86/SciFi/LookingForward/include/LookingForwardUtils.h
index 73a0380587b..8257b48e94b 100644
--- a/x86/SciFi/LookingForward/include/LookingForwardUtils.h
+++ b/x86/SciFi/LookingForward/include/LookingForwardUtils.h
@@ -9,13 +9,13 @@
 
 #include <cassert>
 
+#include "HitUtils.cuh"
 #include "SciFiDefinitions.cuh"
 #include "SciFiEventModel.cuh"
 #include "LookingForwardConstants.h"
 #include "MomentumForwardUtils.h"
 #include "BinarySearch.cuh"
 #include "SciFiParametrization.h"
-#include "TrackUtils.cuh"
 #include "LookingForwardFitting.h"
 #include "TMVA_Forward.cuh"
 #include "TMVA_Forward_1.cuh"
@@ -225,3 +225,18 @@ void single_track_quality_update(
   const SciFi::Tracking::TMVA* tmva2,
   const SciFi::Hits& scifi_hits,
   const int event_offset);
+
+__host__ void collectAllXHits_proto_p(
+  const SciFi::Hits& scifi_hits,
+  const SciFi::HitCount& scifi_hit_count,
+  const SciFi::Tracking::Arrays* constArrays,
+  const float magnet_polarity,
+  const MiniState& velo_state,
+  const MiniState& UT_state,
+  const float qOverP,
+  int side, 
+  std::array<int, 2 * 6>& windows_x,
+  std::array<int, 2 * 6>& windows_uv,
+  std::array<float, 4 * 6>& parameters_uv,
+  const SciFiWindowsParams& window_params,
+  const std::array<int, 12> true_scifi_indices_per_layer);
diff --git a/x86/SciFi/LookingForward/src/LookingForwardStudies.cpp b/x86/SciFi/LookingForward/src/LookingForwardStudies.cpp
index 7b9b15d6e38..2f9132fe01d 100644
--- a/x86/SciFi/LookingForward/src/LookingForwardStudies.cpp
+++ b/x86/SciFi/LookingForward/src/LookingForwardStudies.cpp
@@ -1,6 +1,4 @@
 #include "LookingForwardStudies.h"
-#include "TrackUtils.cuh"
-#include "FindXHits.cuh"
 #include "LookingForwardSbt.h"
 #include "LookingForwardConstants.cuh"
 #include <numeric>
diff --git a/x86/SciFi/LookingForward/src/LookingForwardUtils.cpp b/x86/SciFi/LookingForward/src/LookingForwardUtils.cpp
index fe1b294374c..a25c77b0a4f 100644
--- a/x86/SciFi/LookingForward/src/LookingForwardUtils.cpp
+++ b/x86/SciFi/LookingForward/src/LookingForwardUtils.cpp
@@ -924,3 +924,161 @@ void filter_tracks_with_TMVA(
     selected_tracks.push_back(tracks[best_track]);
   }
 }
+
+
+__host__ void collectAllXHits_proto_p(
+  const SciFi::Hits& scifi_hits,
+  const SciFi::HitCount& scifi_hit_count,
+  const SciFi::Tracking::Arrays* constArrays,
+  const float magnet_polarity,
+  const MiniState& velo_state,
+  const MiniState& UT_state,
+  const float qOverP,
+  int side,
+  std::array<int, 2 * 6>& windows_x,
+  std::array<int, 2 * 6>& windows_uv,
+  std::array<float, 4 * 6>& parameters_uv,
+  const SciFiWindowsParams& window_params,
+  const std::array<int, 12> true_scifi_indices_per_layer)
+{
+  const float tx2 = velo_state.tx*velo_state.tx;
+  const float ty2 = velo_state.ty*velo_state.ty;
+  const float slope2 = tx2 + ty2;
+  const float pt = sqrtf(slope2 / (1.f + slope2) ) / fabsf(qOverP);
+  const float p = 1.f / std::abs(qOverP);
+
+  /* OPTIMIZE: possibly use these variables for wrong sign treatment */
+  // const float q = qOverP > 0.f ? 1.f : -1.f;
+  // const bool wSignTreatment = pt > SciFi::Tracking::wrongSignPT;
+  // float zMag = zMagnet(velo_state, constArrays);
+  // const float qop_WS = sqrtf(slope2 / (1.f + slope2) ) / pt;
+  // float dxRefWS = 0.f;
+  // if ( wSignTreatment ) {
+  //   dxRefWS = 0.9f * calcDxRef(SciFi::Tracking::wrongSignPT, velo_state);
+  // }
+  // const float dir = q * SciFi::Tracking::magscalefactor * (-1.f); // needed for wrong sign treatment
+  // const float xTolWS = dx_calc(velo_state, qop_WS, window_params);
+
+  //const float q = qOverP > 0.f ? 1.f : -1.f;
+  //const float dir = q * magnet_polarity * (-1.f);
+
+  //const bool wSignTreatment = pt > SciFi::Tracking::wrongSignPT;
+  float zMag = zMagnet(velo_state, constArrays);
+  const float qop_WS = sqrtf(slope2 / (1.f + slope2) ) / pt;
+  // float dxRefWS = 0.f;
+  // if ( wSignTreatment ) {
+  //   dxRefWS = 0.9f * calcDxRef(SciFi::Tracking::wrongSignPT, velo_state);
+  // }
+  const float xAtRef = xFromVelo(SciFi::Tracking::zReference, UT_state);
+  float xParams_seed[4] {xAtRef, UT_state.tx, 0, 0};
+
+  // use parametrization to propagate from UT to SciFi
+  const auto state_zRef = propagate_state_from_velo(UT_state, qOverP, 5);  // zRef is between layers 4 and 5
+  const float xTol = dx_calc(velo_state, qOverP, window_params);
+  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
+
+  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
+    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
+    assert(iZone - iZoneStartingPoint < 12);
+
+    const auto izone_rel = iZone - iZoneStartingPoint;
+    const float zZone = constArrays->xZone_zPos[izone_rel];
+
+    //const int layer = constArrays->xZones[iZone] / 2;
+    const float dz_x = (zZone - SciFi::Tracking::zReference);
+    const float xInZone = scifi_propagation(state_zRef.x, UT_state.tx, qOverP, dz_x);
+    const float yInZone = yFromVelo(zZone, velo_state);
+
+    const float xInZoneStraight = evalCubicParameterization(xParams_seed, zZone);
+
+    if (side > 0) {
+      if (
+        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
+        !isInside(yInZone, SciFi::Tracking::yLim_Min, SciFi::Tracking::yLim_Max))
+        continue;
+    }
+    else {
+      if (
+        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
+        !isInside(yInZone, side * SciFi::Tracking::yLim_Max, side * SciFi::Tracking::yLim_Min))
+        continue;
+    }
+
+    float xMin = xInZone - xTol;
+    float xMax = xInZone + xTol;
+
+    /* OPTIMIZE: how do we take care of wrong sign tracks with momentum windows? */
+    //float xTolWS = 0.0;
+    // if (wSignTreatment) {
+    //   // xTolWS = (zZone < SciFi::Tracking::zReference) ?
+    //   //   dxRefWS * zZone / SciFi::Tracking::zReference :
+    //   //   dxRefWS * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
+    //   // if (dir > 0) {
+    //   //   xMin = xInZone - xTolWS;
+    //   // }
+    //   // else {
+    //   //   xMax = xInZone + xTolWS;
+    //   // }
+
+    //   debug_cout << "\t before WS treatment: xMin = " << xMin << ", xMax = " << xMax << ", WS = " << int(wSignTreatment) << ", pt = " << pt << std::endl;
+    //   if (dir > 0) {
+    //     xMin = -1.f * xInZone - xTolWS;
+    //   }
+    //   else {
+    //     xMax = xInZone + xTolWS;
+    //   }
+    //   debug_cout << "\t after WS treatment: xMin = " << xMin << ", xMax = " << xMax << std::endl;
+    // }
+
+    // Get the hits within the bounds
+    assert(iZone < SciFi::Constants::n_layers);
+    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
+    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
+    int x_zone_offset_end = x_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
+    const int itH = getLowerBound(scifi_hits.x0, xMin, x_zone_offset_begin, x_zone_offset_end);
+    const int itEnd = getLowerBound(scifi_hits.x0, xMax, x_zone_offset_begin, x_zone_offset_end);
+    assert(itH >= x_zone_offset_begin && itH <= x_zone_offset_end);
+    assert(itEnd >= x_zone_offset_begin && itEnd <= x_zone_offset_end);
+
+    windows_x[2*izone_rel] = itH;
+    windows_x[2*izone_rel+1] = itEnd - itH;
+
+    // Now match the stereo hits
+    const float this_uv_z = constArrays->uvZone_zPos[izone_rel];
+    const float dz_uv = this_uv_z - SciFi::Tracking::zReference;
+    const float yInUVZone = yFromVelo(this_uv_z, velo_state);
+    const float dx = yInUVZone * constArrays->uvZone_dxdy[izone_rel];
+    const float xPredUv = scifi_propagation(state_zRef.x, UT_state.tx, qOverP, dz_uv) - dx;
+    const int uv_layer = constArrays->uvZones[iZone] / 2;
+    // To Do: study this window
+    const float xBound = 70.f * window_params.extrapolation_stddev[uv_layer];
+    const float maxDx = xBound; // * ratio;
+
+    const float xMinUV = xPredUv - maxDx;
+    const float xMaxUV = xPredUv + maxDx;
+
+    // Get bounds in UV layers
+    // do one search on the same side as the x module
+    // if we are close to y = 0, also look within a region on the other side module ("triangle search")
+    assert(constArrays->uvZones[iZone] < SciFi::Constants::n_zones);
+    const int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[iZone]);
+    const int uv_zone_offset_end =
+      uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone]);
+    /* OPTIMIZE: check how large the effect on the efficiency is to include the triangle hits */
+    //    const int triangleOffset = side > 0 ? -1 : 1;
+    //assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
+    // const int triangle_zone_offset_begin =
+    //   scifi_hit_count.zone_offset(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
+    // assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
+    // const int triangle_zone_offset_end =
+    //   triangle_zone_offset_begin +
+    //   scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
+    int itUVStart = getLowerBound(scifi_hits.x0, xMinUV, uv_zone_offset_begin, uv_zone_offset_end);
+    int itUVEnd = getLowerBound(scifi_hits.x0, xMaxUV, uv_zone_offset_begin, uv_zone_offset_end);
+    //    int itUV2 = getLowerBound(scifi_hits.x0, xMinUV, triangle_zone_offset_begin, triangle_zone_offset_end);
+
+    windows_uv[2*izone_rel] = itUVStart;
+    windows_uv[2*izone_rel+1] = itUVEnd;
+
+  }
+}
diff --git a/x86/SciFi/MomentumForward/CMakeLists.txt b/x86/SciFi/MomentumForward/CMakeLists.txt
index 2c33bcd8195..ed98cb7844e 100644
--- a/x86/SciFi/MomentumForward/CMakeLists.txt
+++ b/x86/SciFi/MomentumForward/CMakeLists.txt
@@ -11,7 +11,7 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/classifiers/include)
 include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
 
 file(GLOB x86MomentumForward "src/*cpp" )
@@ -20,8 +20,6 @@ add_library(x86MomentumForward STATIC
   ${x86MomentumForward}
 )
 
-set_property(TARGET x86Forward PROPERTY
-             CUDA_SEPARABLE_COMPILATION ON)
 set_property(TARGET x86MomentumForward PROPERTY
              CUDA_RESOLVE_DEVICE_SYMBOLS ON)
 
diff --git a/x86/SciFi/MomentumForward/include/MomentumForwardConstants.h b/x86/SciFi/MomentumForward/include/MomentumForwardConstants.h
index 73bd1c667d8..a1cf1569f94 100644
--- a/x86/SciFi/MomentumForward/include/MomentumForwardConstants.h
+++ b/x86/SciFi/MomentumForward/include/MomentumForwardConstants.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "SystemOfUnits.h"
-#include "PrForwardConstants.cuh"
+#include "SciFiDefinitions.cuh"
 
 namespace SciFi {
   namespace MomentumForward {
diff --git a/x86/SciFi/PrForward/CMakeLists.txt b/x86/SciFi/PrForward/CMakeLists.txt
deleted file mode 100644
index 45de4aada34..00000000000
--- a/x86/SciFi/PrForward/CMakeLists.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-include_directories(include)
-include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/checker/tracking/include)
-include_directories(${CMAKE_SOURCE_DIR}/main/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/PrVeloUT/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/UTDecoding/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/utils/sorting)
-include_directories(${CMAKE_SOURCE_DIR}/stream/gear/include)
-include_directories(${CMAKE_SOURCE_DIR}/stream/setup/include)
-include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/LookingForward/include)
-include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/MomentumForward/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/utils/binary_search/include)
-
-
-file(GLOB x86Forward_src "src/*cpp")
-
-add_library(x86Forward STATIC
-  ${x86Forward_src}
-)
-
-set_property(TARGET x86Forward PROPERTY
-             CUDA_SEPARABLE_COMPILATION ON)
-set_property(TARGET x86Forward PROPERTY
-             CUDA_RESOLVE_DEVICE_SYMBOLS ON)
-
-if ( ROOT_FOUND )
-  target_compile_definitions(x86Forward PUBLIC WITH_ROOT)
-  target_include_directories(x86Forward BEFORE PRIVATE
-    ${ROOT_INCLUDE_DIRS}
-  )
-endif()
diff --git a/x86/SciFi/PrForward/include/PrForwardWrapper.h b/x86/SciFi/PrForward/include/PrForwardWrapper.h
deleted file mode 100644
index 058ffd00202..00000000000
--- a/x86/SciFi/PrForward/include/PrForwardWrapper.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include "PrForwardTools.cuh"
-
-void PrForwardWrapper(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const Velo::Consolidated::States& velo_states,
-  const uint event_tracks_offset,
-  const UT::Consolidated::Tracks& ut_tracks,
-  const int n_veloUT_tracks,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  SciFi::TrackHits outputTracks[SciFi::Constants::max_tracks],
-  uint* n_forward_tracks);
diff --git a/x86/SciFi/PrForward/include/RunForwardCPU.h b/x86/SciFi/PrForward/include/RunForwardCPU.h
deleted file mode 100644
index 8252af53601..00000000000
--- a/x86/SciFi/PrForward/include/RunForwardCPU.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include "Common.h"
-#include "VeloDefinitions.cuh"
-#include "TrackChecker.h"
-#include "PrForwardWrapper.h"
-#include "VeloEventModel.cuh"
-#include "CpuHandler.cuh"
-#include "PrepareTracks.h"
-#include "ArgumentsCommon.cuh"
-#include "ArgumentsVelo.cuh"
-#include "ArgumentsUT.cuh"
-#include "ArgumentsSciFi.cuh"
-
-int run_forward_on_CPU(
-  SciFi::TrackHits* host_scifi_tracks_events,
-  int* host_scifi_n_tracks,
-  const uint* host_scifi_hits,
-  const uint* host_scifi_hit_count,
-  const char* host_scifi_geometry,
-  const std::array<float, 9>& host_inv_clus_res,
-  const uint* host_velo_tracks_atomics,
-  const uint* host_velo_track_hit_number,
-  const char* host_velo_states,
-  const int* host_atomics_ut,
-  const uint* host_ut_track_hit_number,
-  const float* host_ut_qop,
-  const uint* host_ut_track_velo_indices,
-  const uint number_of_events);
-
-CPU_ALGORITHM(
-  run_forward_on_CPU,
-  cpu_scifi_pr_forward_t,
-  ARGUMENTS(
-    dev_scifi_tracks,
-    dev_atomics_scifi,
-    dev_scifi_selected_track_indices,
-    dev_scifi_hits,
-    dev_scifi_hit_count,
-    dev_atomics_velo,
-    dev_velo_track_hit_number,
-    dev_velo_states,
-    dev_atomics_ut,
-    dev_ut_track_hits,
-    dev_ut_track_hit_number,
-    dev_ut_qop,
-    dev_ut_track_velo_indices))
diff --git a/x86/SciFi/PrForward/src/PrForwardWrapper.cpp b/x86/SciFi/PrForward/src/PrForwardWrapper.cpp
deleted file mode 100644
index aeebab54bce..00000000000
--- a/x86/SciFi/PrForward/src/PrForwardWrapper.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "PrForwardWrapper.h"
-
-void PrForwardWrapper(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const Velo::Consolidated::States& velo_states,
-  const uint event_tracks_offset,
-  const UT::Consolidated::Tracks& ut_tracks,
-  const int n_veloUT_tracks,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  SciFi::TrackHits outputTracks[SciFi::Constants::max_tracks],
-  uint* n_forward_tracks)
-{
-  // Loop over the veloUT input tracks
-  for (int i_veloUT_track = 0; i_veloUT_track < n_veloUT_tracks; ++i_veloUT_track) {
-    const float qop_ut = ut_tracks.qop[i_veloUT_track];
-
-    const int i_velo_track = ut_tracks.velo_track[i_veloUT_track];
-    const uint velo_states_index = event_tracks_offset + i_velo_track;
-    const MiniState velo_state = velo_states.get(velo_states_index);
-
-    find_forward_tracks(
-      scifi_hits,
-      scifi_hit_count,
-      qop_ut,
-      i_veloUT_track,
-      outputTracks,
-      n_forward_tracks,
-      n_veloUT_tracks,
-      tmva1,
-      tmva2,
-      constArrays,
-      magnet_polarity,
-      velo_state);
-  }
-}
diff --git a/x86/SciFi/PrForward/src/RunForwardCPU.cpp b/x86/SciFi/PrForward/src/RunForwardCPU.cpp
deleted file mode 100644
index 5e2c4383bb8..00000000000
--- a/x86/SciFi/PrForward/src/RunForwardCPU.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-#include "RunForwardCPU.h"
-
-#ifdef WITH_ROOT
-#include "TH1D.h"
-#include "TFile.h"
-#include "TTree.h"
-#endif
-
-int run_forward_on_CPU(
-  SciFi::TrackHits* host_scifi_tracks,
-  int* host_scifi_n_tracks,
-  const uint* host_scifi_hits,
-  const uint* host_scifi_hit_count,
-  const char* host_scifi_geometry,
-  const std::array<float, 9>& host_inv_clus_res,
-  const uint* host_velo_tracks_atomics,
-  const uint* host_velo_track_hit_number,
-  const char* host_velo_states,
-  const int* host_atomics_ut,
-  const uint* host_ut_track_hit_number,
-  const float* host_ut_qop,
-  const uint* host_ut_track_velo_indices,
-  const uint number_of_events)
-{
-  // #ifdef WITH_ROOT
-  //   // Histograms only for checking and debugging
-  //   TFile* f = new TFile("../output/scifi.root", "RECREATE");
-  //   TTree* t_Forward_tracks = new TTree("Forward_tracks", "Forward_tracks");
-  //   TTree* t_statistics = new TTree("statistics", "statistics");
-  //   TTree* t_scifi_hits = new TTree("scifi_hits", "scifi_hits");
-  //   uint planeCode, LHCbID;
-  //   float x0, z0, w, dxdy, dzdy, yMin, yMax;
-  //   float qop;
-  //   int n_tracks;
-  //   float state_x, state_y, state_z, state_tx, state_ty;
-
-  //   t_Forward_tracks->Branch("qop", &qop);
-  //   t_Forward_tracks->Branch("state_x", &state_x);
-  //   t_Forward_tracks->Branch("state_y", &state_y);
-  //   t_Forward_tracks->Branch("state_z", &state_z);
-  //   t_Forward_tracks->Branch("state_tx", &state_tx);
-  //   t_Forward_tracks->Branch("state_ty", &state_ty);
-  //   t_statistics->Branch("n_tracks", &n_tracks);
-  //   t_scifi_hits->Branch("planeCode", &planeCode);
-  //   t_scifi_hits->Branch("LHCbID", &LHCbID);
-  //   t_scifi_hits->Branch("x0", &x0);
-  //   t_scifi_hits->Branch("z0", &z0);
-  //   t_scifi_hits->Branch("w", &w);
-  //   t_scifi_hits->Branch("dxdy", &dxdy);
-  //   t_scifi_hits->Branch("dzdy", &dzdy);
-  //   t_scifi_hits->Branch("yMin", &yMin);
-  //   t_scifi_hits->Branch("yMax", &yMax);
-  // #endif
-
-  // // to do: set from configuration
-  // const float magnet_polarity = -1.f;
-
-  //   for (uint i_event = 0; i_event < number_of_events; ++i_event) {
-
-  //     // Velo consolidated types
-  //     const Velo::Consolidated::Tracks velo_tracks {
-  //       (uint*) host_velo_tracks_atomics, (uint*) host_velo_track_hit_number, i_event, number_of_events};
-  //     const uint event_tracks_offset = velo_tracks.tracks_offset(i_event);
-  //     const Velo::Consolidated::States host_velo_states_event {(char*) host_velo_states,
-  //                                                              velo_tracks.total_number_of_tracks};
-
-  //     // UT consolidated types
-  //     UT::Consolidated::Tracks ut_tracks {(uint*) host_atomics_ut,
-  //                                         (uint*) host_ut_track_hit_number,
-  //                                         (float*) host_ut_qop,
-  //                                         (uint*) host_ut_track_velo_indices,
-  //                                         i_event,
-  //                                         number_of_events};
-  //     const int n_veloUT_tracks_event = ut_tracks.number_of_tracks(i_event);
-
-  //     // SciFi non-consolidated types
-  //     int* n_forward_tracks = host_scifi_n_tracks + i_event;
-  //     SciFi::TrackHits* scifi_tracks_event = host_scifi_tracks + i_event * SciFi::Constants::max_tracks;
-  //  MiniState* scifi_states_event;
-
-  //     const uint total_number_of_hits = host_scifi_hit_count[number_of_events *
-  //     SciFi::Constants::n_mat_groups_and_mats]; SciFi::HitCount scifi_hit_count {(uint32_t*) host_scifi_hit_count,
-  //     i_event};
-
-  //     const SciFi::SciFiGeometry scifi_geometry(host_scifi_geometry);
-
-  //     SciFi::Hits scifi_hits(
-  //       (uint*) host_scifi_hits,
-  //       total_number_of_hits,
-  //       &scifi_geometry,
-  //       reinterpret_cast<const float*>(host_inv_clus_res.data()));
-
-  // #ifdef WITH_ROOT
-  //     // store hit variables in tree
-  //     for (size_t zone = 0; zone < SciFi::Constants::n_zones; zone++) {
-  //       const auto zone_offset = scifi_hit_count.zone_offset(zone);
-  //       for (size_t hit = 0; hit < scifi_hit_count.zone_number_of_hits(zone); hit++) {
-  //         const auto hit_offset = zone_offset + hit;
-
-  //         planeCode = scifi_hits.planeCode(hit_offset);
-  //         LHCbID = scifi_hits.LHCbID(hit_offset);
-  //         x0 = scifi_hits.x0[hit_offset];
-  //         z0 = scifi_hits.z0[hit_offset];
-  //         w = scifi_hits.w(hit_offset);
-  //         dxdy = scifi_hits.dxdy(hit_offset);
-  //         dzdy = scifi_hits.dzdy(hit_offset);
-  //         yMin = scifi_hits.yMin(hit_offset);
-  //         yMax = scifi_hits.yMax(hit_offset);
-  //         t_scifi_hits->Fill();
-  //       }
-  //     }
-  // #endif
-
-  //     // initialize TMVA vars
-  //     SciFi::Tracking::TMVA tmva1;
-  //     SciFi::Tracking::TMVA1_Init(tmva1);
-  //     SciFi::Tracking::TMVA tmva2;
-  //     SciFi::Tracking::TMVA2_Init(tmva2);
-
-  //     SciFi::Tracking::Arrays constArrays;
-
-  //     PrForwardWrapper(
-  //       scifi_hits,
-  //       scifi_hit_count,
-  //       host_velo_states_event,
-  //       event_tracks_offset,
-  //       ut_tracks,
-  //       n_veloUT_tracks_event,
-  //       &tmva1,
-  //       &tmva2,
-  //       &constArrays,
-  //       magnet_polarity,
-  //       scifi_tracks_event,
-  //       (uint*) n_forward_tracks);
-
-  // #ifdef WITH_ROOT
-  //     // store qop in tree
-  //     for (int i_track = 0; i_track < *n_forward_tracks; ++i_track) {
-  //       qop = scifi_tracks_event[i_track].qop;
-  //       state_x = scifi_tracks_event[i_track].state.x;
-  //       state_y = scifi_tracks_event[i_track].state.y;
-  //       state_z = scifi_tracks_event[i_track].state.z;
-  //       state_tx = scifi_tracks_event[i_track].state.tx;
-  //       state_ty = scifi_tracks_event[i_track].state.ty;
-  //       t_Forward_tracks->Fill();
-  //     }
-  //     n_tracks = n_forward_tracks[i_event];
-  //     t_statistics->Fill();
-  // #endif
-  //   }
-
-  // #ifdef WITH_ROOT
-  //   f->Write();
-  //   f->Close();
-  // #endif
-
-  return 0;
-}
diff --git a/x86/global_event_cut/CMakeLists.txt b/x86/global_event_cut/CMakeLists.txt
index 0973aa29a48..31ae99b9375 100644
--- a/x86/global_event_cut/CMakeLists.txt
+++ b/x86/global_event_cut/CMakeLists.txt
@@ -7,7 +7,6 @@ include_directories(${CMAKE_SOURCE_DIR}/stream/setup/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/global_event_cut/include)
 
 add_library(CpuGEC STATIC
-- 
GitLab


From 0bea95b165706ebee5a2281203ff40d037cc890f Mon Sep 17 00:00:00 2001
From: gligorov <gligorov@mail.cern.ch>
Date: Thu, 20 Jun 2019 21:45:00 +0200
Subject: [PATCH 2/8] begin cleaning up legacy ut code

---
 configuration/sequences/PrVeloUT.h            |  34 --
 cuda/UT/CMakeLists.txt                        |   3 -
 cuda/UT/PrVeloUT/include/PrVeloUT.cuh         | 252 ----------
 .../PrVeloUT/include/PrVeloUTDefinitions.cuh  |  59 ---
 cuda/UT/PrVeloUT/include/VeloUT.cuh           |  38 --
 cuda/UT/PrVeloUT/src/PrVeloUT.cu              | 441 ------------------
 cuda/UT/PrVeloUT/src/VeloUT.cu                | 160 -------
 cuda/UT/common/include/UTDefinitions.cuh      |   5 +
 .../include/UTMagnetToolDefinitions.h}        |   6 +-
 .../UT/compassUT/include/CalculateWindows.cuh |   1 -
 cuda/UT/compassUT/include/CompassUT.cuh       |   5 +-
 cuda/UT/compassUT/include/FindBestHits.cuh    |   4 +-
 cuda/UT/compassUT/include/SearchWindows.cuh   |   4 +-
 cuda/UT/compassUT/include/UTFastFitter.cuh    |   2 +-
 cuda/UT/compassUT/src/CompassUT.cu            |   2 +-
 cuda/UT/compassUT/src/UTFastFitter.cu         |   2 +-
 16 files changed, 16 insertions(+), 1002 deletions(-)
 delete mode 100644 configuration/sequences/PrVeloUT.h
 delete mode 100644 cuda/UT/PrVeloUT/include/PrVeloUT.cuh
 delete mode 100644 cuda/UT/PrVeloUT/include/PrVeloUTDefinitions.cuh
 delete mode 100644 cuda/UT/PrVeloUT/include/VeloUT.cuh
 delete mode 100644 cuda/UT/PrVeloUT/src/PrVeloUT.cu
 delete mode 100644 cuda/UT/PrVeloUT/src/VeloUT.cu
 rename cuda/UT/{PrVeloUT/include/PrVeloUTMagnetToolDefinitions.h => common/include/UTMagnetToolDefinitions.h} (86%)

diff --git a/configuration/sequences/PrVeloUT.h b/configuration/sequences/PrVeloUT.h
deleted file mode 100644
index 5167a505839..00000000000
--- a/configuration/sequences/PrVeloUT.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * Specify here the algorithms to be executed in the sequence,
- * in the expected order of execution.
- */
-SEQUENCE_T(
-  init_event_list_t,
-  global_event_cut_t,
-  velo_estimate_input_size_t,
-  prefix_sum_velo_clusters_t,
-  velo_masked_clustering_t,
-  velo_calculate_phi_and_sort_t,
-  velo_fill_candidates_t,
-  velo_search_by_triplet_t,
-  velo_weak_tracks_adder_t,
-  copy_and_prefix_sum_single_block_velo_t,
-  copy_velo_track_hit_number_t,
-  prefix_sum_velo_track_hit_number_t,
-  consolidate_velo_tracks_t,
-  velo_kalman_fit_t,
-  pv_beamline_extrapolate_t,
-  pv_beamline_histo_t,
-  pv_beamline_peak_t,
-  pv_beamline_multi_fitter_t,
-  pv_beamline_cleanup_t,
-  ut_calculate_number_of_hits_t,
-  prefix_sum_ut_hits_t,
-  ut_pre_decode_t,
-  ut_find_permutation_t,
-  ut_decode_raw_banks_in_order_t,
-  veloUT_t,
-  copy_and_prefix_sum_single_block_ut_t,
-  copy_ut_track_hit_number_t,
-  prefix_sum_ut_track_hit_number_t,
-  consolidate_ut_tracks_t)
diff --git a/cuda/UT/CMakeLists.txt b/cuda/UT/CMakeLists.txt
index f09bb0463d7..8f9e2823bac 100644
--- a/cuda/UT/CMakeLists.txt
+++ b/cuda/UT/CMakeLists.txt
@@ -1,6 +1,5 @@
 file(GLOB UT_common "common/src/*cu")
 file(GLOB UT_decoding "UTDecoding/src/*cu")
-file(GLOB UT_tracking "PrVeloUT/src/*cu")
 file(GLOB UT_consolidate "consolidate/src/*cu")
 file(GLOB CompassUT_tracking "compassUT/src/*cu")
 
@@ -15,14 +14,12 @@ include_directories(../utils/sorting/include)
 include_directories(../utils/binary_search/include)
 include_directories(common/include)
 include_directories(UTDecoding/include)
-include_directories(PrVeloUT/include)
 include_directories(consolidate/include)
 include_directories(compassUT/include)
 
 add_library(UT STATIC
   ${UT_common}
   ${UT_decoding}
-  ${UT_tracking}
   ${UT_consolidate}
   ${CompassUT_tracking}
 )
diff --git a/cuda/UT/PrVeloUT/include/PrVeloUT.cuh b/cuda/UT/PrVeloUT/include/PrVeloUT.cuh
deleted file mode 100644
index d43e16370f2..00000000000
--- a/cuda/UT/PrVeloUT/include/PrVeloUT.cuh
+++ /dev/null
@@ -1,252 +0,0 @@
-#pragma once
-
-#include <algorithm>
-#include <array>
-#include <cassert>
-#include <cmath>
-#include <fstream>
-#include <vector>
-
-#include "PrVeloUTDefinitions.cuh"
-#include "PrVeloUTMagnetToolDefinitions.h"
-#include "UTDefinitions.cuh"
-#include "UTEventModel.cuh"
-#include "VeloConsolidated.cuh"
-#include "VeloDefinitions.cuh"
-#include "VeloEventModel.cuh"
-#include "States.cuh"
-
-/** PrVeloUT
- *
- *  @author Mariusz Witek
- *  @date   2007-05-08
- *  @update for A-Team framework 2007-08-20 SHM
- *
- *  2017-03-01: Christoph Hasse (adapt to future framework)
- *  2018-05-05: Plácido Fernández (make standalone)
- *  2018-07:    Dorothea vom Bruch (convert to C and then CUDA code)
- */
-struct TrackHelper {
-  int bestHitIndices[UT::Constants::n_layers] = {-1, -1, -1, -1};
-  int n_hits = 0;
-  float bestParams[4];
-  float wb, invKinkVeloDist, xMidField;
-
-  __host__ __device__ TrackHelper(const MiniState& state)
-  {
-    bestParams[0] = bestParams[2] = bestParams[3] = 0.;
-    bestParams[1] = PrVeloUTConst::maxPseudoChi2;
-    xMidField = state.x + state.tx * (PrVeloUTConst::zKink - state.z);
-    const float a = PrVeloUTConst::sigmaVeloSlope * (PrVeloUTConst::zKink - state.z);
-    wb = 1. / (a * a);
-    invKinkVeloDist = 1 / (PrVeloUTConst::zKink - state.z);
-  }
-};
-
-__host__ __device__ void propagate_state_to_end_velo(VeloState& velo_state);
-
-__host__ __device__ bool veloTrackInUTAcceptance(const MiniState& state);
-
-__device__ bool getHits(
-  int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  int n_hitCandidatesInLayers[UT::Constants::n_layers],
-  float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::Hits& ut_hits,
-  UT::HitOffsets& ut_hit_offsets,
-  const float* fudgeFactors,
-  const MiniState& trState,
-  const float* ut_dxDy,
-  const float* dev_unique_sector_xs,
-  const uint* dev_unique_x_sector_layer_offsets);
-
-__host__ __device__ bool formClusters(
-  const int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  const int n_hitCandidatesInLayers[UT::Constants::n_layers],
-  const float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::Hits& ut_hits,
-  UT::HitOffsets& ut_hit_offsets,
-  TrackHelper& helper,
-  MiniState& state,
-  const float* ut_dxDy,
-  const bool forward);
-
-__host__ __device__ void prepareOutputTrack(
-  const Velo::Consolidated::Hits& velo_track_hits,
-  const uint velo_track_hit_number,
-  const TrackHelper& helper,
-  const MiniState& state,
-  int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  int n_hitCandidatesInLayers[UT::Constants::n_layers],
-  UT::Hits& ut_hits,
-  UT::HitOffsets& ut_hit_offsets,
-  const float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::TrackHits VeloUT_tracks[UT::Constants::max_num_tracks],
-  int* n_veloUT_tracks,
-  const int i_velo_track,
-  const float* bdlTable,
-  const int event_hit_offset);
-
-__host__ __device__ void fillArray(int* array, const int size, const size_t value);
-
-__host__ __device__ void fillArrayAt(int* array, const int offset, const int n_vals, const size_t value);
-
-__host__ __device__ void fillIterators(UT::Hits& ut_hits, UT::HitOffsets& ut_hit_offsets, int posLayers[4][85]);
-
-__host__ __device__ void findHits(
-  const uint lowerBoundSectorGroup,
-  const uint upperBoundSectorGroup,
-  UT::Hits& ut_hits,
-  UT::HitOffsets& ut_hit_offsets,
-  uint layer_offset,
-  const int i_layer,
-  const float* ut_dxDy,
-  const MiniState& myState,
-  const float xTolNormFact,
-  const float invNormFact,
-  int hitCandidatesInLayer[UT::Constants::max_hit_candidates_per_layer],
-  int& n_hitCandidatesInLayer,
-  float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer]);
-
-// =================================================
-// -- 2 helper functions for fit
-// -- Pseudo chi2 fit, templated for 3 or 4 hits
-// =================================================
-template<int N, bool InOrder>
-__host__ __device__ void addHits(
-  float* mat,
-  float* rhs,
-  const float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  const int hitCandidateIndices[UT::Constants::n_layers],
-  const int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::Hits& ut_hits,
-  const int hitIndices[N],
-  const float* ut_dxDy,
-  const bool forward)
-{
-  for (int i_hit = 0; i_hit < N; ++i_hit) {
-    const int hit_index = hitIndices[i_hit];
-    // const int planeCode = ut_hits.planeCode[hit_index];
-    int planeCode = forward ? i_hit : 4 - 1 - i_hit;
-    if (planeCode == 1 && !InOrder) {
-      planeCode = 3;
-    }
-    else if (planeCode == 0 && !InOrder) {
-      planeCode = 1;
-    }
-    const float ui = x_pos_layers[planeCode][hitCandidateIndices[i_hit]];
-    const float dxDy = ut_dxDy[planeCode];
-    const float ci = ut_hits.cosT(hit_index, dxDy);
-    const float z = ut_hits.zAtYEq0[hit_index];
-    const float dz = 0.001 * (z - PrVeloUTConst::zMidUT);
-    const float wi = ut_hits.weight[hit_index];
-
-    mat[0] += wi * ci;
-    mat[1] += wi * ci * dz;
-    mat[2] += wi * ci * dz * dz;
-    rhs[0] += wi * ui;
-    rhs[1] += wi * ui * dz;
-  }
-}
-
-template<int N, bool InOrder>
-__host__ __device__ void addChi2s(
-  const float xUTFit,
-  const float xSlopeUTFit,
-  float& chi2,
-  const float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  const int hitCandidateIndices[UT::Constants::n_layers],
-  const int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::Hits& ut_hits,
-  const int hitIndices[N],
-  const bool forward)
-{
-  for (int i_hit = 0; i_hit < N; ++i_hit) {
-    const int hit_index = hitIndices[i_hit];
-    // const int planeCode = ut_hits.planeCode[hit_index];
-    int planeCode = forward ? i_hit : 4 - 1 - i_hit;
-    if (planeCode == 1 && !InOrder) {
-      planeCode = 3;
-    }
-    else if (planeCode == 0 && !InOrder) {
-      planeCode = 1;
-    }
-    const float zd = ut_hits.zAtYEq0[hit_index];
-    const float xd = xUTFit + xSlopeUTFit * (zd - PrVeloUTConst::zMidUT);
-    const float x = x_pos_layers[planeCode][hitCandidateIndices[i_hit]];
-    const float du = xd - x;
-    chi2 += (du * du) * ut_hits.weight[hit_index];
-  }
-}
-
-template<int N, bool InOrder>
-__host__ __device__ void simpleFit(
-  const float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  const int hitCandidateIndices[UT::Constants::n_layers],
-  const int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::Hits& ut_hits,
-  const int hitIndices[N],
-  TrackHelper& helper,
-  MiniState& state,
-  const float* ut_dxDy,
-  const bool forward)
-{
-  assert(N == 3 || N == 4);
-
-  /* Straight line fit of UT hits,
-     including the hit at x_mid_field, z_mid_field,
-     use least squares method for fitting x(z) = a + bz,
-     the chi2 is minimized and expressed in terms of sums as described
-     in chapter 4 of http://cds.cern.ch/record/1635665/files/LHCb-PUB-2013-023.pdf
-    */
-  // -- Scale the z-component, to not run into numerical problems with floats
-  // -- first add to sum values from hit at xMidField, zMidField hit
-  const float zDiff = 0.001 * (PrVeloUTConst::zKink - PrVeloUTConst::zMidUT);
-  float mat[3] = {helper.wb, helper.wb * zDiff, helper.wb * zDiff * zDiff};
-  float rhs[2] = {helper.wb * helper.xMidField, helper.wb * helper.xMidField * zDiff};
-
-  // then add to sum values from hits on track
-  addHits<N, InOrder>(
-    mat, rhs, x_pos_layers, hitCandidateIndices, hitCandidatesInLayers, ut_hits, hitIndices, ut_dxDy, forward);
-
-  const float denom = 1. / (mat[0] * mat[2] - mat[1] * mat[1]);
-  const float xSlopeUTFit = 0.001 * (mat[0] * rhs[1] - mat[1] * rhs[0]) * denom;
-  const float xUTFit = (mat[2] * rhs[0] - mat[1] * rhs[1]) * denom;
-
-  // new VELO slope x
-  const float xb = xUTFit + xSlopeUTFit * (PrVeloUTConst::zKink - PrVeloUTConst::zMidUT);
-  const float xSlopeVeloFit = (xb - state.x) * helper.invKinkVeloDist;
-  const float chi2VeloSlope = (state.tx - xSlopeVeloFit) * PrVeloUTConst::invSigmaVeloSlope;
-
-  /* chi2 takes chi2 from velo fit + chi2 from UT fit */
-  float chi2UT = chi2VeloSlope * chi2VeloSlope;
-  addChi2s<N, InOrder>(
-    xUTFit,
-    xSlopeUTFit,
-    chi2UT,
-    x_pos_layers,
-    hitCandidateIndices,
-    hitCandidatesInLayers,
-    ut_hits,
-    hitIndices,
-    forward);
-
-  chi2UT /= (N + 1 - 2);
-
-  if (chi2UT < helper.bestParams[1]) {
-    // calculate q/p
-    const float sinInX = xSlopeVeloFit * std::sqrt(1. + xSlopeVeloFit * xSlopeVeloFit);
-    const float sinOutX = xSlopeUTFit * std::sqrt(1. + xSlopeUTFit * xSlopeUTFit);
-    const float qp = (sinInX - sinOutX);
-
-    helper.bestParams[0] = qp;
-    helper.bestParams[1] = chi2UT;
-    helper.bestParams[2] = xUTFit;
-    helper.bestParams[3] = xSlopeUTFit;
-    helper.bestHitIndices[3] = -1;
-    for (int i_hit = 0; i_hit < N; ++i_hit) {
-      helper.bestHitIndices[i_hit] = hitIndices[i_hit];
-    }
-
-    helper.n_hits = N;
-  }
-}
diff --git a/cuda/UT/PrVeloUT/include/PrVeloUTDefinitions.cuh b/cuda/UT/PrVeloUT/include/PrVeloUTDefinitions.cuh
deleted file mode 100644
index db675e90104..00000000000
--- a/cuda/UT/PrVeloUT/include/PrVeloUTDefinitions.cuh
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma once
-
-#include "cuda_runtime.h"
-
-#include "SystemOfUnits.h"
-
-/**
-   *Constants mainly taken from PrVeloUT.h from Rec
-   *  @author Mariusz Witek
-   *  @date   2007-05-08
-   *  @update for A-Team framework 2007-08-20 SHM
-   *
-   *  2017-03-01: Christoph Hasse (adapt to future framework)
-   *  2018-05-05: Plácido Fernández (make standalone)
-   *  2018-07:    Dorothea vom Bruch (convert to C, and then to CUDA code)
-
- */
-
-namespace PrVeloUTConst {
-
-  // zMidUT is a position of normalization plane which should
-  // to be close to z middle of UT ( +- 5 cm ).
-  // No need to update with small UT movement.
-  static constexpr float zMidUT = 2484.6f;
-  //  distToMomentum is properly recalculated in PrUTMagnetTool when B field changes
-  static constexpr float distToMomentum = 4.0212e-05f;
-  static constexpr float sigmaVeloSlope = 0.10f * Gaudi::Units::mrad;
-  static constexpr float invSigmaVeloSlope = 1.0f / sigmaVeloSlope;
-  static constexpr float zKink = 1780.0f;
-
-  static constexpr float minMomentum = 1.5f * Gaudi::Units::GeV;
-  static constexpr float minPT = 0.3f * Gaudi::Units::GeV;
-  static constexpr float maxPseudoChi2 = 1280.0f;
-  static constexpr float yTol = 0.5f * Gaudi::Units::mm;
-  static constexpr float yTolSlope = 0.08f;
-  static constexpr float hitTol1 = 6.0f * Gaudi::Units::mm;
-  static constexpr float hitTol2 = 0.8f * Gaudi::Units::mm;
-  static constexpr float deltaTx1 = 0.035f;
-  static constexpr float deltaTx2 = 0.018f;
-  static constexpr float maxXSlope = 0.350f;
-  static constexpr float maxYSlope = 0.300f;
-  static constexpr float centralHoleSize = 33.0f * Gaudi::Units::mm;
-  static constexpr float intraLayerDist = 15.0f * Gaudi::Units::mm;
-  static constexpr float overlapTol = 0.7f * Gaudi::Units::mm;
-  static constexpr float passHoleSize = 40.0f * Gaudi::Units::mm;
-  static constexpr int minHighThres = 1;
-  static constexpr bool printVariables = false;
-  static constexpr bool passTracks = false;
-  static constexpr bool doTiming = false;
-  // Scale the z-component, to not run into numerical problems with floats
-  // first add to sum values from hit at xMidField, zMidField hit
-  static constexpr float zDiff = 0.001f * (zKink - zMidUT);
-
-  constexpr float magFieldParams[3] = { 2010.0f, -2240.0f, -71330.f };
-  
-  static constexpr float LD3Hits = -0.5f;
-  static constexpr float LD4Hits = -0.5f;
-  
-} // namespace PrVeloUTConst
diff --git a/cuda/UT/PrVeloUT/include/VeloUT.cuh b/cuda/UT/PrVeloUT/include/VeloUT.cuh
deleted file mode 100644
index cd27f1ba7fa..00000000000
--- a/cuda/UT/PrVeloUT/include/VeloUT.cuh
+++ /dev/null
@@ -1,38 +0,0 @@
-#pragma once
-
-#include "VeloDefinitions.cuh"
-#include "UTDefinitions.cuh"
-#include "PrVeloUTMagnetToolDefinitions.h"
-#include "PrVeloUT.cuh"
-#include "Handler.cuh"
-#include "ArgumentsVelo.cuh"
-#include "ArgumentsUT.cuh"
-#include "UTEventModel.cuh"
-
-__global__ void veloUT(
-  uint* dev_ut_hits,
-  uint* dev_ut_hit_offsets,
-  int* dev_atomics_velo,
-  uint* dev_velo_track_hit_number,
-  char* dev_velo_track_hits,
-  char* dev_velo_states,
-  UT::TrackHits* dev_veloUT_tracks,
-  int* dev_atomics_ut,
-  PrUTMagnetTool* dev_ut_magnet_tool,
-  float* dev_ut_dxDy,
-  const uint* dev_unique_x_sector_layer_offsets,
-  const uint* dev_unique_x_sector_offsets,
-  const float* dev_unique_sector_xs);
-
-ALGORITHM(
-  veloUT,
-  veloUT_t,
-  ARGUMENTS(
-    dev_ut_hits,
-    dev_ut_hit_offsets,
-    dev_atomics_velo,
-    dev_velo_track_hit_number,
-    dev_velo_track_hits,
-    dev_velo_states,
-    dev_ut_tracks,
-    dev_atomics_ut))
diff --git a/cuda/UT/PrVeloUT/src/PrVeloUT.cu b/cuda/UT/PrVeloUT/src/PrVeloUT.cu
deleted file mode 100644
index 18642e5a73e..00000000000
--- a/cuda/UT/PrVeloUT/src/PrVeloUT.cu
+++ /dev/null
@@ -1,441 +0,0 @@
-#include "PrVeloUT.cuh"
-
-//-----------------------------------------------------------------------------
-// Implementation file for PrVeloUT
-//
-// 2007-05-08: Mariusz Witek
-// 2017-03-01: Christoph Hasse (adapt to future framework)
-// 2018-05-05: Plácido Fernández (make standalone)
-// 2018-07:    Dorothea vom Bruch (convert to C and then CUDA code)
-//-----------------------------------------------------------------------------
-
-// -- These things are all hardcopied from the PrTableForFunction
-// -- and PrUTMagnetTool
-// -- If the granularity or whatever changes, this will give wrong results
-
-__host__ __device__ int masterIndex(const int index1, const int index2, const int index3)
-{
-  return (index3 * 11 + index2) * 31 + index1;
-}
-
-//=====================================================================
-// Propagate to end of Velo z position (z=770mm)
-// only propagate x, y, z; covariance matrix is not needed
-//=====================================================================
-__host__ __device__ void propagate_state_to_end_velo(VeloState& velo_state)
-{
-  const float dz = Velo::Constants::z_endVelo - velo_state.z;
-  velo_state.x += dz * velo_state.tx;
-  velo_state.y += dz * velo_state.ty;
-  velo_state.z = Velo::Constants::z_endVelo;
-}
-
-//=============================================================================
-// Reject tracks outside of acceptance or pointing to the beam pipe
-//=============================================================================
-__host__ __device__ bool veloTrackInUTAcceptance(const MiniState& state)
-{
-  const float xMidUT = state.x + state.tx * (PrVeloUTConst::zMidUT - state.z);
-  const float yMidUT = state.y + state.ty * (PrVeloUTConst::zMidUT - state.z);
-
-  if (xMidUT * xMidUT + yMidUT * yMidUT < PrVeloUTConst::centralHoleSize * PrVeloUTConst::centralHoleSize) return false;
-  if ((std::abs(state.tx) > PrVeloUTConst::maxXSlope) || (std::abs(state.ty) > PrVeloUTConst::maxYSlope)) return false;
-
-  if (
-    PrVeloUTConst::passTracks && std::abs(xMidUT) < PrVeloUTConst::passHoleSize &&
-    std::abs(yMidUT) < PrVeloUTConst::passHoleSize) {
-    return false;
-  }
-
-  return true;
-}
-
-//=============================================================================
-// Find the hits
-//=============================================================================
-__device__ bool getHits(
-  int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  int n_hitCandidatesInLayers[UT::Constants::n_layers],
-  float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::Hits& ut_hits,
-  UT::HitOffsets& ut_hit_offsets,
-  const float* fudgeFactors,
-  const MiniState& trState,
-  const float* ut_dxDy,
-  const float* dev_unique_sector_xs,
-  const uint* dev_unique_x_sector_layer_offsets)
-{
-  // -- This is hardcoded, so faster
-  // -- If you ever change the Table in the magnet tool, this will be wrong
-  const float absSlopeY = std::abs(trState.ty);
-  const int index = (int) (absSlopeY * 100 + 0.5);
-  assert(3 + 4 * index < PrUTMagnetTool::N_dxLay_vals);
-  const std::array<float, 4> normFact = {
-    fudgeFactors[4 * index], fudgeFactors[1 + 4 * index], fudgeFactors[2 + 4 * index], fudgeFactors[3 + 4 * index]};
-
-  // -- this 500 seems a little odd...
-  // to do: change back!
-  const float invTheta = std::min(500., 1.0 / std::sqrt(trState.tx * trState.tx + trState.ty * trState.ty));
-  // const float minMom   = std::max(PrVeloUTConst::minPT*invTheta, PrVeloUTConst::minMomentum);
-  const float minMom = std::max(PrVeloUTConst::minPT * invTheta, float(1.5) * Gaudi::Units::GeV);
-  const float xTol = std::abs(1. / (PrVeloUTConst::distToMomentum * minMom));
-  const float yTol = PrVeloUTConst::yTol + PrVeloUTConst::yTolSlope * xTol;
-
-  int nLayers = 0;
-
-  float dxDyHelper[UT::Constants::n_layers] = {0., 1., -1., 0};
-  for (int iStation = 0; iStation < 2; ++iStation) {
-
-    if (iStation == 1 && nLayers == 0) return false;
-
-    for (int iLayer = 0; iLayer < 2; ++iLayer) {
-      if (iStation == 1 && iLayer == 1 && nLayers < 2) return false;
-
-      int layer = 2 * iStation + iLayer;
-      int layer_offset = ut_hit_offsets.layer_offset(layer);
-
-      if (ut_hit_offsets.layer_number_of_hits(layer) == 0) continue;
-      const float dxDy = ut_dxDy[layer];
-      const float zLayer = ut_hits.zAtYEq0[layer_offset + 0];
-
-      const float yAtZ = trState.y + trState.ty * (zLayer - trState.z);
-      const float xLayer = trState.x + trState.tx * (zLayer - trState.z);
-      const float yLayer = yAtZ + yTol * dxDyHelper[layer];
-
-      const float normFactNum = normFact[2 * iStation + iLayer];
-      const float invNormFact = 1.0 / normFactNum;
-
-      const float lowerBoundX =
-        (xLayer - dxDy * yLayer) - xTol * invNormFact - std::abs(trState.tx) * PrVeloUTConst::intraLayerDist;
-      const float upperBoundX =
-        (xLayer - dxDy * yLayer) + xTol * invNormFact + std::abs(trState.tx) * PrVeloUTConst::intraLayerDist;
-
-      // Find sector group for lowerBoundX and upperBoundX
-      const uint first_sector_group_in_layer = dev_unique_x_sector_layer_offsets[layer];
-      const uint last_sector_group_in_layer = dev_unique_x_sector_layer_offsets[layer + 1];
-
-      uint lowerBoundSectorGroup = first_sector_group_in_layer;
-      uint upperBoundSectorGroup = last_sector_group_in_layer - 1;
-
-      // The window of search is out of bounds
-      if (
-        upperBoundX < dev_unique_sector_xs[first_sector_group_in_layer] ||
-        lowerBoundX > dev_unique_sector_xs[last_sector_group_in_layer - 1]) {
-        continue;
-      }
-
-      for (int i = first_sector_group_in_layer + 1; i < last_sector_group_in_layer; ++i) {
-        if (dev_unique_sector_xs[i] > lowerBoundX) {
-          lowerBoundSectorGroup = i - 1;
-          break;
-        }
-      }
-
-      upperBoundSectorGroup = lowerBoundSectorGroup + 3;
-      if (upperBoundSectorGroup >= last_sector_group_in_layer) {
-        upperBoundSectorGroup = last_sector_group_in_layer - 1;
-      }
-
-      assert(upperBoundSectorGroup < last_sector_group_in_layer);
-      assert(lowerBoundSectorGroup >= first_sector_group_in_layer);
-      assert(lowerBoundSectorGroup < upperBoundSectorGroup);
-
-      findHits(
-        lowerBoundSectorGroup,
-        upperBoundSectorGroup,
-        ut_hits,
-        ut_hit_offsets,
-        layer_offset,
-        layer,
-        ut_dxDy,
-        trState,
-        xTol * invNormFact,
-        invNormFact,
-        hitCandidatesInLayers[layer],
-        n_hitCandidatesInLayers[layer],
-        x_pos_layers);
-
-      nLayers += int(!(n_hitCandidatesInLayers[layer] == 0));
-    }
-  }
-
-  return nLayers > 2;
-}
-
-//=========================================================================
-// Form clusters
-//=========================================================================
-__host__ __device__ bool formClusters(
-  const int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  const int n_hitCandidatesInLayers[UT::Constants::n_layers],
-  const float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::Hits& ut_hits,
-  UT::HitOffsets& ut_hit_offsets,
-  TrackHelper& helper,
-  MiniState& state,
-  const float* ut_dxDy,
-  const bool forward)
-{
-  // handle forward / backward cluster search
-  int layers[UT::Constants::n_layers];
-  for (int i_layer = 0; i_layer < UT::Constants::n_layers; ++i_layer) {
-    if (forward)
-      layers[i_layer] = i_layer;
-    else
-      layers[i_layer] = UT::Constants::n_layers - 1 - i_layer;
-  }
-
-  // Go through the layers
-  bool fourLayerSolution = false;
-  int hitCandidateIndices[UT::Constants::n_layers];
-  for (int i_hit0 = 0; i_hit0 < n_hitCandidatesInLayers[layers[0]]; ++i_hit0) {
-
-    const int layer_offset0 = ut_hit_offsets.layer_offset(layers[0]);
-    const int hit_index0 = layer_offset0 + hitCandidatesInLayers[layers[0]][i_hit0];
-    const float xhitLayer0 = x_pos_layers[layers[0]][i_hit0];
-    const float zhitLayer0 = ut_hits.zAtYEq0[hit_index0];
-    hitCandidateIndices[0] = i_hit0;
-
-    for (int i_hit2 = 0; i_hit2 < n_hitCandidatesInLayers[layers[2]]; ++i_hit2) {
-
-      const int layer_offset2 = ut_hit_offsets.layer_offset(layers[2]);
-      const int hit_index2 = layer_offset2 + hitCandidatesInLayers[layers[2]][i_hit2];
-      const float xhitLayer2 = x_pos_layers[layers[2]][i_hit2];
-      const float zhitLayer2 = ut_hits.zAtYEq0[hit_index2];
-      hitCandidateIndices[2] = i_hit2;
-
-      const float tx = (xhitLayer2 - xhitLayer0) / (zhitLayer2 - zhitLayer0);
-      if (std::abs(tx - state.tx) > PrVeloUTConst::deltaTx2) continue;
-
-      int IndexBestHit1 = -10;
-      float hitTol = PrVeloUTConst::hitTol2;
-      for (int i_hit1 = 0; i_hit1 < n_hitCandidatesInLayers[layers[1]]; ++i_hit1) {
-
-        const int layer_offset1 = ut_hit_offsets.layer_offset(layers[1]);
-        const int hit_index1 = layer_offset1 + hitCandidatesInLayers[layers[1]][i_hit1];
-        const float xhitLayer1 = x_pos_layers[layers[1]][i_hit1];
-        const float zhitLayer1 = ut_hits.zAtYEq0[hit_index1];
-
-        const float xextrapLayer1 = xhitLayer0 + tx * (zhitLayer1 - zhitLayer0);
-        if (std::abs(xhitLayer1 - xextrapLayer1) < hitTol) {
-          hitTol = std::abs(xhitLayer1 - xextrapLayer1);
-          IndexBestHit1 = hit_index1;
-          hitCandidateIndices[1] = i_hit1;
-        }
-      } // loop over layer 1
-
-      if (fourLayerSolution && IndexBestHit1 < 0) continue;
-
-      int IndexBestHit3 = -10;
-      hitTol = PrVeloUTConst::hitTol2;
-      for (int i_hit3 = 0; i_hit3 < n_hitCandidatesInLayers[layers[3]]; ++i_hit3) {
-
-        const int layer_offset3 = ut_hit_offsets.layer_offset(layers[3]);
-        const int hit_index3 = layer_offset3 + hitCandidatesInLayers[layers[3]][i_hit3];
-        const float xhitLayer3 = x_pos_layers[layers[3]][i_hit3];
-        const float zhitLayer3 = ut_hits.zAtYEq0[hit_index3];
-
-        const float xextrapLayer3 = xhitLayer2 + tx * (zhitLayer3 - zhitLayer2);
-        if (std::abs(xhitLayer3 - xextrapLayer3) < hitTol) {
-          hitTol = std::abs(xhitLayer3 - xextrapLayer3);
-          IndexBestHit3 = hit_index3;
-          hitCandidateIndices[3] = i_hit3;
-        }
-      } // loop over layer 3
-
-      // -- All hits found
-      if (IndexBestHit1 > 0 && IndexBestHit3 > 0) {
-        const int hitIndices[4] = {hit_index0, IndexBestHit1, hit_index2, IndexBestHit3};
-        simpleFit<4, true>(
-          x_pos_layers,
-          hitCandidateIndices,
-          hitCandidatesInLayers,
-          ut_hits,
-          hitIndices,
-          helper,
-          state,
-          ut_dxDy,
-          forward);
-
-        if (!fourLayerSolution && helper.n_hits > 0) {
-          fourLayerSolution = true;
-        }
-        continue;
-      }
-
-      // -- Nothing found in layer 3
-      if (!fourLayerSolution && IndexBestHit1 > 0) {
-        const int hitIndices[3] = {hit_index0, IndexBestHit1, hit_index2};
-        simpleFit<3, true>(
-          x_pos_layers,
-          hitCandidateIndices,
-          hitCandidatesInLayers,
-          ut_hits,
-          hitIndices,
-          helper,
-          state,
-          ut_dxDy,
-          forward);
-        continue;
-      }
-      // -- Nothing found in layer 1
-      if (!fourLayerSolution && IndexBestHit3 > 0) {
-        hitCandidateIndices[1] = hitCandidateIndices[3]; // hit3 saved in second position of hits4fit
-        const int hitIndices[3] = {hit_index0, IndexBestHit3, hit_index2};
-        simpleFit<3, false>(
-          x_pos_layers,
-          hitCandidateIndices,
-          hitCandidatesInLayers,
-          ut_hits,
-          hitIndices,
-          helper,
-          state,
-          ut_dxDy,
-          forward);
-        continue;
-      }
-    }
-  }
-
-  return fourLayerSolution;
-}
-//=========================================================================
-// Create the Velo-UT tracks
-//=========================================================================
-__host__ __device__ void prepareOutputTrack(
-  const Velo::Consolidated::Hits& velo_track_hits,
-  const uint velo_track_hit_number,
-  const TrackHelper& helper,
-  const MiniState& state,
-  int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  int n_hitCandidatesInLayers[UT::Constants::n_layers],
-  UT::Hits& ut_hits,
-  UT::HitOffsets& ut_hit_offsets,
-  const float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer],
-  UT::TrackHits VeloUT_tracks[UT::Constants::max_num_tracks],
-  int* n_veloUT_tracks,
-  const int i_velo_track,
-  const float* bdlTable,
-  const int event_hit_offset)
-{
-  //== Handle states. copy Velo one, add UT.
-  const float zOrigin = (std::fabs(state.ty) > 0.001) ? state.z - state.y / state.ty : state.z - state.x / state.tx;
-
-  // -- These are calculations, copied and simplified from PrTableForFunction
-  const std::array<float, 3> var = {state.ty, zOrigin, state.z};
-
-  const int index1 = std::max(0, std::min(30, int((var[0] + 0.3) / 0.6 * 30)));
-  const int index2 = std::max(0, std::min(10, int((var[1] + 250) / 500 * 10)));
-  const int index3 = std::max(0, std::min(10, int(var[2] / 800 * 10)));
-
-  assert(masterIndex(index1, index2, index3) < PrUTMagnetTool::N_bdl_vals);
-  float bdl = bdlTable[masterIndex(index1, index2, index3)];
-
-  const float bdls[3] = {bdlTable[masterIndex(index1 + 1, index2, index3)],
-                         bdlTable[masterIndex(index1, index2 + 1, index3)],
-                         bdlTable[masterIndex(index1, index2, index3 + 1)]};
-  const float deltaBdl[3] = {0.02, 50.0, 80.0};
-  const float boundaries[3] = {
-    -0.3f + float(index1) * deltaBdl[0], -250.0f + float(index2) * deltaBdl[1], 0.0f + float(index3) * deltaBdl[2]};
-
-  // -- This is an interpolation, to get a bit more precision
-  float addBdlVal = 0.0;
-  const float minValsBdl[3] = {-0.3, -250.0, 0.0};
-  const float maxValsBdl[3] = {0.3, 250.0, 800.0};
-  for (int i = 0; i < 3; ++i) {
-    if (var[i] < minValsBdl[i] || var[i] > maxValsBdl[i]) continue;
-    const float dTab_dVar = (bdls[i] - bdl) / deltaBdl[i];
-    const float dVar = (var[i] - boundaries[i]);
-    addBdlVal += dTab_dVar * dVar;
-  }
-  bdl += addBdlVal;
-  // ----
-
-  const float qpxz2p = -1 * std::sqrt(1. + state.ty * state.ty) / bdl * 3.3356 / Gaudi::Units::GeV;
-  const float qop = (std::abs(bdl) < 1.e-8) ? 0.0 : helper.bestParams[0] * qpxz2p;
-
-  // -- Don't make tracks that have grossly too low momentum
-  // -- Beware of the momentum resolution!
-  const float p = 1.3 * std::abs(1 / qop);
-  const float pt = p * std::sqrt(state.tx * state.tx + state.ty * state.ty);
-
-  if (p < PrVeloUTConst::minMomentum || pt < PrVeloUTConst::minPT) return;
-
-#ifdef __CUDA_ARCH__
-  uint n_tracks = atomicAdd(n_veloUT_tracks, 1);
-#else
-  (*n_veloUT_tracks)++;
-  uint n_tracks = *n_veloUT_tracks - 1;
-#endif
-
-  UT::TrackHits track;
-  track.hits_num = helper.n_hits;
-  track.qop = qop;
-  track.velo_track_index = i_velo_track;
-
-  for (int i_hit = 0; i_hit < UT::Constants::n_layers; ++i_hit) {
-    const int hit_index = helper.bestHitIndices[i_hit];
-    track.hits[i_hit] = hit_index == -1 ? -1 : hit_index - event_hit_offset;
-  }
-
-  assert(n_tracks < UT::Constants::max_num_tracks);
-  VeloUT_tracks[n_tracks] = track;
-}
-
-// ==============================================================================
-// -- Finds the hits in a given layer within a certain range
-// ==============================================================================
-__host__ __device__ void findHits(
-  const uint lowerBoundSectorGroup,
-  const uint upperBoundSectorGroup,
-  UT::Hits& ut_hits,
-  UT::HitOffsets& ut_hit_offsets,
-  uint layer_offset,
-  const int i_layer,
-  const float* ut_dxDy,
-  const MiniState& myState,
-  const float xTolNormFact,
-  const float invNormFact,
-  int hitCandidatesInLayer[UT::Constants::max_hit_candidates_per_layer],
-  int& n_hitCandidatesInLayer,
-  float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer])
-{
-  const uint posBeg = ut_hit_offsets.sector_group_offset(lowerBoundSectorGroup) - layer_offset;
-  const uint posEnd = ut_hit_offsets.sector_group_offset(upperBoundSectorGroup) +
-                      ut_hit_offsets.sector_group_number_of_hits(upperBoundSectorGroup) - layer_offset;
-
-  const auto zInit = ut_hits.zAtYEq0[layer_offset + posBeg];
-  const auto yApprox = myState.y + myState.ty * (zInit - myState.z);
-  const auto xOnTrackProto = myState.x + myState.tx * (zInit - myState.z);
-  const auto yyProto = myState.y - myState.ty * myState.z;
-  const float dxDy = ut_dxDy[i_layer];
-
-  for (int i = posBeg; i < posEnd; ++i) {
-    const auto xx = ut_hits.xAt(layer_offset + i, yApprox, dxDy);
-    const auto dx = xx - xOnTrackProto;
-
-    if (dx < -xTolNormFact) continue;
-    if (dx > xTolNormFact) continue;
-
-    // -- Now refine the tolerance in Y
-    if (ut_hits.isNotYCompatible(
-          layer_offset + i, yApprox, PrVeloUTConst::yTol + PrVeloUTConst::yTolSlope * std::abs(dx * invNormFact)))
-      continue;
-
-    const auto zz = ut_hits.zAtYEq0[layer_offset + i];
-    const auto yy = yyProto + myState.ty * zz;
-    const auto xx2 = ut_hits.xAt(layer_offset + i, yy, dxDy);
-
-    hitCandidatesInLayer[n_hitCandidatesInLayer] = i;
-    x_pos_layers[i_layer][n_hitCandidatesInLayer] = xx2;
-
-    n_hitCandidatesInLayer++;
-
-    if (n_hitCandidatesInLayer >= UT::Constants::max_hit_candidates_per_layer)
-      printf("%u > %u !! \n", n_hitCandidatesInLayer, UT::Constants::max_hit_candidates_per_layer);
-    assert(n_hitCandidatesInLayer < UT::Constants::max_hit_candidates_per_layer);
-  }
-  for (int i_hit = 0; i_hit < n_hitCandidatesInLayer; ++i_hit) {
-    assert(hitCandidatesInLayer[i_hit] < UT::Constants::max_numhits_per_event);
-  }
-}
diff --git a/cuda/UT/PrVeloUT/src/VeloUT.cu b/cuda/UT/PrVeloUT/src/VeloUT.cu
deleted file mode 100644
index 4374bd3cf84..00000000000
--- a/cuda/UT/PrVeloUT/src/VeloUT.cu
+++ /dev/null
@@ -1,160 +0,0 @@
-#include "VeloUT.cuh"
-
-__global__ void veloUT(
-  uint* dev_ut_hits,
-  uint* dev_ut_hit_offsets,
-  int* dev_atomics_velo,
-  uint* dev_velo_track_hit_number,
-  char* dev_velo_track_hits,
-  char* dev_velo_states,
-  UT::TrackHits* dev_veloUT_tracks,
-  int* dev_atomics_ut,
-  PrUTMagnetTool* dev_ut_magnet_tool,
-  float* dev_ut_dxDy,
-  const uint* dev_unique_x_sector_layer_offsets,
-  const uint* dev_unique_x_sector_offsets,
-  const float* dev_unique_sector_xs)
-{
-  const uint number_of_events = gridDim.x;
-  const uint event_number = blockIdx.x;
-
-  const uint number_of_unique_x_sectors = dev_unique_x_sector_layer_offsets[4];
-  const uint total_number_of_hits = dev_ut_hit_offsets[number_of_events * number_of_unique_x_sectors];
-
-  // Velo consolidated types
-  const Velo::Consolidated::Tracks velo_tracks {
-    (uint*) dev_atomics_velo, dev_velo_track_hit_number, event_number, number_of_events};
-  const Velo::Consolidated::States velo_states {dev_velo_states, velo_tracks.total_number_of_tracks};
-  const uint number_of_tracks_event = velo_tracks.number_of_tracks(event_number);
-  const uint event_tracks_offset = velo_tracks.tracks_offset(event_number);
-
-  UT::HitOffsets ut_hit_offsets {
-    dev_ut_hit_offsets, event_number, number_of_unique_x_sectors, dev_unique_x_sector_layer_offsets};
-  UT::Hits ut_hits {dev_ut_hits, total_number_of_hits};
-  const auto event_hit_offset = ut_hit_offsets.event_offset();
-
-  /* dev_atomics_ut contains in an SoA:
-     1. # of veloUT tracks
-  */
-  int* n_veloUT_tracks_event = dev_atomics_ut + event_number;
-  UT::TrackHits* veloUT_tracks_event = dev_veloUT_tracks + event_number * UT::Constants::max_num_tracks;
-
-  // initialize atomic veloUT tracks counter
-  if (threadIdx.x == 0) {
-    *n_veloUT_tracks_event = 0;
-  }
-  __syncthreads();
-
-  // if (threadIdx.x == 0) {
-  //   for (int i=0; i<4; ++i) {
-  //     printf("Layer %i hits:\n", i);
-
-  //     for (int s=dev_unique_x_sector_layer_offsets[i]; s<dev_unique_x_sector_layer_offsets[i+1]; ++s) {
-  //       printf(" Sector group %i, x %f:\n", s, dev_unique_sector_xs[s]);
-  //       uint group_offset = ut_hit_offsets.sector_group_offset(s);
-  //       uint n_hits_group = ut_hit_offsets.sector_group_number_of_hits(s);
-
-  //       for (int j=0; j<n_hits_group; ++j) {
-  //         const auto hit_index = group_offset + j;
-
-  //         printf("  yBegin = %f, yEnd = %f, zAtYEq0 = %f, xAtYEq0 = %f, weight = %f, highThreshold = %u \n",
-  //          ut_hits.yBegin[hit_index],
-  //          ut_hits.yEnd[hit_index],
-  //          ut_hits.zAtYEq0[hit_index],
-  //          ut_hits.xAtYEq0[hit_index],
-  //          ut_hits.weight[hit_index],
-  //          ut_hits.highThreshold[hit_index]);
-  //       }
-  //     }
-  //   }
-  // }
-
-  const float* fudgeFactors = &(dev_ut_magnet_tool->dxLayTable[0]);
-  const float* bdlTable = &(dev_ut_magnet_tool->bdlTable[0]);
-
-  // array to store indices of selected hits in layers
-  // -> can then access the hit information in the HitsSoA
-  int hitCandidatesInLayers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer];
-  int n_hitCandidatesInLayers[UT::Constants::n_layers];
-
-  for (int i = 0; i < (number_of_tracks_event + blockDim.x - 1) / blockDim.x; ++i) {
-    const int i_track = i * blockDim.x + threadIdx.x;
-
-    const uint velo_states_index = event_tracks_offset + i_track;
-    if (i_track >= number_of_tracks_event) continue;
-    if (velo_states.backward[velo_states_index]) continue;
-
-    // Mini State with only x, y, tx, ty and z
-    MiniState velo_state = velo_states.get(velo_states_index);
-
-    if (!veloTrackInUTAcceptance(velo_state)) continue;
-
-    // for storing calculated x position of hits for this track
-    float x_pos_layers[UT::Constants::n_layers][UT::Constants::max_hit_candidates_per_layer];
-
-    for (int i_layer = 0; i_layer < UT::Constants::n_layers; ++i_layer) {
-      n_hitCandidatesInLayers[i_layer] = 0;
-    }
-
-    if (!getHits(
-          hitCandidatesInLayers,
-          n_hitCandidatesInLayers,
-          x_pos_layers,
-          ut_hits,
-          ut_hit_offsets,
-          fudgeFactors,
-          velo_state,
-          dev_ut_dxDy,
-          dev_unique_sector_xs,
-          dev_unique_x_sector_layer_offsets))
-      continue;
-
-    TrackHelper helper {velo_state};
-
-    // go through UT layers in forward direction
-    if (!formClusters(
-          hitCandidatesInLayers,
-          n_hitCandidatesInLayers,
-          x_pos_layers,
-          ut_hits,
-          ut_hit_offsets,
-          helper,
-          velo_state,
-          dev_ut_dxDy,
-          true)) {
-
-      // go through UT layers in backward direction
-      formClusters(
-        hitCandidatesInLayers,
-        n_hitCandidatesInLayers,
-        x_pos_layers,
-        ut_hits,
-        ut_hit_offsets,
-        helper,
-        velo_state,
-        dev_ut_dxDy,
-        false);
-    }
-
-    if (helper.n_hits > 0) {
-      const uint velo_track_hit_number = velo_tracks.number_of_hits(i_track);
-      const Velo::Consolidated::Hits velo_track_hits = velo_tracks.get_hits(dev_velo_track_hits, i_track);
-
-      prepareOutputTrack(
-        velo_track_hits,
-        velo_track_hit_number,
-        helper,
-        velo_state,
-        hitCandidatesInLayers,
-        n_hitCandidatesInLayers,
-        ut_hits,
-        ut_hit_offsets,
-        x_pos_layers,
-        veloUT_tracks_event,
-        n_veloUT_tracks_event,
-        i_track,
-        bdlTable,
-        event_hit_offset);
-    }
-  } // velo tracks
-}
diff --git a/cuda/UT/common/include/UTDefinitions.cuh b/cuda/UT/common/include/UTDefinitions.cuh
index a409e1da810..3d763c98faf 100644
--- a/cuda/UT/common/include/UTDefinitions.cuh
+++ b/cuda/UT/common/include/UTDefinitions.cuh
@@ -81,6 +81,11 @@ namespace UT {
     // Scale the z-component, to not run into numerical problems with floats
     // first add to sum values from hit at xMidField, zMidField hit
     static constexpr float zDiff = 0.001f * (zKink - zMidUT);
+    //
+    constexpr float magFieldParams[3] = { 2010.0f, -2240.0f, -71330.f };
+    //
+    static constexpr float LD3Hits = -0.5f;
+    static constexpr float LD4Hits = -0.5f;
 
   } // namespace Constants
 } // namespace UT
diff --git a/cuda/UT/PrVeloUT/include/PrVeloUTMagnetToolDefinitions.h b/cuda/UT/common/include/UTMagnetToolDefinitions.h
similarity index 86%
rename from cuda/UT/PrVeloUT/include/PrVeloUTMagnetToolDefinitions.h
rename to cuda/UT/common/include/UTMagnetToolDefinitions.h
index 0f311d3ef7d..4831334ce5a 100644
--- a/cuda/UT/PrVeloUT/include/PrVeloUTMagnetToolDefinitions.h
+++ b/cuda/UT/common/include/UTMagnetToolDefinitions.h
@@ -11,7 +11,7 @@
    *  2018-07:    Dorothea vom Bruch (convert to C code for GPU compatability)
 
  */
-struct PrUTMagnetTool {
+struct UTMagnetTool {
   static const int N_dxLay_vals = 124;
   static const int N_bdl_vals = 3751;
 
@@ -19,8 +19,8 @@ struct PrUTMagnetTool {
   float dxLayTable[N_dxLay_vals];
   float bdlTable[N_bdl_vals];
 
-  PrUTMagnetTool() {}
-  PrUTMagnetTool(const float* _dxLayTable, const float* _bdlTable)
+  UTMagnetTool() {}
+  UTMagnetTool(const float* _dxLayTable, const float* _bdlTable)
   {
     for (int i = 0; i < N_dxLay_vals; ++i) {
       dxLayTable[i] = _dxLayTable[i];
diff --git a/cuda/UT/compassUT/include/CalculateWindows.cuh b/cuda/UT/compassUT/include/CalculateWindows.cuh
index a8e690fbe65..7bc31f964aa 100644
--- a/cuda/UT/compassUT/include/CalculateWindows.cuh
+++ b/cuda/UT/compassUT/include/CalculateWindows.cuh
@@ -2,7 +2,6 @@
 
 #include "UTDefinitions.cuh"
 #include "VeloConsolidated.cuh"
-#include "PrVeloUTMagnetToolDefinitions.h"
 #include "UTEventModel.cuh"
 #include "States.cuh"
 #include <tuple>
diff --git a/cuda/UT/compassUT/include/CompassUT.cuh b/cuda/UT/compassUT/include/CompassUT.cuh
index ea848ee8867..8986aeeac7f 100644
--- a/cuda/UT/compassUT/include/CompassUT.cuh
+++ b/cuda/UT/compassUT/include/CompassUT.cuh
@@ -1,7 +1,6 @@
 #pragma once
 
-#include "PrVeloUT.cuh"
-#include "PrVeloUTMagnetToolDefinitions.h"
+#include "UTMagnetToolDefinitions.h"
 #include "UTDefinitions.cuh"
 #include "VeloDefinitions.cuh"
 #include "CompassUTDefinitions.cuh"
@@ -22,7 +21,7 @@ __global__ void compass_ut(
   uint* dev_velo_track_hit_number,
   char* dev_velo_track_hits,
   char* dev_velo_states,
-  PrUTMagnetTool* dev_ut_magnet_tool,
+  UTMagnetTool* dev_ut_magnet_tool,
   const float* dev_magnet_polarity,
   const float* dev_ut_dxDy,
   int* dev_active_tracks,
diff --git a/cuda/UT/compassUT/include/FindBestHits.cuh b/cuda/UT/compassUT/include/FindBestHits.cuh
index 22329b87198..484594bf8da 100644
--- a/cuda/UT/compassUT/include/FindBestHits.cuh
+++ b/cuda/UT/compassUT/include/FindBestHits.cuh
@@ -1,7 +1,5 @@
 #pragma once
 
-#include "PrVeloUT.cuh"
-#include "PrVeloUTMagnetToolDefinitions.h"
 #include "UTDefinitions.cuh"
 #include "CompassUTDefinitions.cuh"
 #include "FindBestHits.cuh"
@@ -44,4 +42,4 @@ __device__ __inline__ bool check_tol_refine(
   const MiniState& velo_state,
   const float normFactNum,
   const float xTol,
-  const float dxDy);
\ No newline at end of file
+  const float dxDy);
diff --git a/cuda/UT/compassUT/include/SearchWindows.cuh b/cuda/UT/compassUT/include/SearchWindows.cuh
index 305fe2af1b3..ee138d3e551 100644
--- a/cuda/UT/compassUT/include/SearchWindows.cuh
+++ b/cuda/UT/compassUT/include/SearchWindows.cuh
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "UTDefinitions.cuh"
-#include "PrVeloUTMagnetToolDefinitions.h"
+#include "UTMagnetToolDefinitions.h"
 #include "CompassUTDefinitions.cuh"
 #include "Handler.cuh"
 #include "ArgumentsCommon.cuh"
@@ -14,7 +14,7 @@ __global__ void ut_search_windows(
   int* dev_atomics_storage,
   uint* dev_velo_track_hit_number,
   char* dev_velo_states,
-  PrUTMagnetTool* dev_ut_magnet_tool,
+  UTMagnetTool* dev_ut_magnet_tool,
   const float* dev_ut_dxDy,
   const uint* dev_unique_x_sector_layer_offsets,
   const float* dev_unique_sector_xs,
diff --git a/cuda/UT/compassUT/include/UTFastFitter.cuh b/cuda/UT/compassUT/include/UTFastFitter.cuh
index 3f0ca0b8ff1..7382ee520f9 100644
--- a/cuda/UT/compassUT/include/UTFastFitter.cuh
+++ b/cuda/UT/compassUT/include/UTFastFitter.cuh
@@ -1,8 +1,8 @@
 #pragma once
 
 #include "States.cuh"
+#include "UTDefinitions.cuh"
 #include "CompassUTDefinitions.cuh"
-#include "PrVeloUTDefinitions.cuh"
 #include "UTEventModel.cuh"
 
 __host__ __device__
diff --git a/cuda/UT/compassUT/src/CompassUT.cu b/cuda/UT/compassUT/src/CompassUT.cu
index cf847254e07..037364baecc 100644
--- a/cuda/UT/compassUT/src/CompassUT.cu
+++ b/cuda/UT/compassUT/src/CompassUT.cu
@@ -372,7 +372,7 @@ __device__ void save_track(
   }
   const float evalParams[3] = {p, pt, finalParams[3]};
   const float discriminant = evaluateLinearDiscriminant(evalParams, nHits);
-  if( discriminant  < PrVeloUTConst::LD3Hits ) return;
+  if( discriminant  < UT::Constants::LD3Hits ) return;
 
   // the track will be added
   int n_tracks = atomicAdd(n_veloUT_tracks, 1);
diff --git a/cuda/UT/compassUT/src/UTFastFitter.cu b/cuda/UT/compassUT/src/UTFastFitter.cu
index 2749ebb79e2..97c01d3a9fa 100644
--- a/cuda/UT/compassUT/src/UTFastFitter.cu
+++ b/cuda/UT/compassUT/src/UTFastFitter.cu
@@ -49,7 +49,7 @@ float fastfitter(
 {
     
   const float ty = velo_state.ty;
-  const float zKink = PrVeloUTConst::magFieldParams[0] - ty*ty*PrVeloUTConst::magFieldParams[1] - ty*ty*ty*ty*PrVeloUTConst::magFieldParams[2];
+  const float zKink = UT::Constants::magFieldParams[0] - ty*ty*UT::Constants::magFieldParams[1] - ty*ty*ty*ty*UT::Constants::magFieldParams[2];
   const float xMidField = velo_state.x + velo_state.tx*(zKink-velo_state.z);
 
     const float zDiff     = 0.001f * (zKink - UT::Constants::zMidUT);
-- 
GitLab


From c247bdff2c829789f4d30a0c4d2f42955683a032 Mon Sep 17 00:00:00 2001
From: gligorov <vladimir.gligorov@cern.ch>
Date: Thu, 20 Jun 2019 23:12:46 +0200
Subject: [PATCH 3/8] finish v0 of cleanup

---
 CMakeLists.txt                                |  1 -
 .../PrForward/include/FindStereoHits.cuh      |  1 -
 cuda/SciFi/PrForward/include/FindXHits.cuh    |  1 -
 .../PrForward/include/PrForwardTools.cuh      |  1 -
 .../include/ReferencePlaneProjection.cuh      |  1 -
 cuda/SciFi/PrForward/include/TrackUtils.cuh   |  1 -
 .../include/LFSearchInitialWindowsImpl.cuh    |  1 -
 cuda/UT/compassUT/include/FindBestHits.cuh    |  1 +
 cuda/UT/compassUT/src/CompassUT.cu            |  4 +-
 cuda/UT/compassUT/src/SearchWindows.cu        |  2 +-
 .../non_event_data/include/Consumers.h        |  4 +-
 .../non_event_data/src/UTLookupTables.cpp     | 10 ++---
 stream/CMakeLists.txt                         |  1 -
 .../include/UTSequenceCheckers_impl.cuh       |  1 -
 stream/sequence/include/Constants.cuh         |  4 +-
 stream/sequence/include/StreamWrapper.cuh     |  2 +-
 stream/setup/include/ConfiguredSequence.cuh   |  2 -
 .../visitors/UT/src/VeloUTTrackingVisitor.cu  | 42 -------------------
 18 files changed, 14 insertions(+), 66 deletions(-)
 delete mode 100644 stream/visitors/UT/src/VeloUTTrackingVisitor.cu

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b7c94c6d4fc..ffeb915be4f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -186,7 +186,6 @@ include_directories(x86/global_event_cut/include)
 include_directories(x86/utils/prefix_sum/include)
 include_directories(cuda/global_event_cut/include)
 include_directories(cuda/UT/common/include)
-include_directories(cuda/UT/PrVeloUT/include)
 include_directories(cuda/UT/compassUT/include)
 include_directories(cuda/UT/UTDecoding/include)
 include_directories(cuda/UT/consolidate/include)
diff --git a/cuda/SciFi/PrForward/include/FindStereoHits.cuh b/cuda/SciFi/PrForward/include/FindStereoHits.cuh
index 68717ee8bdb..c14347c5657 100644
--- a/cuda/SciFi/PrForward/include/FindStereoHits.cuh
+++ b/cuda/SciFi/PrForward/include/FindStereoHits.cuh
@@ -9,7 +9,6 @@
 #include "SciFiEventModel.cuh"
 #include "TrackUtils.cuh"
 #include "HitUtils.cuh"
-#include "PrVeloUT.cuh"
 
 /**
    Functions related to selecting hits on the uv planes,
diff --git a/cuda/SciFi/PrForward/include/FindXHits.cuh b/cuda/SciFi/PrForward/include/FindXHits.cuh
index 0ae60f6abd4..ff17e8e3eb3 100644
--- a/cuda/SciFi/PrForward/include/FindXHits.cuh
+++ b/cuda/SciFi/PrForward/include/FindXHits.cuh
@@ -12,7 +12,6 @@
 #include "HitUtils.cuh"
 #include "LinearFitting.cuh"
 #include "ReferencePlaneProjection.cuh"
-#include "PrVeloUT.cuh"
 #include "SciFiEventModel.cuh"
 
 #include "LookingForwardUtils.h"
diff --git a/cuda/SciFi/PrForward/include/PrForwardTools.cuh b/cuda/SciFi/PrForward/include/PrForwardTools.cuh
index 7309da577a5..a4c924a45bf 100644
--- a/cuda/SciFi/PrForward/include/PrForwardTools.cuh
+++ b/cuda/SciFi/PrForward/include/PrForwardTools.cuh
@@ -14,7 +14,6 @@
 #include "SciFiDefinitions.cuh"
 #include "VeloDefinitions.cuh"
 #include "UTDefinitions.cuh"
-#include "PrVeloUT.cuh"
 #include "PrForwardConstants.cuh"
 #include "TrackUtils.cuh"
 #include "LinearFitting.cuh"
diff --git a/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh b/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
index 7137603555e..b1e549f5948 100644
--- a/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
+++ b/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
@@ -7,7 +7,6 @@
 #include <fstream>
 
 #include "SciFiDefinitions.cuh"
-#include "PrVeloUT.cuh"
 #include "TrackUtils.cuh"
 #include "SciFiEventModel.cuh"
 
diff --git a/cuda/SciFi/PrForward/include/TrackUtils.cuh b/cuda/SciFi/PrForward/include/TrackUtils.cuh
index 0c90ae52edd..fb3577f5a3c 100644
--- a/cuda/SciFi/PrForward/include/TrackUtils.cuh
+++ b/cuda/SciFi/PrForward/include/TrackUtils.cuh
@@ -4,7 +4,6 @@
 
 #include "SciFiDefinitions.cuh"
 #include "PrForwardConstants.cuh"
-#include "PrVeloUT.cuh"
 #include "HitUtils.cuh"
 #include "ParabolaFitting.cuh"
 #include "SciFiEventModel.cuh"
diff --git a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
index 2830fbace96..1e9f9fb7dd2 100644
--- a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
+++ b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
@@ -12,7 +12,6 @@
 #include "HitUtils.cuh"
 #include "LinearFitting.cuh"
 #include "ReferencePlaneProjection.cuh"
-#include "PrVeloUT.cuh"
 #include "SciFiEventModel.cuh"
 #include "LookingForwardUtils.h"
 
diff --git a/cuda/UT/compassUT/include/FindBestHits.cuh b/cuda/UT/compassUT/include/FindBestHits.cuh
index 484594bf8da..19e2480d4fd 100644
--- a/cuda/UT/compassUT/include/FindBestHits.cuh
+++ b/cuda/UT/compassUT/include/FindBestHits.cuh
@@ -1,5 +1,6 @@
 #pragma once
 
+#include "UTEventModel.cuh"
 #include "UTDefinitions.cuh"
 #include "CompassUTDefinitions.cuh"
 #include "FindBestHits.cuh"
diff --git a/cuda/UT/compassUT/src/CompassUT.cu b/cuda/UT/compassUT/src/CompassUT.cu
index 037364baecc..35faba356e7 100644
--- a/cuda/UT/compassUT/src/CompassUT.cu
+++ b/cuda/UT/compassUT/src/CompassUT.cu
@@ -10,7 +10,7 @@ __global__ void compass_ut(
   uint* dev_velo_track_hit_number,
   char* dev_velo_track_hits,
   char* dev_velo_states,
-  PrUTMagnetTool* dev_ut_magnet_tool,
+  UTMagnetTool* dev_ut_magnet_tool,
   const float* dev_magnet_polarity,
   const float* dev_ut_dxDy,
   int* dev_active_tracks,
@@ -298,7 +298,7 @@ __device__ void save_track(
   const int index2 = std::max(0, std::min(10, int((var[1] + 250) / 500 * 10)));
   const int index3 = std::max(0, std::min(10, int(var[2] / 800 * 10)));
 
-  assert(master_index(index1, index2, index3) < PrUTMagnetTool::N_bdl_vals);
+  assert(master_index(index1, index2, index3) < UTMagnetTool::N_bdl_vals);
   float bdl = bdl_table[master_index(index1, index2, index3)];
 
   const int num_idx = 3;
diff --git a/cuda/UT/compassUT/src/SearchWindows.cu b/cuda/UT/compassUT/src/SearchWindows.cu
index 257183abe8d..55f2e3bd5f2 100644
--- a/cuda/UT/compassUT/src/SearchWindows.cu
+++ b/cuda/UT/compassUT/src/SearchWindows.cu
@@ -9,7 +9,7 @@ __global__ void ut_search_windows(
   int* dev_atomics_storage, // semi_prefixsum, offset to tracks
   uint* dev_velo_track_hit_number,
   char* dev_velo_states,
-  PrUTMagnetTool* dev_ut_magnet_tool,
+  UTMagnetTool* dev_ut_magnet_tool,
   const float* dev_ut_dxDy,
   const uint* dev_unique_x_sector_layer_offsets, // prefixsum to point to the x hit of the sector, per layer
   const float* dev_unique_sector_xs,             // list of xs that define the groups
diff --git a/integration/non_event_data/include/Consumers.h b/integration/non_event_data/include/Consumers.h
index 8194dbca2ca..4c266107cfe 100644
--- a/integration/non_event_data/include/Consumers.h
+++ b/integration/non_event_data/include/Consumers.h
@@ -46,13 +46,13 @@ namespace Consumers {
   struct UTLookupTables final : public Allen::NonEventData::Consumer {
   public:
 
-    UTLookupTables(PrUTMagnetTool*& tool);
+    UTLookupTables(UTMagnetTool*& tool);
 
     void consume(std::vector<char> const& data) override;
 
   private:
 
-    std::reference_wrapper<PrUTMagnetTool*> m_tool;
+    std::reference_wrapper<UTMagnetTool*> m_tool;
     size_t m_size = 0;
   };
 
diff --git a/integration/non_event_data/src/UTLookupTables.cpp b/integration/non_event_data/src/UTLookupTables.cpp
index 6cb52d9611b..c6172fcfac2 100644
--- a/integration/non_event_data/src/UTLookupTables.cpp
+++ b/integration/non_event_data/src/UTLookupTables.cpp
@@ -9,7 +9,7 @@ namespace {
   using std::to_string;
 }
 
-Consumers::UTLookupTables::UTLookupTables(PrUTMagnetTool*& tool)
+Consumers::UTLookupTables::UTLookupTables(UTMagnetTool*& tool)
   : m_tool{tool} {}
 
 void Consumers::UTLookupTables::consume(std::vector<char> const& data) {
@@ -46,16 +46,16 @@ void Consumers::UTLookupTables::consume(std::vector<char> const& data) {
   p += table_size[0] * sizeof(float);
 
   if (!m_tool) {
-    cudaCheck(cudaMalloc((void**) &m_tool.get(), sizeof(PrUTMagnetTool)));
-    m_size = sizeof(PrUTMagnetTool);
+    cudaCheck(cudaMalloc((void**) &m_tool.get(), sizeof(UTMagnetTool)));
+    m_size = sizeof(UTMagnetTool);
   }
   if (m_size != (data.size() - 7 * sizeof(int) - 2 * sizeof(size_t))) {
     throw StrException{string{"sizes don't match: "} + to_string(m_size)
                               + " " + to_string(data.size())};
   }
 
-  PrUTMagnetTool host_tool{deflection, bdl};
+  UTMagnetTool host_tool{deflection, bdl};
 
   // deflection table
-  cudaCheck(cudaMemcpy(m_tool.get(), &host_tool, sizeof(PrUTMagnetTool), cudaMemcpyHostToDevice));
+  cudaCheck(cudaMemcpy(m_tool.get(), &host_tool, sizeof(UTMagnetTool), cudaMemcpyHostToDevice));
 }
diff --git a/stream/CMakeLists.txt b/stream/CMakeLists.txt
index 79b59cde8a4..8691cbe8cf7 100644
--- a/stream/CMakeLists.txt
+++ b/stream/CMakeLists.txt
@@ -17,7 +17,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/associate/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/global_event_cut/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/ip_cut/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/PrVeloUT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/UTDecoding/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/sorting/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/consolidate/include)
diff --git a/stream/checkers/include/UTSequenceCheckers_impl.cuh b/stream/checkers/include/UTSequenceCheckers_impl.cuh
index 9626e80ccb7..0e23020ac00 100644
--- a/stream/checkers/include/UTSequenceCheckers_impl.cuh
+++ b/stream/checkers/include/UTSequenceCheckers_impl.cuh
@@ -1,6 +1,5 @@
 #include "MomentumForwardStudies.h"
 #include "LookingForwardStudies.h"
-#include "VeloUT.cuh"
 #include "TrackChecker.h"
 
 /**
diff --git a/stream/sequence/include/Constants.cuh b/stream/sequence/include/Constants.cuh
index 27ce3ee0ade..ba0f286ea8a 100644
--- a/stream/sequence/include/Constants.cuh
+++ b/stream/sequence/include/Constants.cuh
@@ -13,7 +13,7 @@
 #include "TMVA_Forward_2.cuh"
 #include "UTDefinitions.cuh"
 #include "Logger.h"
-#include "PrVeloUTMagnetToolDefinitions.h"
+#include "UTMagnetToolDefinitions.h"
 #include "KalmanParametrizations.cuh"
 #include "SciFiParametrization.h"
 #include "LookingForwardConstants.cuh"
@@ -57,7 +57,7 @@ struct Constants {
   gsl::span<uint> dev_ut_region_offsets;
   gsl::span<float> dev_unique_sector_xs;
   gsl::span<char> dev_ut_boards;
-  PrUTMagnetTool* dev_ut_magnet_tool = nullptr;
+  UTMagnetTool* dev_ut_magnet_tool = nullptr;
 
   SciFi::Tracking::TMVA* dev_scifi_tmva1 = nullptr;
   SciFi::Tracking::TMVA* dev_scifi_tmva2 = nullptr;
diff --git a/stream/sequence/include/StreamWrapper.cuh b/stream/sequence/include/StreamWrapper.cuh
index 7aa601af403..c99a6c40640 100644
--- a/stream/sequence/include/StreamWrapper.cuh
+++ b/stream/sequence/include/StreamWrapper.cuh
@@ -5,7 +5,7 @@
 #include <stdint.h>
 
 #include "UTDefinitions.cuh"
-#include "PrVeloUTMagnetToolDefinitions.h"
+#include "UTMagnetToolDefinitions.h"
 #include "SciFiDefinitions.cuh"
 #include "Logger.h"
 #include "Common.h"
diff --git a/stream/setup/include/ConfiguredSequence.cuh b/stream/setup/include/ConfiguredSequence.cuh
index ac3ccc26690..c3ef9e4239c 100644
--- a/stream/setup/include/ConfiguredSequence.cuh
+++ b/stream/setup/include/ConfiguredSequence.cuh
@@ -16,7 +16,6 @@
 #include "UTPreDecode.cuh"
 #include "UTFindPermutation.cuh"
 #include "UTDecodeRawBanksInOrder.cuh"
-#include "VeloUT.cuh"
 #include "VeloEventModel.cuh"
 #include "ConsolidateUT.cuh"
 #include "SciFiCalculateClusterCount.cuh"
@@ -91,6 +90,5 @@
 // eg.
 // "cmake -DSEQUENCE=DefaultSequence .." (or just "cmake ..") matches "sequences/DefaultSequence.cuh"
 // "cmake -DSEQUENCE=Velo .." matches "sequences/Velo.cuh"
-// "cmake -DSEQUENCE=VeloUT .." matches "sequences/VeloUT.cuh"
 
 #include "ConfiguredSequence.h"
diff --git a/stream/visitors/UT/src/VeloUTTrackingVisitor.cu b/stream/visitors/UT/src/VeloUTTrackingVisitor.cu
deleted file mode 100644
index e462dcfef4f..00000000000
--- a/stream/visitors/UT/src/VeloUTTrackingVisitor.cu
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "SequenceVisitor.cuh"
-#include "VeloUT.cuh"
-
-template<>
-void SequenceVisitor::set_arguments_size<veloUT_t>(
-  veloUT_t::arguments_t arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  const HostBuffers& host_buffers)
-{
-  arguments.set_size<dev_ut_tracks>(host_buffers.host_number_of_selected_events[0] * UT::Constants::max_num_tracks);
-  arguments.set_size<dev_atomics_ut>(host_buffers.host_number_of_selected_events[0] * UT::num_atomics + 1);
-}
-
-template<>
-void SequenceVisitor::visit<veloUT_t>(
-  veloUT_t& state,
-  const veloUT_t::arguments_t& arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  HostBuffers& host_buffers,
-  cudaStream_t& cuda_stream,
-  cudaEvent_t& cuda_generic_event)
-{
-  state.set_opts(dim3(host_buffers.host_number_of_selected_events[0]), dim3(32), cuda_stream);
-  state.set_arguments(
-    arguments.offset<dev_ut_hits>(),
-    arguments.offset<dev_ut_hit_offsets>(),
-    arguments.offset<dev_atomics_velo>(),
-    arguments.offset<dev_velo_track_hit_number>(),
-    arguments.offset<dev_velo_track_hits>(),
-    arguments.offset<dev_velo_states>(),
-    arguments.offset<dev_ut_tracks>(),
-    arguments.offset<dev_atomics_ut>(),
-    constants.dev_ut_magnet_tool,
-    constants.dev_ut_dxDy.data(),
-    constants.dev_unique_x_sector_layer_offsets.data(),
-    constants.dev_unique_x_sector_offsets.data(),
-    constants.dev_unique_sector_xs.data());
-
-  state.invoke();
-}
-- 
GitLab


From efb5bc8aec3a97ad9e0e9397494333c218ced5d2 Mon Sep 17 00:00:00 2001
From: gligorov <vladimir.gligorov@cern.ch>
Date: Fri, 21 Jun 2019 10:52:51 +0200
Subject: [PATCH 4/8] remove dedicated IP cut code

---
 .../sequences/VeloPVIPUTSciFiDecoding.h       | 42 ----------------
 configuration/sequences/VeloPVIPUTSciFiMuon.h | 49 -------------------
 cuda/CMakeLists.txt                           |  1 -
 cuda/ip_cut/CMakeLists.txt                    | 20 --------
 cuda/ip_cut/include/IPCut.cuh                 | 26 ----------
 cuda/ip_cut/include/IPCutValues.cuh           | 15 ------
 cuda/ip_cut/src/IPCut.cu                      | 35 -------------
 stream/CMakeLists.txt                         |  3 --
 stream/setup/include/ConfiguredSequence.cuh   |  1 -
 stream/visitors/ip_cut/src/IPCutVisitor.cu    | 27 ----------
 10 files changed, 219 deletions(-)
 delete mode 100644 configuration/sequences/VeloPVIPUTSciFiDecoding.h
 delete mode 100644 configuration/sequences/VeloPVIPUTSciFiMuon.h
 delete mode 100644 cuda/ip_cut/CMakeLists.txt
 delete mode 100644 cuda/ip_cut/include/IPCut.cuh
 delete mode 100644 cuda/ip_cut/include/IPCutValues.cuh
 delete mode 100644 cuda/ip_cut/src/IPCut.cu
 delete mode 100644 stream/visitors/ip_cut/src/IPCutVisitor.cu

diff --git a/configuration/sequences/VeloPVIPUTSciFiDecoding.h b/configuration/sequences/VeloPVIPUTSciFiDecoding.h
deleted file mode 100644
index cf2f4d9bf9b..00000000000
--- a/configuration/sequences/VeloPVIPUTSciFiDecoding.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/**
- * Specify here the algorithms to be executed in the sequence,
- * in the expected order of execution.
- */
-SEQUENCE_T(
-  init_event_list_t,
-  global_event_cut_t,
-  velo_estimate_input_size_t,
-  prefix_sum_velo_clusters_t,
-  velo_masked_clustering_t,
-  velo_calculate_phi_and_sort_t,
-  velo_fill_candidates_t,
-  velo_search_by_triplet_t,
-  velo_weak_tracks_adder_t,
-  copy_and_prefix_sum_single_block_velo_t,
-  copy_velo_track_hit_number_t,
-  prefix_sum_velo_track_hit_number_t,
-  consolidate_velo_tracks_t,
-  velo_kalman_fit_t,
-  pv_beamline_extrapolate_t,
-  pv_beamline_histo_t,
-  pv_beamline_peak_t,
-  pv_beamline_multi_fitter_t,
-  pv_beamline_cleanup_t,
-  velo_pv_ip_t,
-  ip_cut_t,
-  ut_calculate_number_of_hits_t,
-  prefix_sum_ut_hits_t,
-  ut_pre_decode_t,
-  ut_find_permutation_t,
-  ut_decode_raw_banks_in_order_t,
-  ut_search_windows_t,
-  compass_ut_t,
-  copy_and_prefix_sum_single_block_ut_t,
-  copy_ut_track_hit_number_t,
-  prefix_sum_ut_track_hit_number_t,
-  consolidate_ut_tracks_t,
-  scifi_calculate_cluster_count_v4_t,
-  prefix_sum_scifi_hits_t,
-  scifi_pre_decode_v4_t,
-  scifi_raw_bank_decoder_v4_t,
-  scifi_direct_decoder_v4_t)
diff --git a/configuration/sequences/VeloPVIPUTSciFiMuon.h b/configuration/sequences/VeloPVIPUTSciFiMuon.h
deleted file mode 100644
index 1bdbc48cbc3..00000000000
--- a/configuration/sequences/VeloPVIPUTSciFiMuon.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * Specify here the algorithms to be executed in the sequence,
- * in the expected order of execution.
- */
-SEQUENCE_T(
-  init_event_list_t,
-  global_event_cut_t,
-  velo_estimate_input_size_t,
-  prefix_sum_velo_clusters_t,
-  velo_masked_clustering_t,
-  velo_calculate_phi_and_sort_t,
-  velo_fill_candidates_t,
-  velo_search_by_triplet_t,
-  velo_weak_tracks_adder_t,
-  copy_and_prefix_sum_single_block_velo_t,
-  copy_velo_track_hit_number_t,
-  prefix_sum_velo_track_hit_number_t,
-  consolidate_velo_tracks_t,
-  velo_kalman_fit_t,
-  pv_beamline_extrapolate_t,
-  pv_beamline_histo_t,
-  pv_beamline_peak_t,
-  pv_beamline_multi_fitter_t,
-  pv_beamline_cleanup_t,
-  velo_pv_ip_t,
-  ip_cut_t,
-  ut_calculate_number_of_hits_t,
-  prefix_sum_ut_hits_t,
-  ut_pre_decode_t,
-  ut_find_permutation_t,
-  ut_decode_raw_banks_in_order_t,
-  ut_search_windows_t,
-  compass_ut_t,
-  copy_and_prefix_sum_single_block_ut_t,
-  copy_ut_track_hit_number_t,
-  prefix_sum_ut_track_hit_number_t,
-  consolidate_ut_tracks_t,
-  scifi_calculate_cluster_count_v4_t,
-  prefix_sum_scifi_hits_t,
-  scifi_pre_decode_v4_t,
-  scifi_raw_bank_decoder_v4_t,
-  scifi_direct_decoder_v4_t,
-  scifi_pr_forward_t,
-  copy_and_prefix_sum_single_block_scifi_t,
-  copy_scifi_track_hit_number_t,
-  prefix_sum_scifi_track_hit_number_t,
-  consolidate_scifi_tracks_t,
-  muon_catboost_features_extraction_t,
-  muon_catboost_evaluator_t)
diff --git a/cuda/CMakeLists.txt b/cuda/CMakeLists.txt
index 3a87ca3a7eb..ad7840bff0b 100644
--- a/cuda/CMakeLists.txt
+++ b/cuda/CMakeLists.txt
@@ -1,5 +1,4 @@
 add_subdirectory(utils)
-add_subdirectory(ip_cut)
 add_subdirectory(global_event_cut)
 add_subdirectory(velo)
 add_subdirectory(PV/patPV)
diff --git a/cuda/ip_cut/CMakeLists.txt b/cuda/ip_cut/CMakeLists.txt
deleted file mode 100644
index 6b823ed0ab3..00000000000
--- a/cuda/ip_cut/CMakeLists.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-file(GLOB ip_cut "src/*cu")
-
-include_directories(${CMAKE_SOURCE_DIR}/main/include)
-include_directories(${CMAKE_SOURCE_DIR}/stream/gear/include)
-include_directories(${CMAKE_SOURCE_DIR}/stream/setup/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/associate/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/beamlinePV/include)
-include_directories(include)
-
-add_library(IPCut STATIC
-  ${ip_cut}
-)
-set_property(TARGET IPCut PROPERTY
-             CUDA_SEPARABLE_COMPILATION ON)
diff --git a/cuda/ip_cut/include/IPCut.cuh b/cuda/ip_cut/include/IPCut.cuh
deleted file mode 100644
index 6a5b8d3baa0..00000000000
--- a/cuda/ip_cut/include/IPCut.cuh
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include "Common.h"
-#include "Handler.cuh"
-#include "PV_Definitions.cuh"
-#include "VeloEventModel.cuh"
-#include "VeloConsolidated.cuh"
-#include "ArgumentsCommon.cuh"
-#include "ArgumentsVelo.cuh"
-
-__global__ void ip_cut(
-  char* dev_kalman_velo_states,
-  int* dev_atomics_velo,
-  uint* dev_velo_track_hit_number,
-  char* dev_velo_pv_ip,
-  bool* dev_accepted_velo_tracks);
-
-ALGORITHM(
-  ip_cut,
-  ip_cut_t,
-  ARGUMENTS(
-    dev_velo_kalman_beamline_states,
-    dev_atomics_velo,
-    dev_velo_track_hit_number,
-    dev_velo_pv_ip,
-    dev_accepted_velo_tracks))
diff --git a/cuda/ip_cut/include/IPCutValues.cuh b/cuda/ip_cut/include/IPCutValues.cuh
deleted file mode 100644
index 5d58f0ffd7c..00000000000
--- a/cuda/ip_cut/include/IPCutValues.cuh
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-/**
-   Contains constants needed for IP cuts
-   - cut values
-
- */
-#include "SystemOfUnits.h"
-#include <cassert>
-
-namespace Cuts {
-  namespace IP {
-    constexpr float baseline = 100.f * Gaudi::Units::um;
-  }
-} // namespace Cuts
diff --git a/cuda/ip_cut/src/IPCut.cu b/cuda/ip_cut/src/IPCut.cu
deleted file mode 100644
index f650e9078ae..00000000000
--- a/cuda/ip_cut/src/IPCut.cu
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <iostream>
-#include <functional>
-#include <algorithm>
-
-#include "IPCut.cuh"
-#include <AssociateConsolidated.cuh>
-#include <IPCutValues.cuh>
-
-__global__ void ip_cut(
-  char* dev_kalman_velo_states,
-  int* dev_atomics_velo,
-  uint* dev_velo_track_hit_number,
-  char* dev_velo_pv_ip,
-  bool* dev_accepted_velo_tracks)
-{
-
-  const uint number_of_events = gridDim.x;
-  const uint event_number = blockIdx.x;
-
-  // Velo consolidated types
-  const Velo::Consolidated::Tracks velo_tracks {
-    (uint*) dev_atomics_velo, dev_velo_track_hit_number, event_number, number_of_events};
-  const uint number_of_tracks_event = velo_tracks.number_of_tracks(event_number);
-  const uint event_tracks_offset = velo_tracks.tracks_offset(event_number);
-
-  Associate::Consolidated::Table velo_pv_ip {dev_velo_pv_ip, velo_tracks.total_number_of_tracks};
-  // The track <-> PV association table for this event
-  auto pv_table = velo_pv_ip.event_table(velo_tracks, event_number);
-
-  bool* accepted = dev_accepted_velo_tracks + event_tracks_offset;
-
-  for (int i = threadIdx.x; i < number_of_tracks_event; i += blockDim.x) {
-    accepted[i] = (pv_table.value[i] > Cuts::IP::baseline);
-  }
-}
diff --git a/stream/CMakeLists.txt b/stream/CMakeLists.txt
index 8691cbe8cf7..6477e2a843f 100644
--- a/stream/CMakeLists.txt
+++ b/stream/CMakeLists.txt
@@ -15,7 +15,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/associate/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/global_event_cut/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/ip_cut/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/UTDecoding/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/sorting/include)
@@ -90,7 +89,6 @@ file(GLOB stream_sequence "sequence/src/*cu")
 file(GLOB stream_sequence_cpp "sequence/src/*cpp")
 file(GLOB stream_setup "setup/src/*cu")
 file(GLOB stream_visitors_gec "visitors/global_event_cut/src/*cu")
-file(GLOB stream_visitors_ip "visitors/ip_cut/src/*cu")
 file(GLOB stream_visitors_velo "visitors/velo/src/*cu")
 file(GLOB stream_visitors_patPV "visitors/patPV/src/*cu")
 file(GLOB stream_visitors_beamlinePV "visitors/beamlinePV/src/*cu")
@@ -135,7 +133,6 @@ target_link_libraries(Stream PRIVATE
   Common
   Utils
   Associate
-  IPCut
   GlobalEventCut
   Velo
   PatPV
diff --git a/stream/setup/include/ConfiguredSequence.cuh b/stream/setup/include/ConfiguredSequence.cuh
index c3ef9e4239c..343e9d16e75 100644
--- a/stream/setup/include/ConfiguredSequence.cuh
+++ b/stream/setup/include/ConfiguredSequence.cuh
@@ -38,7 +38,6 @@
 #include "pv_beamline_multi_fitter.cuh"
 #include "pv_beamline_cleanup.cuh"
 #include "RunForwardCPU.h"
-#include "IPCut.cuh"
 #include "VeloPVIP.cuh"
 #include "RunMomentumForwardCPU.h"
 #include "RunBeamlinePVOnCPU.h"
diff --git a/stream/visitors/ip_cut/src/IPCutVisitor.cu b/stream/visitors/ip_cut/src/IPCutVisitor.cu
deleted file mode 100644
index f18307b82b5..00000000000
--- a/stream/visitors/ip_cut/src/IPCutVisitor.cu
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "Logger.h"
-#include "IPCut.cuh"
-#include "SequenceVisitor.cuh"
-
-DEFINE_EMPTY_SET_ARGUMENTS_SIZE(ip_cut_t)
-
-template<>
-void SequenceVisitor::visit<ip_cut_t>(
-  ip_cut_t& state,
-  const ip_cut_t::arguments_t& arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  HostBuffers& host_buffers,
-  cudaStream_t& cuda_stream,
-  cudaEvent_t& cuda_generic_event)
-{
-  // Setup opts and arguments for kernel call
-  state.set_opts(dim3(host_buffers.host_number_of_selected_events[0]), dim3(32), cuda_stream);
-  state.set_arguments(
-    arguments.offset<dev_velo_kalman_beamline_states>(),
-    arguments.offset<dev_atomics_velo>(),
-    arguments.offset<dev_velo_track_hit_number>(),
-    arguments.offset<dev_velo_pv_ip>(),
-    arguments.offset<dev_accepted_velo_tracks>());
-
-  state.invoke();
-}
-- 
GitLab


From 232d6c04d27c39ad350429b164cbcae788653314 Mon Sep 17 00:00:00 2001
From: gligorov <vladimir.gligorov@cern.ch>
Date: Fri, 21 Jun 2019 14:47:01 +0200
Subject: [PATCH 5/8] Get rid of PrForward in cuda, refactor the remaining
 useful components

---
 CMakeLists.txt                                |   3 +-
 checker/tracking/CMakeLists.txt               |   1 -
 cuda/SciFi/CMakeLists.txt                     |   9 +-
 cuda/SciFi/PrForward/.gitignore               |   1 -
 cuda/SciFi/PrForward/README.md                |   1 -
 .../PrForward/include/FindStereoHits.cuh      |  49 --
 cuda/SciFi/PrForward/include/FindXHits.cuh    | 120 ---
 cuda/SciFi/PrForward/include/HitUtils.cuh     | 220 -----
 .../SciFi/PrForward/include/LinearFitting.cuh |  77 --
 .../PrForward/include/ParabolaFitting.cuh     |  18 -
 cuda/SciFi/PrForward/include/PrForward.cuh    |  59 --
 .../PrForward/include/PrForwardConstants.cuh  | 236 -----
 .../PrForward/include/PrForwardTools.cuh      |  88 --
 .../include/ReferencePlaneProjection.cuh      |  27 -
 cuda/SciFi/PrForward/include/TrackUtils.cuh   |  74 --
 cuda/SciFi/PrForward/src/FindStereoHits.cu    | 247 ------
 cuda/SciFi/PrForward/src/FindXHits.cu         | 830 ------------------
 cuda/SciFi/PrForward/src/HitUtils.cu          | 324 -------
 cuda/SciFi/PrForward/src/LinearFitting.cu     | 179 ----
 cuda/SciFi/PrForward/src/ParabolaFitting.cu   |  59 --
 cuda/SciFi/PrForward/src/PrForward.cu         | 195 ----
 cuda/SciFi/PrForward/src/PrForwardTools.cu    | 398 ---------
 .../PrForward/src/ReferencePlaneProjection.cu |  40 -
 cuda/SciFi/PrForward/src/TrackUtils.cu        | 264 ------
 cuda/SciFi/classifiers/README.md              |   1 +
 .../include/TMVA_Forward.cuh                  |   2 -
 .../include/TMVA_Forward_1.cuh                |   0
 .../include/TMVA_Forward_2.cuh                |   0
 .../src/TMVA_Forward.cu                       |   0
 .../SciFi/common/include/SciFiDefinitions.cuh |  92 +-
 .../consolidate/include/ConsolidateSciFi.cuh  |   1 -
 .../include/LFCollectCandidates.cuh           |   1 -
 .../include/LFSearchInitialWindows.cuh        |   2 +-
 .../include/LFSearchInitialWindowsImpl.cuh    |   6 +-
 .../include/LFTripletKeepBest.cuh             |   1 -
 .../include/LFTripletSeeding.cuh              |   1 -
 .../triplet_seeding/src/LFTripletSeeding.cu   |   1 -
 cuda/SciFi/utils/README.md                    |   1 +
 cuda/SciFi/utils/include/HitUtils.cuh         |  28 +
 cuda/SciFi/utils/include/TrackUtils.cuh       |  35 +
 cuda/SciFi/utils/src/HitUtils.cu              |  17 +
 cuda/SciFi/utils/src/TrackUtils.cu            | 108 +++
 cuda/associate/CMakeLists.txt                 |   1 -
 cuda/global_event_cut/CMakeLists.txt          |   1 -
 cuda/kalman/CMakeLists.txt                    |   1 -
 cuda/muon/CMakeLists.txt                      |   1 -
 cuda/selections/CMakeLists.txt                |   1 -
 cuda/utils/CMakeLists.txt                     |   1 -
 cuda/vertex_fit/CMakeLists.txt                |   1 -
 integration/non_event_data/CMakeLists.txt     |   2 +-
 mdf/CMakeLists.txt                            |   1 -
 stream/CMakeLists.txt                         |   5 +-
 .../include/SciFiSequenceCheckers_impl.cuh    |   3 +-
 .../include/UTSequenceCheckers_impl.cuh       |   1 +
 .../include/VeloSequenceCheckers_impl.cuh     |   1 +
 stream/sequence/include/Constants.cuh         |   1 -
 stream/setup/include/ConfiguredSequence.cuh   |   2 -
 .../src/CpuSciFiMomentumForwardVisitor.cu     |   1 -
 .../SciFi/src/CpuSciFiPrForwardVisitor.cu     |  90 --
 .../SciFi/src/SciFiPrForwardVisitor.cu        |  48 -
 x86/SciFi/CMakeLists.txt                      |   1 -
 x86/SciFi/LookingForward/CMakeLists.txt       |   3 +-
 .../include/LookingForwardConstants.h         |   2 +-
 .../include/LookingForwardSbt.h               |   2 +-
 .../include/LookingForwardStudies.h           |   1 +
 .../include/LookingForwardUtils.h             |  17 +-
 .../src/LookingForwardStudies.cpp             |   2 -
 .../src/LookingForwardUtils.cpp               | 158 ++++
 x86/SciFi/MomentumForward/CMakeLists.txt      |   4 +-
 .../include/MomentumForwardConstants.h        |   2 +-
 x86/SciFi/PrForward/CMakeLists.txt            |  40 -
 .../PrForward/include/PrForwardWrapper.h      |  17 -
 x86/SciFi/PrForward/include/RunForwardCPU.h   |  47 -
 x86/SciFi/PrForward/src/PrForwardWrapper.cpp  |  39 -
 x86/SciFi/PrForward/src/RunForwardCPU.cpp     | 158 ----
 x86/global_event_cut/CMakeLists.txt           |   1 -
 76 files changed, 477 insertions(+), 3995 deletions(-)
 delete mode 100644 cuda/SciFi/PrForward/.gitignore
 delete mode 100644 cuda/SciFi/PrForward/README.md
 delete mode 100644 cuda/SciFi/PrForward/include/FindStereoHits.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/FindXHits.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/HitUtils.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/LinearFitting.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/ParabolaFitting.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/PrForward.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/PrForwardConstants.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/PrForwardTools.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
 delete mode 100644 cuda/SciFi/PrForward/include/TrackUtils.cuh
 delete mode 100644 cuda/SciFi/PrForward/src/FindStereoHits.cu
 delete mode 100644 cuda/SciFi/PrForward/src/FindXHits.cu
 delete mode 100644 cuda/SciFi/PrForward/src/HitUtils.cu
 delete mode 100644 cuda/SciFi/PrForward/src/LinearFitting.cu
 delete mode 100644 cuda/SciFi/PrForward/src/ParabolaFitting.cu
 delete mode 100644 cuda/SciFi/PrForward/src/PrForward.cu
 delete mode 100644 cuda/SciFi/PrForward/src/PrForwardTools.cu
 delete mode 100644 cuda/SciFi/PrForward/src/ReferencePlaneProjection.cu
 delete mode 100644 cuda/SciFi/PrForward/src/TrackUtils.cu
 create mode 100644 cuda/SciFi/classifiers/README.md
 rename cuda/SciFi/{PrForward => classifiers}/include/TMVA_Forward.cuh (96%)
 rename cuda/SciFi/{PrForward => classifiers}/include/TMVA_Forward_1.cuh (100%)
 rename cuda/SciFi/{PrForward => classifiers}/include/TMVA_Forward_2.cuh (100%)
 rename cuda/SciFi/{PrForward => classifiers}/src/TMVA_Forward.cu (100%)
 create mode 100644 cuda/SciFi/utils/README.md
 create mode 100644 cuda/SciFi/utils/include/HitUtils.cuh
 create mode 100644 cuda/SciFi/utils/include/TrackUtils.cuh
 create mode 100644 cuda/SciFi/utils/src/HitUtils.cu
 create mode 100644 cuda/SciFi/utils/src/TrackUtils.cu
 delete mode 100644 stream/visitors/SciFi/src/CpuSciFiPrForwardVisitor.cu
 delete mode 100644 stream/visitors/SciFi/src/SciFiPrForwardVisitor.cu
 delete mode 100644 x86/SciFi/PrForward/CMakeLists.txt
 delete mode 100644 x86/SciFi/PrForward/include/PrForwardWrapper.h
 delete mode 100644 x86/SciFi/PrForward/include/RunForwardCPU.h
 delete mode 100644 x86/SciFi/PrForward/src/PrForwardWrapper.cpp
 delete mode 100644 x86/SciFi/PrForward/src/RunForwardCPU.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ffeb915be4f..06ac84cf195 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -215,7 +215,7 @@ include_directories(cuda/SciFi/looking_forward_sbt/extend_tracks_uv/include)
 include_directories(cuda/SciFi/looking_forward_sbt/quality_filter/include)
 include_directories(cuda/SciFi/looking_forward_sbt/quality_filter_x/include)
 include_directories(cuda/SciFi/looking_forward_sbt/search_uv_windows/include)
-include_directories(cuda/SciFi/PrForward/include)
+include_directories(cuda/SciFi/classifiers/include)
 include_directories(cuda/SciFi/consolidate/include)
 include_directories(cuda/muon/common/include)
 include_directories(cuda/utils/prefix_sum/include)
@@ -227,7 +227,6 @@ include_directories(checker/tracking/include)
 include_directories(checker/pv/include)
 include_directories(checker/selections/include)
 include_directories(stream/sequence/include)
-include_directories(x86/SciFi/PrForward/include)
 include_directories(x86/SciFi/LookingForward/include)
 include_directories(x86/SciFi/MomentumForward/include)
 include_directories(cuda/UT/UTDecoding/include)
diff --git a/checker/tracking/CMakeLists.txt b/checker/tracking/CMakeLists.txt
index fa931478c6a..7ff1dcecfc3 100644
--- a/checker/tracking/CMakeLists.txt
+++ b/checker/tracking/CMakeLists.txt
@@ -9,7 +9,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/kalman/ParKalman/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/beamlinePV/include)
diff --git a/cuda/SciFi/CMakeLists.txt b/cuda/SciFi/CMakeLists.txt
index a387c9b8156..fcffc61c06c 100644
--- a/cuda/SciFi/CMakeLists.txt
+++ b/cuda/SciFi/CMakeLists.txt
@@ -19,7 +19,8 @@ file(GLOB scifi_lf_quality_filter "looking_forward_sbt/quality_filter/src/*cu")
 file(GLOB scifi_lf_quality_filter_x "looking_forward_sbt/quality_filter_x/src/*cu")
 file(GLOB scifi_lf_search_uv_windows "looking_forward_sbt/search_uv_windows/src/*cu")
 file(GLOB scifi_lf_fit "looking_forward_sbt/fit/src/*cu")
-file(GLOB scifi_prforward "PrForward/src/*cu")
+file(GLOB scifi_utils "utils/src/*cu")
+file(GLOB scifi_classifiers "classifiers/src/*cu")
 file(GLOB scifi_consolidate "consolidate/src/*cu")
 
 include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
@@ -61,12 +62,14 @@ include_directories(looking_forward_sbt/quality_filter/include)
 include_directories(looking_forward_sbt/quality_filter_x/include)
 include_directories(looking_forward_sbt/search_uv_windows/include)
 include_directories(looking_forward_sbt/fit/include)
-include_directories(PrForward/include)
+include_directories(utils/include)
+include_directories(classifiers/include)
 include_directories(consolidate/include)
 
 add_library(SciFi STATIC
   ${scifi_common}
   ${scifi_preprocessing}
+  ${scifi_utils}
   ${scifi_lf_common}
   ${scifi_lf_calculate_first_layer_window}
   ${scifi_lf_calculate_second_layer_window}
@@ -86,7 +89,7 @@ add_library(SciFi STATIC
   ${scifi_lf_quality_filter_x}
   ${scifi_lf_search_uv_windows}
   ${scifi_lf_fit}
-  ${scifi_prforward}
+  ${scifi_classifiers}
   ${scifi_consolidate}
 )
 
diff --git a/cuda/SciFi/PrForward/.gitignore b/cuda/SciFi/PrForward/.gitignore
deleted file mode 100644
index 378eac25d31..00000000000
--- a/cuda/SciFi/PrForward/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build
diff --git a/cuda/SciFi/PrForward/README.md b/cuda/SciFi/PrForward/README.md
deleted file mode 100644
index cc8a2c28798..00000000000
--- a/cuda/SciFi/PrForward/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Implementation of the forward based on Rec v23r3
diff --git a/cuda/SciFi/PrForward/include/FindStereoHits.cuh b/cuda/SciFi/PrForward/include/FindStereoHits.cuh
deleted file mode 100644
index c14347c5657..00000000000
--- a/cuda/SciFi/PrForward/include/FindStereoHits.cuh
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-#include "SciFiDefinitions.cuh"
-#include "SciFiEventModel.cuh"
-#include "TrackUtils.cuh"
-#include "HitUtils.cuh"
-
-/**
-   Functions related to selecting hits on the uv planes,
-   which match to the VeloUT input track
- */
-
-__host__ __device__ void collectStereoHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::Arrays* constArrays,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits);
-
-__host__ __device__ bool selectStereoHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  const SciFi::Tracking::Arrays* constArrays,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
-
-__host__ __device__ bool addHitsOnEmptyStereoLayers(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  const SciFi::Tracking::Arrays* constArrays,
-  PlaneCounter& planeCounter,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
diff --git a/cuda/SciFi/PrForward/include/FindXHits.cuh b/cuda/SciFi/PrForward/include/FindXHits.cuh
deleted file mode 100644
index ff17e8e3eb3..00000000000
--- a/cuda/SciFi/PrForward/include/FindXHits.cuh
+++ /dev/null
@@ -1,120 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-#include "SciFiDefinitions.cuh"
-#include "PrForwardConstants.cuh"
-#include "UTDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "HitUtils.cuh"
-#include "LinearFitting.cuh"
-#include "ReferencePlaneProjection.cuh"
-#include "SciFiEventModel.cuh"
-
-#include "LookingForwardUtils.h"
-
-/**
-   Functions related to selecting hits on the x planes,
-   which match to the VeloUT input track
- */
-__host__ void collectAllXHits_proto_p(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const MiniState& UT_state,
-  const float qOverP,
-  int side, 
-  std::array<int, 2 * 6>& windows_x,
-  std::array<int, 2 * 6>& windows_uv,
-  std::array<float, 4 * 6>& parameters_uv,
-  const SciFiWindowsParams& window_params,
-  const std::array<int, 12> true_scifi_indices_per_layer);
-
-__host__ void x_limits_from_dxRef( 
-  const SciFi::Tracking::Arrays* constArrays,
-  const MiniState& velo_state,
-  const float InvPz,
-  const float p,
-  const float tx2,
-  const float ty2, 
-  const bool wSignTreatment, 
-  float& xBoundOnRef,
-  float& xBoundOnRefWS); 
-
-__host__ void collectAllXHits_proto(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& UT_state,
-  const float qOverP,
-  int side,
-  std::array<int, 2 * 6>& windows_x,
-  std::array<int, 2 * 6>& windows_uv,
-  std::array<float, 4 * 6>& parameters_uv);
-  
-__host__ __device__ void collectAllXHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int& n_x_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const float qop,
-  int side);
-
-__host__ __device__ void improveXCluster(
-  int& it2,
-  const int it1,
-  const int itEnd,
-  const int n_x_hits,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const float xWindow,
-  const SciFi::Tracking::HitSearchCuts& pars,
-  PlaneCounter& planeCounter,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ void selectXCandidates(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int& n_x_hits,
-  bool usedHits[SciFi::Tracking::max_x_hits],
-  float coordX[SciFi::Tracking::max_x_hits],
-  SciFi::Tracking::Track candidate_tracks[SciFi::Constants::max_tracks],
-  int& n_candidate_tracks,
-  const float zRef_track,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::Arrays* constArrays,
-  int side,
-  const bool secondLoop);
-
-__host__ __device__ bool addHitsOnEmptyXLayers(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  bool fullFit,
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  const SciFi::Tracking::Arrays* constArrays,
-  PlaneCounter& planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars_cur,
-  int side);
diff --git a/cuda/SciFi/PrForward/include/HitUtils.cuh b/cuda/SciFi/PrForward/include/HitUtils.cuh
deleted file mode 100644
index dad26033d92..00000000000
--- a/cuda/SciFi/PrForward/include/HitUtils.cuh
+++ /dev/null
@@ -1,220 +0,0 @@
-#pragma once
-
-#include "SciFiDefinitions.cuh"
-#include "PrForwardConstants.cuh"
-#include "SciFiEventModel.cuh"
-
-/**
-   Helper functions related to properties of hits on planes
- */
-
-// Helper used to keep track of how many x / stereo hits per lane have
-// been added to a candidate track
-struct PlaneCounter {
-  int planeList[SciFi::Constants::n_layers] = {0};
-  unsigned int nbDifferent = 0;
-
-  __host__ __device__ inline void addHit(int plane)
-  {
-    assert(plane < SciFi::Constants::n_layers);
-    nbDifferent += (int) ((planeList[plane] += 1) == 1);
-  }
-
-  __host__ __device__ inline void removeHit(int plane)
-  {
-    assert(plane < SciFi::Constants::n_layers);
-    nbDifferent -= ((int) ((planeList[plane] -= 1) == 0));
-  }
-
-  __host__ __device__ inline int nbInPlane(int plane) const
-  {
-    assert(plane < SciFi::Constants::n_layers);
-    return planeList[plane];
-  }
-
-  __host__ __device__ inline int nbSingle() const
-  {
-    int single = 0;
-    for (int i = 0; i < SciFi::Constants::n_layers; ++i) {
-      single += planeList[i] == 1 ? 1 : 0;
-    }
-    return single;
-  }
-
-  __host__ __device__ inline void clear()
-  {
-    nbDifferent = 0;
-    for (int i = 0; i < SciFi::Constants::n_layers; ++i) {
-      planeList[i] = 0;
-    }
-  }
-};
-
-__host__ __device__ void countPlanesOfXHits(
-  PlaneCounter& planeCounter,
-  const int it1,
-  const int it2,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ void countUnusedXHitsOnPlanes(
-  PlaneCounter& lplaneCounter,
-  const int itWindowStart,
-  const int itWindowEnd,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ void addXHitsForCandidateWithTooFewPlanes(
-  int& itWindowStart,
-  int& itWindowEnd,
-  const int it2,
-  const int itEnd,
-  float& minInterval,
-  PlaneCounter& lplaneCounter,
-  const int nPlanes,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  int& best,
-  int& bestEnd,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ void collectXHitsToFit(
-  const int it1,
-  const int it2,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  bool usedHits[SciFi::Tracking::max_x_hits],
-  int coordToFit[SciFi::Tracking::max_x_hits],
-  int& n_coordToFit,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  float& xAtRef);
-
-__host__ __device__ int findBestXHitOnEmptyLayer(
-  const int itEnd,
-  const int itH,
-  const SciFi::Hits& scifi_hits,
-  const float maxX,
-  const float xPred);
-
-template<int N>
-__host__ __device__ void sortHitsByKey(float* keys, int n, int* hits)
-{
-  // find permutations
-  uint permutations[N];
-  assert(n <= N);
-  for (int i = 0; i < n; ++i) {
-    uint position = 0;
-    for (int j = 0; j < n; ++j) {
-      // sort keys in ascending order
-      int sort_result = -1;
-      if (keys[i] > keys[j]) sort_result = 1;
-      if (keys[i] == keys[j]) sort_result = 0;
-      position += sort_result > 0 || (sort_result == 0 && i > j);
-    }
-    permutations[position] = i;
-  }
-
-  // apply permutations, store hits in temporary container
-  int hits_tmp[N];
-  float keys_tmp[N];
-  for (int i = 0; i < n; ++i) {
-    const int index = permutations[i];
-    hits_tmp[i] = hits[index];
-    keys_tmp[i] = keys[index];
-  }
-
-  // copy hits back to original container
-  for (int i = 0; i < n; ++i) {
-    hits[i] = hits_tmp[i];
-    keys[i] = keys_tmp[i];
-  }
-}
-
-// check that val is within [min, max]
-__host__ __device__ inline bool isInside(float val, const float min, const float max)
-{
-  return (val > min) && (val < max);
-}
-
-// get lowest index where range[index] > value, within [start,end] of range
-__host__ __device__ inline int getLowerBound(float range[], float value, int start, int end)
-{
-  int i = start;
-  for (; i < end; i++) {
-    if (range[i] > value) break;
-  }
-  return i;
-}
-
-// match stereo hits to x hits
-__host__ __device__ bool matchStereoHit(
-  const int itUV1,
-  const int uv_zone_offset_end,
-  const SciFi::Hits& scifi_hits,
-  const float xMinUV,
-  const float xMaxUV);
-
-__host__ __device__ bool matchStereoHitWithTriangle(
-  const int itUV2,
-  const int triangle_zone_offset_end,
-  const float yInZone,
-  const SciFi::Hits& scifi_hits,
-  const float xMinUV,
-  const float xMaxUV,
-  const int side);
-
-__host__ __device__ void removeOutlier(
-  const SciFi::Hits& scifi_hits,
-  PlaneCounter& planeCounter,
-  int* coordToFit,
-  int& n_coordToFit,
-  const int worst);
-
-__host__ __device__ void findStereoHitsWithinXTol(
-  const int itBegin,
-  const int itEnd,
-  const SciFi::Hits& scifi_hits,
-  const float yZone,
-  const float xPred,
-  const float dxTol,
-  const bool triangleSearch,
-  const float dxDySign,
-  int& n_stereoHits,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits]);
-
-__host__ __device__ void findStereoHitClusterByDx(
-  PlaneCounter& planeCounter,
-  int& endRange,
-  const SciFi::Tracking::HitSearchCuts& pars,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  const int n_stereoHits,
-  const SciFi::Hits& scifi_hits,
-  float& sumCoord,
-  int& first_hit);
-
-__host__ __device__ void cleanStereoHitCluster(
-  int& beginRange,
-  int& endRange,
-  const int n_stereoHits,
-  const int stereoHits[SciFi::Tracking::max_stereo_hits],
-  const float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  float& sumCoord,
-  PlaneCounter& planeCounter,
-  const SciFi::Hits& scifi_hits);
-
-__host__ __device__ int findBestStereoHitOnEmptyLayer(
-  const int itBegin,
-  const int itEnd,
-  const SciFi::Hits& scifi_hits,
-  const float yZone,
-  const float xPred,
-  const float dxTol,
-  const bool triangleSearch);
diff --git a/cuda/SciFi/PrForward/include/LinearFitting.cuh b/cuda/SciFi/PrForward/include/LinearFitting.cuh
deleted file mode 100644
index 486f7b50905..00000000000
--- a/cuda/SciFi/PrForward/include/LinearFitting.cuh
+++ /dev/null
@@ -1,77 +0,0 @@
-#pragma once
-
-#include "SciFiDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "HitUtils.cuh"
-#include "SciFiEventModel.cuh"
-
-#include <cmath>
-
-namespace SciFi {
-  namespace Tracking {
-
-    struct LineFitterPars {
-      float m_z0 = 0.;
-      float m_c0 = 0.;
-      float m_tc = 0.;
-
-      float m_s0 = 0.;
-      float m_sz = 0.;
-      float m_sz2 = 0.;
-      float m_sc = 0.;
-      float m_scz = 0.;
-    };
-  } // namespace Tracking
-} // namespace SciFi
-
-__host__ __device__ void incrementLineFitParameters(
-  SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int it);
-
-__host__ __device__ void fitHitsFromSingleHitPlanes(
-  const int it1,
-  const int it2,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  const PlaneCounter planeCounter,
-  SciFi::Tracking::LineFitterPars& lineFitParameters,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits],
-  int nOtherHits[SciFi::Constants::n_layers]);
-
-__host__ __device__ void addAndFitHitsFromMultipleHitPlanes(
-  const int nOtherHits[SciFi::Constants::n_layers],
-  SciFi::Tracking::LineFitterPars& lineFitParameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits]);
-
-__host__ __device__ float getLineFitDistance(
-  SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int it);
-
-__host__ __device__ float getLineFitChi2(
-  SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int it);
-
-__host__ __device__ void solveLineFit(SciFi::Tracking::LineFitterPars& parameters);
-
-__host__ __device__ void fastLinearFit(
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  PlaneCounter planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
diff --git a/cuda/SciFi/PrForward/include/ParabolaFitting.cuh b/cuda/SciFi/PrForward/include/ParabolaFitting.cuh
deleted file mode 100644
index 0cfb8d66da7..00000000000
--- a/cuda/SciFi/PrForward/include/ParabolaFitting.cuh
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-
-#include "SciFiDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "SciFiEventModel.cuh"
-
-__host__ __device__ int fitParabola(
-  int* coordToFit,
-  const int n_coordToFit,
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  const bool xFit);
diff --git a/cuda/SciFi/PrForward/include/PrForward.cuh b/cuda/SciFi/PrForward/include/PrForward.cuh
deleted file mode 100644
index 376a16fe8fe..00000000000
--- a/cuda/SciFi/PrForward/include/PrForward.cuh
+++ /dev/null
@@ -1,59 +0,0 @@
-#pragma once
-
-#include "PrForwardTools.cuh"
-#include "Handler.cuh"
-// #include "ArgumentsCommon.cuh"
-#include "ArgumentsVelo.cuh"
-#include "ArgumentsUT.cuh"
-#include "ArgumentsSciFi.cuh"
-
-/** @class PrForward PrForward.h
- *
- *  - InputTracksName: Input location for VeloUT tracks
- *  - OutputTracksName: Output location for Forward tracks
- *  Based on code written by
- *  2012-03-20 : Olivier Callot
- *  2013-03-15 : Thomas Nikodem
- *  2015-02-13 : Sevda Esen [additional search in the triangles by Marian Stahl]
- *  2016-03-09 : Thomas Nikodem [complete restructuring]
- *  2018-08    : Vava Gligorov [extract code from Rec, make compile within GPU framework
- *  2018-09    : Dorothea vom Bruch [convert to CUDA, runs on GPU]
- */
-
-__global__ void scifi_pr_forward(
-  uint32_t* dev_scifi_hits,
-  const uint32_t* dev_scifi_hit_count,
-  const int* dev_atomics_velo,
-  const uint* dev_velo_track_hit_number,
-  const char* dev_velo_states,
-  const int* dev_atomics_ut,
-  const char* dev_ut_track_hits,
-  const uint* dev_ut_track_hit_number,
-  const float* dev_ut_qop,
-  const uint* dev_ut_track_velo_indices,
-  SciFi::TrackHits* dev_scifi_tracks,
-  int* dev_atomics_scifi,
-  const SciFi::Tracking::TMVA* dev_tmva1,
-  const SciFi::Tracking::TMVA* dev_tmva2,
-  const SciFi::Tracking::Arrays* dev_constArrays,
-  const float* dev_magnet_polarity,
-  const char* dev_scifi_geometry,
-  const float* dev_inv_clus_res);
-
-ALGORITHM(
-  scifi_pr_forward,
-  scifi_pr_forward_t,
-  ARGUMENTS(
-    dev_scifi_hits,
-    dev_scifi_hit_count,
-    dev_atomics_velo,
-    dev_velo_track_hit_number,
-    dev_velo_states,
-    dev_atomics_ut,
-    dev_ut_track_hits,
-    dev_ut_track_hit_number,
-    dev_ut_qop,
-    dev_ut_track_velo_indices,
-    dev_scifi_tracks,
-    dev_scifi_selected_track_indices,
-    dev_atomics_scifi))
diff --git a/cuda/SciFi/PrForward/include/PrForwardConstants.cuh b/cuda/SciFi/PrForward/include/PrForwardConstants.cuh
deleted file mode 100644
index c909c530190..00000000000
--- a/cuda/SciFi/PrForward/include/PrForwardConstants.cuh
+++ /dev/null
@@ -1,236 +0,0 @@
-#pragma once
-
-/**
-   Contains constants needed for the forward tracking
-   - cut values
-   - geometry descriptions
-   - parameterizations
-
-   12/09/2018: cut values are those defined in:
-   https://gitlab.cern.ch/lhcb/Rec/blob/master/Tf/TrackSys/python/TrackSys/Configuration.py
-   https://gitlab.cern.ch/lhcb/Rec/blob/master/Tf/TrackSys/python/TrackSys/RecoUpgradeTracking.py
-
-   for the RecoFastTrackingStage, using the default values of ConfigHLT1 (master branch of Rec)
-
- */
-
-#include "VeloEventModel.cuh"
-#include "SystemOfUnits.h"
-#include "SciFiDefinitions.cuh"
-#include <cassert>
-
-namespace SciFi {
-
-  namespace Tracking {
-
-    constexpr int max_candidate_tracks = 5;   // max # of candidate tracks from x hits only
-    constexpr int max_tracks_second_loop = 5; // same as above, but for second loop
-    constexpr int max_selected_tracks = max_candidate_tracks + max_tracks_second_loop;
-    constexpr int max_x_hits = 500;     // max # of hits in all x layers
-    constexpr int max_other_hits = 5;   // max # of hits from x planes with more than 1 hit
-    constexpr int max_stereo_hits = 25; // max # of hits in all stereo layers
-    constexpr int max_coordToFit = 15;  // only for x layers
-    constexpr int max_scifi_hits = 20;  // for x and u/v layers
-
-    constexpr int nTrackParams = 9;
-
-    constexpr int TMVA_Nvars = 7;
-    constexpr int TMVA_Nlayers = 5;
-
-    // Formerly PrParameters
-    struct HitSearchCuts {
-      __host__ __device__ HitSearchCuts(
-        unsigned int minXHits_,
-        float maxXWindow_,
-        float maxXWindowSlope_,
-        float maxXGap_,
-        unsigned int minStereoHits_) :
-        minXHits {minXHits_},
-        maxXWindow {maxXWindow_}, maxXWindowSlope {maxXWindowSlope_}, maxXGap {maxXGap_}, minStereoHits {minStereoHits_}
-      {}
-      const unsigned int minXHits;
-      const float maxXWindow;
-      const float maxXWindowSlope;
-      const float maxXGap;
-      unsigned int minStereoHits;
-    };
-
-    // dump a bunch of options here
-    constexpr float deltaQuality = 0.1; // Difference in quality btw two tracks which share hits when clone killing
-    constexpr float cloneFraction =
-      0.4; // The fraction of shared SciFi hits btw two tracks to trigger the clone killing
-
-    constexpr float yTolUVSearch = 11. * Gaudi::Units::mm;
-    constexpr float tolY = 5. * Gaudi::Units::mm;
-    constexpr float tolYSlope = 0.002 * Gaudi::Units::mm;
-    constexpr float maxChi2LinearFit = 100.;
-    constexpr float maxChi2XProjection = 15.;
-    constexpr float maxChi2PerDoF = 7.;
-
-    constexpr float tolYMag = 10. * Gaudi::Units::mm;
-    constexpr float tolYMagSlope = 0.015;
-    constexpr float minYGap = 0.4 * Gaudi::Units::mm;
-
-    constexpr unsigned int minTotalHits = 10;
-    constexpr float maxChi2StereoLinear = 60.;
-    constexpr float maxChi2Stereo = 4.5;
-
-    // first loop Hough Cluster search
-    constexpr unsigned int minXHits = 5;
-    constexpr float maxXWindow = 1. * Gaudi::Units::mm; // 1.2 * Gaudi::Units::mm  ;
-    constexpr float maxXWindowSlope = 0.002 * Gaudi::Units::mm;
-    constexpr float maxXGap = 1. * Gaudi::Units::mm; // 1.2 * Gaudi::Units::mm  ;
-    constexpr unsigned int minSingleHits = 2;
-
-    // second loop Hough Cluster search
-    constexpr bool secondLoop = true;
-    constexpr unsigned int minXHits_2nd = 4;
-    constexpr float maxXWindow_2nd = 1.5 * Gaudi::Units::mm;
-    constexpr float maxXWindowSlope_2nd = 0.002 * Gaudi::Units::mm;
-    constexpr float maxXGap_2nd = 0.5 * Gaudi::Units::mm;
-
-    // collectX search
-    constexpr float minPt = 400 * Gaudi::Units::MeV; // 500 * Gaudi::Units::MeV ;
-    // stereo hit matching
-    constexpr float tolYCollectX = 3.5 * Gaudi::Units::mm;        // 4.1* Gaudi::Units::mm ;
-    constexpr float tolYSlopeCollectX = 0.001 * Gaudi::Units::mm; // 0.0018 * Gaudi::Units::mm ;
-    constexpr float tolYTriangleSearch = 20.f;
-    // veloUT momentum estimate
-    constexpr bool useMomentumEstimate = true;
-    constexpr bool useWrongSignWindow = true;
-    constexpr float wrongSignPT = 2000. * Gaudi::Units::MeV;
-    // Track Quality NN
-    constexpr float maxQuality = 0.9;
-    constexpr float deltaQuality_NN = 0.1;
-
-    // parameterizations
-    constexpr float byParams = -0.667996;
-    constexpr float cyParams = -3.68424e-05;
-
-    // z Reference plane
-    constexpr float zReference = 8520. * Gaudi::Units::mm; // in T2
-    constexpr float zRefInv = 1.f / zReference;
-
-    // TODO: CHECK THESE VALUES USING FRAMEWORK
-    constexpr float xLim_Max = 3300.;
-    constexpr float yLim_Max = 2500.;
-    constexpr float xLim_Min = -3300.;
-    constexpr float yLim_Min = -25.;
-
-    // TO BE READ FROM XML EVENTUALLY
-    //constexpr float magscalefactor = -1;
-    constexpr int zoneoffsetpar = 6;
-
-    struct Arrays {
-      // Returns whether the current layer is an X plane
-      const bool is_x_plane [12] {1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1};
-
-      // the Magnet Parametrization
-      // parameterized in offset [0], (slope difference due to kick)^2 [1],
-      // tx^2 [2], ty^2 [3]
-      const float zMagnetParams[4] = {5212.38, 406.609, -1102.35, -498.039};
-
-      // more Parametrizations
-      const float xParams[2] = {18.6195, -5.55793};
-
-      // momentum Parametrization
-      const float momentumParams[6] = {1.21014, 0.637339, -0.200292, 0.632298, 3.23793, -27.0259};
-
-      // covariance values
-      const float covarianceValues[5] = {4.0, 400.0, 4.e-6, 1.e-4, 0.1};
-
-      // definition of zones
-      // access upper with offset of 6
-      const int zoneoffsetpar = 6;
-      const int xZones[12] = {0, 6, 8, 14, 16, 22, 1, 7, 9, 15, 17, 23};
-      const int uvZones[12] = {2, 4, 10, 12, 18, 20, 3, 5, 11, 13, 19, 21};
-
-      // ASSORTED GEOMETRY VALUES, eventually read this from some xml
-      const float xZone_zPos[6] = {7826., 8036., 8508., 8718., 9193., 9403.};
-      const float uvZone_zPos[12] =
-        {7896., 7966., 8578., 8648., 9263., 9333., 7896., 7966., 8578., 8648., 9263., 9333.};
-      const float uvZone_dxdy[12] = {0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892,
-                                     0.0874892,
-                                     -0.0874892};
-      const float Zone_dzdy[24] = {0.0036010};
-
-      // this is used by looking_forward_sbt maybe this is not the right place to put it
-      const float uv_dx[6] = {1.6739478541449213,
-                              1.6738495069872612,
-                              1.935683825160498,
-                              1.9529279746403518,
-                              2.246931985749485,
-                              2.2797556995480273};
-    };
-
-    // parameters for extrapolating from EndVelo to ZReference
-    constexpr float xExtParams[6] = {4.08934e+06f, 6.31187e+08f, 131.999f, -1433.64f, -325.055f, 3173.52f};
-    // Params for momentum dependent search window estimate
-    // upper window to include 98% of hits(can't be too greedy
-    // here or the window size would explode)
-    constexpr float pUp[3] = {1.46244e+02f, 5.15348e+02f, -4.17237e-05f};
-    // lower window, the same to include 98% of hits
-    constexpr float pLo[3] = {5.00000e+01f, 9.61409e+02f, -1.31317e-04f};
-
-    // Track object used for finding tracks, not the final container for storing the tracks
-    struct Track {
-      int hit_indices[max_scifi_hits];
-      float qop;
-      int hitsNum = 0;
-      float quality;
-      float chi2;
-      // [0]: xRef
-      // [1]: (xRef-xMag)/(zRef-zMag)
-      // [2]: xParams[0] * dSlope
-      // [3]: xParams[1] * dSlope
-      // [4]: y param
-      // [5]: y param
-      // [6]: y param
-      // [7]: chi2
-      // [8]: nDoF
-      float trackParams[SciFi::Tracking::nTrackParams];
-
-      __host__ __device__ void addHit(int hit)
-      {
-        assert(hitsNum < max_scifi_hits - 1);
-        hit_indices[hitsNum++] = hit;
-      }
-
-      __host__ __device__ void set_qop(float _qop) { qop = _qop; }
-
-      __host__ __device__ float x(const float z) const
-      {
-        float dz = z - zReference;
-        return trackParams[0] + dz * (trackParams[1] + dz * (trackParams[2] + dz * trackParams[3]));
-      }
-
-      __host__ __device__ float xSlope(const float z) const
-      {
-        float dz = z - zReference;
-        return trackParams[1] + dz * (2.f * trackParams[2] + 3.f * dz * trackParams[3]);
-      }
-
-      __host__ __device__ float y(const float z) const
-      {
-        float dz = z - zReference;
-        return trackParams[4] + dz * (trackParams[5] + dz * trackParams[6]);
-      }
-
-      __host__ __device__ float ySlope(const float z) const
-      {
-        float dz = z - zReference;
-        return trackParams[5] + dz * 2.f * trackParams[6];
-      }
-    };
-
-  } // namespace Tracking
-} // namespace SciFi
diff --git a/cuda/SciFi/PrForward/include/PrForwardTools.cuh b/cuda/SciFi/PrForward/include/PrForwardTools.cuh
deleted file mode 100644
index a4c924a45bf..00000000000
--- a/cuda/SciFi/PrForward/include/PrForwardTools.cuh
+++ /dev/null
@@ -1,88 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-
-#include <cassert>
-#include "Logger.h"
-#include "SystemOfUnits.h"
-#include "TMVA_Forward_1.cuh"
-#include "TMVA_Forward_2.cuh"
-#include "SciFiDefinitions.cuh"
-#include "VeloDefinitions.cuh"
-#include "UTDefinitions.cuh"
-#include "PrForwardConstants.cuh"
-#include "TrackUtils.cuh"
-#include "LinearFitting.cuh"
-#include "HitUtils.cuh"
-#include "FindXHits.cuh"
-#include "FindStereoHits.cuh"
-#include "VeloEventModel.cuh"
-#include "VeloConsolidated.cuh"
-#include "UTConsolidated.cuh"
-#include "SciFiEventModel.cuh"
-#include "States.cuh"
-
-__host__ __device__ void find_forward_tracks(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const float qop_ut,
-  const int i_veloUT_track,
-  SciFi::TrackHits* outputTracks,
-  uint* n_forward_tracks,
-  const int ut_event_number_of_tracks,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state);
-
-__host__ __device__ void selectFullCandidates(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track* candidate_tracks,
-  int& n_candidate_tracks,
-  SciFi::Tracking::Track* selected_tracks,
-  int& n_selected_tracks,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  MiniState velo_state,
-  const float VeloUT_qOverP,
-  SciFi::Tracking::HitSearchCuts& pars_cur,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const bool secondLoop);
-
-__host__ __device__ SciFi::TrackHits makeTrack(SciFi::Tracking::Track track);
-
-template<class T>
-__host__ __device__ void sort_tracks(SciFi::Tracking::Track* tracks, const int n, const T& sort_function)
-{
-  // find permutations based on sort_function
-  uint permutations[SciFi::Tracking::max_selected_tracks];
-  for (int i = 0; i < n; ++i) {
-    uint position = 0;
-    for (int j = 0; j < n; ++j) {
-      const int sort_result = sort_function(tracks[i], tracks[j]);
-      position += sort_result > 0 || (sort_result == 0 && i > j);
-    }
-    permutations[position] = i;
-  }
-
-  // apply permutations, store tracks in temporary container
-  SciFi::Tracking::Track tracks_tmp[SciFi::Tracking::max_selected_tracks];
-  for (int i = 0; i < n; ++i) {
-    const int index = permutations[i];
-    tracks_tmp[i] = tracks[index];
-  }
-
-  // copy tracks back to original container
-  for (int i = 0; i < n; ++i) {
-    tracks[i] = tracks_tmp[i];
-  }
-}
diff --git a/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh b/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
deleted file mode 100644
index b1e549f5948..00000000000
--- a/cuda/SciFi/PrForward/include/ReferencePlaneProjection.cuh
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include <cmath>
-#include <array>
-#include <vector>
-#include <algorithm>
-#include <fstream>
-
-#include "SciFiDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "SciFiEventModel.cuh"
-
-/**
-   Project x hits onto reference plane
-*/
-
-__host__ __device__ void xAtRef_SamePlaneHits(
-  const SciFi::Hits& scifi_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  const float xParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  MiniState velo_state,
-  const float zMag,
-  int itH,
-  int itEnd);
diff --git a/cuda/SciFi/PrForward/include/TrackUtils.cuh b/cuda/SciFi/PrForward/include/TrackUtils.cuh
deleted file mode 100644
index fb3577f5a3c..00000000000
--- a/cuda/SciFi/PrForward/include/TrackUtils.cuh
+++ /dev/null
@@ -1,74 +0,0 @@
-#pragma once
-
-#include <cmath>
-
-#include "SciFiDefinitions.cuh"
-#include "PrForwardConstants.cuh"
-#include "HitUtils.cuh"
-#include "ParabolaFitting.cuh"
-#include "SciFiEventModel.cuh"
-
-/**
-   Helper functions related to track properties
- */
-
-// extrapolate x position from given state to z
-__host__ __device__ float xFromVelo(const float z, const MiniState& velo_state);
-
-// extrapolate y position from given state to z
-__host__ __device__ float yFromVelo(const float z, const MiniState& velo_state);
-
-__host__ __device__ float evalCubicParameterization(const float params[4], float z);
-
-__host__ __device__ float evalParameterizationX(const float* params, float z);
-
-__host__ __device__ float evalParameterizationY(const float* params, float z);
-
-__host__ __device__ bool lowerByQuality(SciFi::Tracking::Track t1, SciFi::Tracking::Track t2);
-
-__host__ __device__ inline float straightLinePropagationFromReferencePlane(const float params[4], float z)
-{
-  float dz = z - SciFi::Tracking::zReference;
-  return params[0] + params[1] * dz;
-} 
-
-__host__ __device__ inline float straightLinePropagationFromReferencePlane(const float x0, const float tx, float z)
-{
-  float dz = z - SciFi::Tracking::zReference;
-  return x0 + tx * dz;
-} 
-
-__host__ __device__ void getTrackParameters(
-  float xAtRef,
-  const MiniState& velo_state,
-  const SciFi::Tracking::Arrays* constArrays,
-  float trackParams[SciFi::Tracking::nTrackParams]);
-
-__host__ __device__ float calcqOverP(float bx, const SciFi::Tracking::Arrays* constArrays, const MiniState& velo_state, const float magnet_polarity);
-
-__host__ __device__ float zMagnet(const MiniState& velo_state, const SciFi::Tracking::Arrays* constArrays);
-
-__host__ __device__ float calcDxRef(float pt, const MiniState& velo_state);
-
-__host__ __device__ float
-trackToHitDistance(const float trackParameters[SciFi::Tracking::nTrackParams], const SciFi::Hits& scifi_hits, int hit);
-
-__host__ __device__ float chi2XHit(const float parsX[4], const SciFi::Hits& scifi_hits, const int hit);
-
-__host__ __device__ bool quadraticFitX(
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  PlaneCounter& planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
-
-__host__ __device__ bool fitYProjection(
-  const SciFi::Hits& scifi_hits,
-  SciFi::Tracking::Track& track,
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  PlaneCounter& planeCounter,
-  const MiniState& velo_state,
-  const SciFi::Tracking::Arrays* constArrays,
-  SciFi::Tracking::HitSearchCuts& pars_cur);
diff --git a/cuda/SciFi/PrForward/src/FindStereoHits.cu b/cuda/SciFi/PrForward/src/FindStereoHits.cu
deleted file mode 100644
index ce5a89f300e..00000000000
--- a/cuda/SciFi/PrForward/src/FindStereoHits.cu
+++ /dev/null
@@ -1,247 +0,0 @@
-#include "FindStereoHits.cuh"
-
-//=========================================================================
-//  Collect all hits in the stereo planes compatible with the track
-//=========================================================================
-__host__ __device__ void collectStereoHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::Arrays* constArrays,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits)
-{
-  for (int zone = 0; zone < SciFi::Constants::n_layers; ++zone) {
-    // get yZone and xPred: x and y values at z of layer based on candidate track parameters
-    const float parsX[4] = {track.trackParams[0], track.trackParams[1], track.trackParams[2], track.trackParams[3]};
-    const float parsY[4] = {track.trackParams[4], track.trackParams[5], track.trackParams[6], 0.f};
-    float zZone = constArrays->uvZone_zPos[zone];
-    const float yZone = evalCubicParameterization(parsY, zZone);
-    assert(constArrays->uvZones[zone] < SciFi::Constants::n_zones);
-    zZone += constArrays->Zone_dzdy[constArrays->uvZones[zone]] * yZone; // Correct for dzDy
-    const float xPred = evalCubicParameterization(parsX, zZone);
-
-    const bool triangleSearch = fabsf(yZone) < SciFi::Tracking::tolYTriangleSearch;
-    // even zone number: if ( yZone > 0 ) continue;
-    // odd zone number: if ( -yZone > 0 ) continue;
-    // -> check for upper / lower half
-    // -> only continue if yZone is in the correct half
-    if (!triangleSearch && (2.f * float(((constArrays->uvZones[zone]) % 2) == 0) - 1.f) * yZone > 0.f) continue;
-
-    const float dxDySign = constArrays->uvZone_dxdy[zone] < 0.f ? -1.f : 1.f;
-    const float seed_x_at_zZone = xFromVelo(zZone, velo_state);
-    const float dxTol =
-      SciFi::Tracking::tolY + SciFi::Tracking::tolYSlope * (fabsf(xPred - seed_x_at_zZone) + fabsf(yZone));
-
-    // find stereo hits whose x coordinate is within xTol of the prediction
-    // from the candidate track
-    // This takes the y value (max, min) into account
-    const float lower_bound_at = -dxTol - yZone * constArrays->uvZone_dxdy[zone] + xPred;
-    int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[zone]);
-    int uv_zone_offset_end = uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[zone]);
-
-    int itBegin = getLowerBound(scifi_hits.x0, lower_bound_at, uv_zone_offset_begin, uv_zone_offset_end);
-    int itEnd = uv_zone_offset_end;
-
-    findStereoHitsWithinXTol(
-      itBegin,
-      itEnd,
-      scifi_hits,
-      yZone,
-      xPred,
-      dxTol,
-      triangleSearch,
-      dxDySign,
-      n_stereoHits,
-      stereoCoords,
-      stereoHits);
-
-    if (n_stereoHits >= SciFi::Tracking::max_stereo_hits) break;
-  }
-
-  // Sort hits by coord
-  // not using thrust::sort due to temporary_buffer::allocate:: get_temporary_buffer failed" error
-  // thrust::sort_by_key(thrust::seq, stereoCoords, stereoCoords + n_stereoHits, stereoHits);
-  sortHitsByKey<SciFi::Tracking::max_stereo_hits>(stereoCoords, n_stereoHits, stereoHits);
-}
-
-//=========================================================================
-//  Fit the stereo hits
-//=========================================================================
-__host__ __device__ bool selectStereoHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  const SciFi::Tracking::Arrays* constArrays,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-  int bestStereoHits[SciFi::Tracking::max_stereo_hits];
-  int n_bestStereoHits = 0;
-  float originalYParams[3] = {track.trackParams[4], track.trackParams[5], track.trackParams[6]};
-  float bestYParams[3];
-  float bestMeanDy = 1e9f;
-
-  if (pars.minStereoHits > n_stereoHits) return false;
-  int endLoop = n_stereoHits - pars.minStereoHits;
-
-  PlaneCounter planeCounter;
-  for (int beginRange = 0; beginRange < endLoop; ++beginRange) {
-    planeCounter.clear();
-    int endRange = beginRange;
-
-    float sumCoord = 0.;
-    // bad hack to reproduce itereator behavior from before: *(-1) = 0
-    int first_hit;
-    if (endRange == 0)
-      first_hit = 0;
-    else
-      first_hit = endRange - 1;
-
-    findStereoHitClusterByDx(
-      planeCounter, endRange, pars, stereoCoords, stereoHits, n_stereoHits, scifi_hits, sumCoord, first_hit);
-
-    cleanStereoHitCluster(
-      beginRange, endRange, n_stereoHits, stereoHits, stereoCoords, sumCoord, planeCounter, scifi_hits);
-
-    // Now we have a candidate, lets fit him
-    // track = original; //only yparams are changed
-    track.trackParams[4] = originalYParams[0];
-    track.trackParams[5] = originalYParams[1];
-    track.trackParams[6] = originalYParams[2];
-
-    int trackStereoHits[SciFi::Tracking::max_stereo_hits];
-    int n_trackStereoHits = 0;
-    assert(endRange < n_stereoHits);
-    for (int range = beginRange; range < endRange; ++range) {
-      trackStereoHits[n_trackStereoHits++] = stereoHits[range];
-    }
-
-    // fit Y Projection of track using stereo hits
-    if (!fitYProjection(
-          scifi_hits, track, trackStereoHits, n_trackStereoHits, planeCounter, velo_state, constArrays, pars))
-      continue;
-
-    if (!addHitsOnEmptyStereoLayers(
-          scifi_hits,
-          scifi_hit_count,
-          track,
-          trackStereoHits,
-          n_trackStereoHits,
-          constArrays,
-          planeCounter,
-          velo_state,
-          pars))
-      continue;
-
-    if (n_trackStereoHits < n_bestStereoHits) continue; // number of hits most important selection criteria!
-
-    //== Calculate  dy chi2 /ndf
-    float meanDy = 0.;
-    assert(n_trackStereoHits < n_stereoHits);
-    for (int i_hit = 0; i_hit < n_trackStereoHits; ++i_hit) {
-      const int hit = trackStereoHits[i_hit];
-      const float d = trackToHitDistance(track.trackParams, scifi_hits, hit) / scifi_hits.dxdy(hit);
-      meanDy += d * d;
-    }
-    meanDy /= float(n_trackStereoHits - 1);
-
-    if (n_trackStereoHits > n_bestStereoHits || meanDy < bestMeanDy) {
-      // if same number of hits take smaller chi2
-      bestYParams[0] = track.trackParams[4];
-      bestYParams[1] = track.trackParams[5];
-      bestYParams[2] = track.trackParams[6];
-      bestMeanDy = meanDy;
-
-      n_bestStereoHits = 0;
-      for (int i_hit = 0; i_hit < n_trackStereoHits; ++i_hit) {
-        assert(n_bestStereoHits < SciFi::Tracking::max_stereo_hits);
-        bestStereoHits[n_bestStereoHits++] = trackStereoHits[i_hit];
-      }
-    }
-
-  } // beginRange loop (<endLoop)
-
-  if (n_bestStereoHits > 0) {
-    track.trackParams[4] = bestYParams[0];
-    track.trackParams[5] = bestYParams[1];
-    track.trackParams[6] = bestYParams[2];
-    assert(n_bestStereoHits < n_stereoHits);
-
-    for (int i_hit = 0; i_hit < n_bestStereoHits; ++i_hit) {
-      int hit = bestStereoHits[i_hit];
-      if (track.hitsNum >= SciFi::Tracking::max_scifi_hits) break;
-      assert(track.hitsNum < SciFi::Tracking::max_scifi_hits);
-      track.addHit(hit);
-    }
-    return true;
-  }
-  return false;
-}
-
-//=========================================================================
-//  Add hits on empty stereo layers, and refit if something was added
-//=========================================================================
-__host__ __device__ bool addHitsOnEmptyStereoLayers(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track& track,
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  const SciFi::Tracking::Arrays* constArrays,
-  PlaneCounter& planeCounter,
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-  // at this point pc is counting only stereo HITS!
-  if (planeCounter.nbDifferent > 5) return true;
-
-  bool added = false;
-  for (unsigned int zone = 0; zone < SciFi::Constants::n_layers; zone += 1) {
-    assert(constArrays->uvZones[zone] < SciFi::Constants::n_zones);
-    if (planeCounter.nbInPlane(constArrays->uvZones[zone] / 2) != 0) continue; // there is already one hit
-
-    float zZone = constArrays->uvZone_zPos[zone];
-
-    const float parsX[4] = {track.trackParams[0], track.trackParams[1], track.trackParams[2], track.trackParams[3]};
-    const float parsY[4] = {track.trackParams[4], track.trackParams[5], track.trackParams[6], 0.};
-
-    float yZone = evalCubicParameterization(parsY, zZone);
-    zZone = constArrays->Zone_dzdy[constArrays->uvZones[zone]] * yZone; // Correct for dzDy
-    yZone = evalCubicParameterization(parsY, zZone);
-    const float xPred = evalCubicParameterization(parsX, zZone);
-
-    const bool triangleSearch = fabsf(yZone) < SciFi::Tracking::tolYTriangleSearch;
-    // change sign of yZone depending on whether we are in the upper or lower half
-    if (!triangleSearch && (2.f * float((((constArrays->uvZones[zone]) % 2) == 0)) - 1.f) * yZone > 0.f) continue;
-
-    // only version without triangle search!
-    const float dxTol =
-      SciFi::Tracking::tolY + SciFi::Tracking::tolYSlope *
-                                (fabsf(xPred - velo_state.x + (zZone - velo_state.z) * velo_state.tx) + fabsf(yZone));
-    // -- Use a binary search to find the lower bound of the range of x values
-    // -- This takes the y value into account
-    const float lower_bound_at = -dxTol - yZone * constArrays->uvZone_dxdy[zone] + xPred;
-    int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[zone]);
-    int uv_zone_offset_end = uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[zone]);
-    int itBegin = getLowerBound(scifi_hits.x0, lower_bound_at, uv_zone_offset_begin, uv_zone_offset_end);
-    int itEnd = uv_zone_offset_end;
-
-    int best = findBestStereoHitOnEmptyLayer(itBegin, itEnd, scifi_hits, yZone, xPred, dxTol, triangleSearch);
-
-    if (-1 != best) {
-      assert(n_stereoHits < SciFi::Tracking::max_stereo_hits);
-      stereoHits[n_stereoHits++] = best;
-      planeCounter.addHit(scifi_hits.planeCode(best) / 2);
-      added = true;
-    }
-  }
-  if (!added) return true;
-  return fitYProjection(scifi_hits, track, stereoHits, n_stereoHits, planeCounter, velo_state, constArrays, pars);
-}
diff --git a/cuda/SciFi/PrForward/src/FindXHits.cu b/cuda/SciFi/PrForward/src/FindXHits.cu
deleted file mode 100644
index daa9b38016a..00000000000
--- a/cuda/SciFi/PrForward/src/FindXHits.cu
+++ /dev/null
@@ -1,830 +0,0 @@
-#include "FindXHits.cuh"
-#include "BinarySearch.cuh"
-
-__host__ void collectAllXHits_proto_p(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const MiniState& UT_state,
-  const float qOverP,
-  int side,
-  std::array<int, 2 * 6>& windows_x,
-  std::array<int, 2 * 6>& windows_uv,
-  std::array<float, 4 * 6>& parameters_uv,
-  const SciFiWindowsParams& window_params,
-  const std::array<int, 12> true_scifi_indices_per_layer)
-{
-  const float tx2 = velo_state.tx*velo_state.tx;
-  const float ty2 = velo_state.ty*velo_state.ty;
-  const float slope2 = tx2 + ty2;
-  const float pt = sqrtf(slope2 / (1.f + slope2) ) / fabsf(qOverP);
-  const float p = 1.f / std::abs(qOverP);
-
-  /* OPTIMIZE: possibly use these variables for wrong sign treatment */
-  // const float q = qOverP > 0.f ? 1.f : -1.f;
-  // const bool wSignTreatment = pt > SciFi::Tracking::wrongSignPT;
-  // float zMag = zMagnet(velo_state, constArrays);
-  // const float qop_WS = sqrtf(slope2 / (1.f + slope2) ) / pt;
-  // float dxRefWS = 0.f;
-  // if ( wSignTreatment ) {
-  //   dxRefWS = 0.9f * calcDxRef(SciFi::Tracking::wrongSignPT, velo_state);
-  // }
-  // const float dir = q * SciFi::Tracking::magscalefactor * (-1.f); // needed for wrong sign treatment
-  // const float xTolWS = dx_calc(velo_state, qop_WS, window_params);
-
-  //const float q = qOverP > 0.f ? 1.f : -1.f;
-  //const float dir = q * magnet_polarity * (-1.f);
-
-  //const bool wSignTreatment = pt > SciFi::Tracking::wrongSignPT;
-  float zMag = zMagnet(velo_state, constArrays);
-  const float qop_WS = sqrtf(slope2 / (1.f + slope2) ) / pt;
-  // float dxRefWS = 0.f;
-  // if ( wSignTreatment ) {
-  //   dxRefWS = 0.9f * calcDxRef(SciFi::Tracking::wrongSignPT, velo_state);
-  // }
-  const float xAtRef = xFromVelo(SciFi::Tracking::zReference, UT_state);
-  float xParams_seed[4] {xAtRef, UT_state.tx, 0, 0};
-
-  // use parametrization to propagate from UT to SciFi
-  const auto state_zRef = propagate_state_from_velo(UT_state, qOverP, 5);  // zRef is between layers 4 and 5
-  const float xTol = dx_calc(velo_state, qOverP, window_params);
-  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
-
-  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
-    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
-    assert(iZone - iZoneStartingPoint < 12);
-
-    const auto izone_rel = iZone - iZoneStartingPoint;
-    const float zZone = constArrays->xZone_zPos[izone_rel];
-
-    //const int layer = constArrays->xZones[iZone] / 2;
-    const float dz_x = (zZone - SciFi::Tracking::zReference);
-    const float xInZone = scifi_propagation(state_zRef.x, UT_state.tx, qOverP, dz_x);
-    const float yInZone = yFromVelo(zZone, velo_state);
-
-    const float xInZoneStraight = evalCubicParameterization(xParams_seed, zZone);
-
-    if (side > 0) {
-      if (
-        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-        !isInside(yInZone, SciFi::Tracking::yLim_Min, SciFi::Tracking::yLim_Max))
-        continue;
-    }
-    else {
-      if (
-        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-        !isInside(yInZone, side * SciFi::Tracking::yLim_Max, side * SciFi::Tracking::yLim_Min))
-        continue;
-    }
-
-    float xMin = xInZone - xTol;
-    float xMax = xInZone + xTol;
-
-    /* OPTIMIZE: how do we take care of wrong sign tracks with momentum windows? */
-    //float xTolWS = 0.0;
-    // if (wSignTreatment) {
-    //   // xTolWS = (zZone < SciFi::Tracking::zReference) ?
-    //   //   dxRefWS * zZone / SciFi::Tracking::zReference :
-    //   //   dxRefWS * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-    //   // if (dir > 0) {
-    //   //   xMin = xInZone - xTolWS;
-    //   // }
-    //   // else {
-    //   //   xMax = xInZone + xTolWS;
-    //   // }
-
-    //   debug_cout << "\t before WS treatment: xMin = " << xMin << ", xMax = " << xMax << ", WS = " << int(wSignTreatment) << ", pt = " << pt << std::endl;
-    //   if (dir > 0) {
-    //     xMin = -1.f * xInZone - xTolWS;
-    //   }
-    //   else {
-    //     xMax = xInZone + xTolWS;
-    //   }
-    //   debug_cout << "\t after WS treatment: xMin = " << xMin << ", xMax = " << xMax << std::endl;
-    // }
-
-    // Get the hits within the bounds
-    assert(iZone < SciFi::Constants::n_layers);
-    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
-    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
-    int x_zone_offset_end = x_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
-    const int itH = getLowerBound(scifi_hits.x0, xMin, x_zone_offset_begin, x_zone_offset_end);
-    const int itEnd = getLowerBound(scifi_hits.x0, xMax, x_zone_offset_begin, x_zone_offset_end);
-    assert(itH >= x_zone_offset_begin && itH <= x_zone_offset_end);
-    assert(itEnd >= x_zone_offset_begin && itEnd <= x_zone_offset_end);
-
-    windows_x[2*izone_rel] = itH;
-    windows_x[2*izone_rel+1] = itEnd - itH;
-
-    // Now match the stereo hits
-    const float this_uv_z = constArrays->uvZone_zPos[izone_rel];
-    const float dz_uv = this_uv_z - SciFi::Tracking::zReference;
-    const float yInUVZone = yFromVelo(this_uv_z, velo_state);
-    const float dx = yInUVZone * constArrays->uvZone_dxdy[izone_rel];
-    const float xPredUv = scifi_propagation(state_zRef.x, UT_state.tx, qOverP, dz_uv) - dx;
-    const int uv_layer = constArrays->uvZones[iZone] / 2;
-    // To Do: study this window
-    const float xBound = 70.f * window_params.extrapolation_stddev[uv_layer];
-    const float maxDx = xBound; // * ratio;
-
-    const float xMinUV = xPredUv - maxDx;
-    const float xMaxUV = xPredUv + maxDx;
-
-    // Get bounds in UV layers
-    // do one search on the same side as the x module
-    // if we are close to y = 0, also look within a region on the other side module ("triangle search")
-    assert(constArrays->uvZones[iZone] < SciFi::Constants::n_zones);
-    const int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[iZone]);
-    const int uv_zone_offset_end =
-      uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone]);
-    /* OPTIMIZE: check how large the effect on the efficiency is to include the triangle hits */
-    //    const int triangleOffset = side > 0 ? -1 : 1;
-    //assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
-    // const int triangle_zone_offset_begin =
-    //   scifi_hit_count.zone_offset(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
-    // assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
-    // const int triangle_zone_offset_end =
-    //   triangle_zone_offset_begin +
-    //   scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
-    int itUVStart = getLowerBound(scifi_hits.x0, xMinUV, uv_zone_offset_begin, uv_zone_offset_end);
-    int itUVEnd = getLowerBound(scifi_hits.x0, xMaxUV, uv_zone_offset_begin, uv_zone_offset_end);
-    //    int itUV2 = getLowerBound(scifi_hits.x0, xMinUV, triangle_zone_offset_begin, triangle_zone_offset_end);
-
-    windows_uv[2*izone_rel] = itUVStart;
-    windows_uv[2*izone_rel+1] = itUVEnd;
-
-  }
-}
-
-__host__ void collectAllXHits_proto(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const float qOverP,
-  int side,
-  std::array<int, 2 * 6>& windows_x,
-  std::array<int, 2 * 6>& windows_uv,
-  std::array<float, 4 * 6>& parameters_uv)
-{
-  // Find size of search window on reference plane, using Velo slopes and min pT as input
-  float dxRef = 0.9f * calcDxRef(SciFi::Tracking::minPt, velo_state);
-  // find position within magnet where bending happens
-  float zMag = zMagnet(velo_state, constArrays);
-
-  const float q = qOverP > 0.f ? 1.f : -1.f;
-  const float dir = q * magnet_polarity * (-1.f);
-
-  float slope2 = velo_state.tx * velo_state.tx + velo_state.ty * velo_state.ty;
-  const float pt = std::sqrt(slope2 / (1.f + slope2)) / std::abs(qOverP);
-  const bool wSignTreatment = SciFi::Tracking::useWrongSignWindow && pt > SciFi::Tracking::wrongSignPT;
-
-  float dxRefWS = 0.f;
-  if (wSignTreatment) {
-    dxRefWS = 0.9f * calcDxRef(
-                       SciFi::Tracking::wrongSignPT,
-                       velo_state); // make windows a bit too small - FIXME check effect of this, seems wrong
-  }
-
-  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
-
-  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
-    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
-    assert(iZone - iZoneStartingPoint < 12);
-
-    const auto izone_rel = iZone - iZoneStartingPoint;
-    const float zZone = constArrays->xZone_zPos[izone_rel];
-    const float xInZone = evalCubicParameterization(xParams_seed, zZone);
-    const float yInZone = evalCubicParameterization(yParams_seed, zZone);
-
-    // Now the code checks if the x and y are in the zone limits. I am really not sure
-    // why this is done here, surely could just check if within limits for the last zone
-    // in T3 and go from there? Need to think more about this.
-    //
-    // Here for now I assume the same min/max x and y for all stations, this again needs to
-    // be read from some file blablabla although actually I suspect having some general tolerances
-    // here is anyway good enough since we are doing a straight line extrapolation in the first place
-    // check (roughly) whether the extrapolated velo track is within the current zone
-    // if (side > 0) {
-    //   if (
-    //     !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-    //     !isInside(yInZone, SciFi::Tracking::yLim_Min, SciFi::Tracking::yLim_Max))
-    //     continue;
-    // }
-    // else {
-    //   if (
-    //     !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-    //     !isInside(yInZone, side * SciFi::Tracking::yLim_Max, side * SciFi::Tracking::yLim_Min))
-    //     continue;
-    // }
-
-    // extrapolate dxRef (x window on reference plane) to plane of current zone
-    const float xTol = (zZone < SciFi::Tracking::zReference) ?
-                         dxRef * zZone / SciFi::Tracking::zReference :
-                         dxRef * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-    float xMin = xInZone - xTol;
-    float xMax = xInZone + xTol;
-
-    if (SciFi::Tracking::useMomentumEstimate) { // For VeloUT tracks, suppress check if track actually has qOverP set,
-                                                // get the option right!
-      float xTolWS = 0.0;
-      if (wSignTreatment) {
-        xTolWS = (zZone < SciFi::Tracking::zReference) ?
-                   dxRefWS * zZone / SciFi::Tracking::zReference :
-                   dxRefWS * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-      }
-      if (dir > 0) {
-        xMin = xInZone - xTolWS;
-      }
-      else {
-        xMax = xInZone + xTolWS;
-      }
-    }
-
-    // Get the hits within the bounds
-    assert(iZone < SciFi::Constants::n_layers);
-    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
-    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
-    int x_zone_size = scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
-    int itH = binary_search_leftmost(scifi_hits.x0 + x_zone_offset_begin, x_zone_size, xMin);
-    const int itSize = binary_search_leftmost(scifi_hits.x0 + x_zone_offset_begin + itH, x_zone_size - itH, xMax);
-    itH += x_zone_offset_begin;
-
-    windows_x[2 * izone_rel] = itH;
-    windows_x[2 * izone_rel + 1] = itSize;
-
-    // Skip making range but continue if the size is zero
-    if (itSize == 0) continue;
-
-    // Now match the stereo hits
-    const float this_uv_z = constArrays->uvZone_zPos[iZone - iZoneStartingPoint];
-    const float xInUv = evalCubicParameterization(xParams_seed, this_uv_z);
-    const float zRatio = (this_uv_z - zMag) / (zZone - zMag);
-    const float dx = yInZone * constArrays->uvZone_dxdy[iZone - iZoneStartingPoint];
-    const float xCentral = xInZone + dx;
-    const float xPredUv = xInUv + (scifi_hits.x0[itH] - xInZone) * zRatio - dx;
-    const float maxDx = SciFi::Tracking::tolYCollectX +
-                        (fabsf(scifi_hits.x0[itH] - xCentral) + fabsf(yInZone)) * SciFi::Tracking::tolYSlopeCollectX;
-    const float xMinUV = xPredUv - maxDx;
-
-    // Get bounds in UV layers
-    // do one search on the same side as the x module
-    // if we are close to y = 0, also look within a region on the other side module ("triangle search")
-    assert(constArrays->uvZones[iZone] < SciFi::Constants::n_zones);
-    const int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[iZone]);
-    const int uv_zone_size = scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone]);
-    const int itUV1 = binary_search_leftmost(scifi_hits.x0 + uv_zone_offset_begin, uv_zone_size, xMinUV);
-
-    const float xPredUVProto = xInUv - xInZone * zRatio - dx;
-    const float maxDxProto = SciFi::Tracking::tolYCollectX + fabsf(yInZone) * SciFi::Tracking::tolYSlopeCollectX;
-
-    windows_uv[2 * izone_rel] = itUV1 + uv_zone_offset_begin;
-    windows_uv[2 * izone_rel + 1] = uv_zone_size - itUV1;
-
-    parameters_uv[4 * izone_rel] = xPredUVProto;
-    parameters_uv[4 * izone_rel + 1] = zRatio;
-    parameters_uv[4 * izone_rel + 2] = maxDxProto;
-    parameters_uv[4 * izone_rel + 3] = xCentral;
-  }
-}
-
-//=========================================================================
-// From LHCb Forward tracking description
-//
-// Collect all X hits, within a window defined by the minimum Pt.
-// Better restrictions possible, if we use the momentum of the input track.
-// Ask for the presence of a stereo hit in the same biLayer compatible.
-// This reduces the efficiency. X-alone hits to be re-added later in the processing
-//
-// side = 1  -> upper y half
-// side = -1 -> lower y half
-//=========================================================================
-//
-__host__ __device__ void collectAllXHits(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int& n_x_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state,
-  const float qOverP,
-  int side)
-{
-  // Find size of search window on reference plane, using Velo slopes and min pT as input
-  float dxRef = 0.9f * calcDxRef(SciFi::Tracking::minPt, velo_state);
-  // find position within magnet where bending happens
-  float zMag = zMagnet(velo_state, constArrays);
-
-  const float q = qOverP > 0.f ? 1.f : -1.f;
-  const float dir = q * magnet_polarity * (-1.f);
-
-  float slope2 = velo_state.tx * velo_state.tx + velo_state.ty * velo_state.ty;
-  const float pt = std::sqrt(slope2 / (1.f + slope2)) / std::abs(qOverP);
-  const bool wSignTreatment = SciFi::Tracking::useWrongSignWindow && pt > SciFi::Tracking::wrongSignPT;
-
-  float dxRefWS = 0.f;
-  if (wSignTreatment) {
-    // DvB: what happens if we use the actual momentum from VeloUT here instead of a constant?
-    dxRefWS = 0.9f * calcDxRef(
-                       SciFi::Tracking::wrongSignPT,
-                       velo_state); // make windows a bit too small - FIXME check effect of this, seems wrong
-  }
-
-  int iZoneEnd[7]; // 6 x planes
-  iZoneEnd[0] = 0;
-  int cptZone = 1;
-
-  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
-
-  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
-    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
-    assert(iZone - iZoneStartingPoint < 12);
-    const float zZone = constArrays->xZone_zPos[iZone - iZoneStartingPoint];
-    const float xInZone = evalCubicParameterization(xParams_seed, zZone);
-    const float yInZone = evalCubicParameterization(yParams_seed, zZone);
-
-    // Now the code checks if the x and y are in the zone limits. I am really not sure
-    // why this is done here, surely could just check if within limits for the last zone
-    // in T3 and go from there? Need to think more about this.
-    //
-    // Here for now I assume the same min/max x and y for all stations, this again needs to
-    // be read from some file blablabla although actually I suspect having some general tolerances
-    // here is anyway good enough since we are doing a straight line extrapolation in the first place
-    // check (roughly) whether the extrapolated velo track is within the current zone
-    if (side > 0) {
-      if (
-        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-        !isInside(yInZone, SciFi::Tracking::yLim_Min, SciFi::Tracking::yLim_Max))
-        continue;
-    }
-    else {
-      if (
-        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
-        !isInside(yInZone, side * SciFi::Tracking::yLim_Max, side * SciFi::Tracking::yLim_Min))
-        continue;
-    }
-
-    // extrapolate dxRef (x window on reference plane) to plane of current zone
-    const float xTol = (zZone < SciFi::Tracking::zReference) ?
-                         dxRef * zZone / SciFi::Tracking::zReference :
-                         dxRef * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-    float xMin = xInZone - xTol;
-    float xMax = xInZone + xTol;
-
-    if (SciFi::Tracking::useMomentumEstimate) { // For VeloUT tracks, suppress check if track actually has qOverP set,
-                                                // get the option right!
-      float xTolWS = 0.0;
-      if (wSignTreatment) {
-        xTolWS = (zZone < SciFi::Tracking::zReference) ?
-                   dxRefWS * zZone / SciFi::Tracking::zReference :
-                   dxRefWS * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
-      }
-      if (dir > 0) {
-        xMin = xInZone - xTolWS;
-      }
-      else {
-        xMax = xInZone + xTolWS;
-      }
-    }
-
-    // Get the hits within the bounds
-    assert(iZone < SciFi::Constants::n_layers);
-    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
-    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
-    int x_zone_offset_end = x_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
-    const int itH = getLowerBound(scifi_hits.x0, xMin, x_zone_offset_begin, x_zone_offset_end);
-    const int itEnd = getLowerBound(scifi_hits.x0, xMax, x_zone_offset_begin, x_zone_offset_end);
-    assert(itH >= x_zone_offset_begin && itH <= x_zone_offset_end);
-    assert(itEnd >= x_zone_offset_begin && itEnd <= x_zone_offset_end);
-
-    // Skip making range but continue if the end is before or equal to the start
-    if (!(itEnd > itH)) continue;
-
-    // Now match the stereo hits
-    const float this_uv_z = constArrays->uvZone_zPos[iZone - iZoneStartingPoint];
-    const float xInUv = evalCubicParameterization(xParams_seed, this_uv_z);
-    const float zRatio = (this_uv_z - zMag) / (zZone - zMag);
-    const float dx = yInZone * constArrays->uvZone_dxdy[iZone - iZoneStartingPoint];
-    const float xCentral = xInZone + dx;
-    const float xPredUv = xInUv + (scifi_hits.x0[itH] - xInZone) * zRatio - dx;
-    const float maxDx = SciFi::Tracking::tolYCollectX +
-                        (fabsf(scifi_hits.x0[itH] - xCentral) + fabsf(yInZone)) * SciFi::Tracking::tolYSlopeCollectX;
-    const float xMinUV = xPredUv - maxDx;
-
-    // Get bounds in UV layers
-    // do one search on the same side as the x module
-    // if we are close to y = 0, also look within a region on the other side module ("triangle search")
-    assert(constArrays->uvZones[iZone] < SciFi::Constants::n_zones);
-    const int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[iZone]);
-    const int uv_zone_offset_end =
-      uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone]);
-    const int triangleOffset = side > 0 ? -1 : 1;
-    assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
-    const int triangle_zone_offset_begin =
-      scifi_hit_count.zone_offset(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
-    assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
-    const int triangle_zone_offset_end =
-      triangle_zone_offset_begin +
-      scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
-    int itUV1 = getLowerBound(scifi_hits.x0, xMinUV, uv_zone_offset_begin, uv_zone_offset_end);
-    int itUV2 = getLowerBound(scifi_hits.x0, xMinUV, triangle_zone_offset_begin, triangle_zone_offset_end);
-
-    const float xPredUVProto = xInUv - xInZone * zRatio - dx;
-    const float maxDxProto = SciFi::Tracking::tolYCollectX + fabsf(yInZone) * SciFi::Tracking::tolYSlopeCollectX;
-
-    const bool withTriangleSearch = fabsf(yInZone) < SciFi::Tracking::tolYTriangleSearch;
-    for (int xHit = itH; xHit < itEnd; ++xHit) { // loop over all xHits in a layer between xMin and xMax
-      const float xPredUv = xPredUVProto + scifi_hits.x0[xHit] * zRatio;
-      const float maxDx = maxDxProto + fabsf(scifi_hits.x0[xHit] - xCentral) * SciFi::Tracking::tolYSlopeCollectX;
-      const float xMinUV = xPredUv - maxDx;
-      const float xMaxUV = xPredUv + maxDx;
-
-      if (
-        matchStereoHit(itUV1, uv_zone_offset_end, scifi_hits, xMinUV, xMaxUV) //) {
-        || (withTriangleSearch &&
-            matchStereoHitWithTriangle(itUV2, triangle_zone_offset_end, yInZone, scifi_hits, xMinUV, xMaxUV, side))) {
-        if (n_x_hits >= SciFi::Tracking::max_x_hits) break;
-        assert(n_x_hits < SciFi::Tracking::max_x_hits);
-        allXHits[n_x_hits++] = xHit;
-      }
-    }
-
-    const int iStart = iZoneEnd[cptZone - 1];
-    const int iEnd = n_x_hits;
-
-    assert(cptZone < 7);
-    iZoneEnd[cptZone++] = iEnd;
-
-    // project x of all hits to reference plane
-    // save it in coordX
-    // -> first step of 1D Hough transform,
-    // select clusters of x hits on reference plane in selectXCandidates
-    if (iStart < iEnd) {
-      xAtRef_SamePlaneHits(
-        scifi_hits, allXHits, n_x_hits, coordX, xParams_seed, constArrays, velo_state, zMag, iStart, iEnd);
-    }
-    if (n_x_hits >= SciFi::Tracking::max_x_hits) break;
-  }
-
-  // Sort hits by x on reference plane
-  // not using thrust::sort due to "temporary_buffer::allocate: get_temporary_buffer failed" error
-  // every time thrust::sort is called, cudaMalloc is called, apparently there can be trouble
-  // doing this many times
-  // thrust::sort_by_key(thrust::seq, coordX, coordX + n_x_hits, allXHits);
-  sortHitsByKey<SciFi::Tracking::max_x_hits>(coordX, n_x_hits, allXHits);
-}
-
-__host__ __device__ void improveXCluster(
-  int& it2,
-  const int it1,
-  const int itEnd,
-  const int n_x_hits,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const float xWindow,
-  const SciFi::Tracking::HitSearchCuts& pars,
-  PlaneCounter& planeCounter,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits)
-{
-
-  int itLast = it2 - 1;
-  while (it2 < itEnd) {
-    assert(it2 < n_x_hits);
-    if (usedHits[it2]) {
-      ++it2;
-      continue;
-    }
-    // now  the first and last+1 hit exist and are not used!
-
-    // Add next hit,
-    // if there is only a small gap between the hits
-    //    or inside window and plane is still empty
-    assert(it2 < itEnd);
-    if (
-      (coordX[it2] < coordX[itLast] + pars.maxXGap) ||
-      ((coordX[it2] - coordX[it1] < xWindow) &&
-       (planeCounter.nbInPlane(scifi_hits.planeCode(allXHits[it2]) / 2) == 0))) {
-      planeCounter.addHit(scifi_hits.planeCode(allXHits[it2]) / 2);
-      itLast = it2;
-      ++it2;
-      continue;
-    }
-    // Found nothing to improve
-    else {
-      break;
-    }
-  }
-}
-
-//=========================================================================
-//  Select the zones in the allXHits array where we can have a track
-//=========================================================================
-__host__ __device__ void selectXCandidates(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  int allXHits[SciFi::Tracking::max_x_hits],
-  int& n_x_hits,
-  bool usedHits[SciFi::Tracking::max_x_hits],
-  float coordX[SciFi::Tracking::max_x_hits],
-  SciFi::Tracking::Track candidate_tracks[SciFi::Tracking::max_candidate_tracks],
-  int& n_candidate_tracks,
-  const float zRef_track,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  const MiniState& velo_state,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::Arrays* constArrays,
-  int side,
-  const bool secondLoop)
-{
-  if (n_x_hits < pars.minXHits) return;
-  if (secondLoop)
-    if (n_candidate_tracks >= SciFi::Tracking::max_tracks_second_loop) return;
-  if (!secondLoop)
-    if (n_candidate_tracks >= SciFi::Tracking::max_candidate_tracks) return;
-
-  int itEnd = n_x_hits;
-  const float xTrack = evalCubicParameterization(xParams_seed, SciFi::Tracking::zReference);
-  int it1 = 0;
-  int it2 = 0;
-  pars.minStereoHits = 0;
-
-  PlaneCounter planeCounter;
-
-  while (it1 < itEnd) {
-    // find next unused Hits
-    assert(it1 < n_x_hits);
-    while (it1 + pars.minXHits - 1 < itEnd && usedHits[it1]) {
-      ++it1;
-    }
-
-    it2 = it1 + pars.minXHits;
-    if (it2 > itEnd) break;
-    assert(it2 - 1 < n_x_hits);
-    while (it2 <= itEnd && usedHits[it2 - 1])
-      ++it2;
-    if (it2 > itEnd) break;
-
-    // Second part of 1D Hough transform:
-    // find a cluster of x positions on the reference plane that are close to each other
-    // TODO better xWindow calculation?? how to tune this???
-    const float xWindow = pars.maxXWindow + (fabsf(coordX[it1]) + fabsf(coordX[it1] - xTrack)) * pars.maxXWindowSlope;
-
-    if ((coordX[it2 - 1] - coordX[it1]) > xWindow) {
-      ++it1;
-      continue;
-    }
-
-    // find out which planes are present in the cluster
-    countPlanesOfXHits(planeCounter, it1, it2, n_x_hits, allXHits, usedHits, scifi_hits);
-
-    // Improve cluster (at the moment only add hits to the right)
-    // to recover inefficiencies from requiring a stereo hit to
-    // be matched to an x-hit in the collectXHits step
-    improveXCluster(it2, it1, itEnd, n_x_hits, usedHits, coordX, xWindow, pars, planeCounter, allXHits, scifi_hits);
-
-    // if not enough different planes, start again from the very beginning with next right hit
-    if (planeCounter.nbDifferent < pars.minXHits) {
-      ++it1;
-      continue;
-    }
-
-    //  Now we have a (rather) clean candidate, do best hit selection
-    SciFi::Tracking::LineFitterPars lineFitParameters;
-    lineFitParameters.m_z0 = SciFi::Tracking::zReference;
-    float xAtRef = 0.;
-    const unsigned int nbSingle = planeCounter.nbSingle();
-    int coordToFit[SciFi::Tracking::max_coordToFit];
-    int n_coordToFit = 0;
-    // 1) If there are enough planes with only one hit, do a straight
-    //    line fit through these and select good matching others
-    if (nbSingle >= SciFi::Tracking::minSingleHits && nbSingle != planeCounter.nbDifferent) {
-      // 1) we have enough single planes (thus two) to make a straight line fit
-      int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits] = {0};
-      int nOtherHits[SciFi::Constants::n_layers] = {0};
-
-      // fit hits on planes with only one hit
-      // save the other hits in separate array
-      fitHitsFromSingleHitPlanes(
-        it1,
-        it2,
-        usedHits,
-        scifi_hits,
-        allXHits,
-        n_x_hits,
-        planeCounter,
-        lineFitParameters,
-        coordX,
-        otherHits,
-        nOtherHits);
-
-      // select best other hits (only best other hit is enough!)
-      // include them in fit
-      addAndFitHitsFromMultipleHitPlanes(nOtherHits, lineFitParameters, scifi_hits, coordX, allXHits, otherHits);
-
-      xAtRef = lineFitParameters.m_c0;
-    }
-    //  2) Try to find a cluster on the reference plane with a maximal
-    //     spread and from a minimum # of different planes
-    else {
-      // 2) Try to find a small distance containing at least 5(4) different planes
-      //    Most of the time do nothing
-      const unsigned int nPlanes = fminf(planeCounter.nbDifferent, uint {5});
-      int itWindowStart = it1;
-      int itWindowEnd = it1 + nPlanes; // pointing at last+1
-      // Hit is used, go to next unused one
-      while (itWindowEnd <= it2 && usedHits[itWindowEnd - 1] && (itWindowEnd - 1) < n_x_hits)
-        ++itWindowEnd;
-      int best = itWindowStart;
-      int bestEnd = itWindowEnd;
-
-      PlaneCounter lplaneCounter;
-      countUnusedXHitsOnPlanes(lplaneCounter, itWindowStart, itWindowEnd, n_x_hits, allXHits, usedHits, scifi_hits);
-
-      // modify itWindowStart and itWindowEnd while adding more x hits
-      // set best and bestEnd to include cluster of x hits on reference plane within minInterval
-      float minInterval = 1.f;
-      addXHitsForCandidateWithTooFewPlanes(
-        itWindowStart,
-        itWindowEnd,
-        it2,
-        itEnd,
-        minInterval,
-        lplaneCounter,
-        nPlanes,
-        coordX,
-        best,
-        bestEnd,
-        usedHits,
-        n_x_hits,
-        allXHits,
-        scifi_hits);
-
-      // TODO tune minInterval cut value
-      if (minInterval < 1.f) {
-        it1 = best;
-        it2 = bestEnd;
-      }
-
-      // Fill coordToFit and compute xAtRef (average x position on reference plane)
-      collectXHitsToFit(it1, it2, n_x_hits, allXHits, usedHits, coordToFit, n_coordToFit, coordX, xAtRef);
-
-    } // end of magical second part
-    //=== We have a candidate :)
-
-    planeCounter.clear();
-    for (int j = 0; j < n_coordToFit; ++j) {
-      planeCounter.addHit(scifi_hits.planeCode(coordToFit[j]) / 2);
-    }
-
-    // Only unused(!) hits in coordToFit now
-    bool ok = planeCounter.nbDifferent > 3;
-    float trackParameters[SciFi::Tracking::nTrackParams];
-    if (ok) {
-      getTrackParameters(xAtRef, velo_state, constArrays, trackParameters);
-      // Track described by cubic function in (z-zRef), but only first two terms are adjusted
-      // during fitting procedure -> linear fit
-      // nb: usedHits are currently not un-marked when removing ourliers
-      fastLinearFit(scifi_hits, trackParameters, coordToFit, n_coordToFit, planeCounter, pars);
-      // to do: do we have to mark these as used as well?
-      addHitsOnEmptyXLayers(
-        scifi_hits,
-        scifi_hit_count,
-        trackParameters,
-        xParams_seed,
-        yParams_seed,
-        false,
-        coordToFit,
-        n_coordToFit,
-        constArrays,
-        planeCounter,
-        pars,
-        side);
-
-      ok = planeCounter.nbDifferent > 3;
-    }
-    // == Fit and remove hits...
-    // track described by cubic function, but fitting only first three parameters here
-    // -> quadratic fit
-    // to do: remove outlier from usedHits
-    if (ok) ok = quadraticFitX(scifi_hits, trackParameters, coordToFit, n_coordToFit, planeCounter, pars);
-    if (ok) ok = trackParameters[7] / trackParameters[8] < SciFi::Tracking::maxChi2PerDoF;
-    if (ok)
-      ok = addHitsOnEmptyXLayers(
-        scifi_hits,
-        scifi_hit_count,
-        trackParameters,
-        xParams_seed,
-        yParams_seed,
-        true,
-        coordToFit,
-        n_coordToFit,
-        constArrays,
-        planeCounter,
-        pars,
-        side);
-    if (ok) {
-      // save track properties in track object
-      SciFi::Tracking::Track track;
-      track.chi2 = trackParameters[7];
-      for (int k = 0; k < 7; ++k) {
-        track.trackParams[k] = trackParameters[k];
-      }
-
-      for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-        int hit = coordToFit[i_hit];
-        assert(track.hitsNum < SciFi::Tracking::max_scifi_hits);
-        track.addHit(hit);
-      }
-      if (!secondLoop) {
-        assert(n_candidate_tracks < SciFi::Tracking::max_candidate_tracks);
-        candidate_tracks[n_candidate_tracks++] = track;
-      }
-      else if (secondLoop) {
-        assert(n_candidate_tracks < SciFi::Tracking::max_tracks_second_loop);
-        candidate_tracks[n_candidate_tracks++] = track;
-      }
-    }
-    if (secondLoop) {
-      if (n_candidate_tracks >= SciFi::Tracking::max_tracks_second_loop) break;
-      assert(n_candidate_tracks < SciFi::Tracking::max_tracks_second_loop);
-    }
-    else if (!secondLoop) {
-      if (n_candidate_tracks >= SciFi::Tracking::max_candidate_tracks) break;
-      assert(n_candidate_tracks < SciFi::Tracking::max_candidate_tracks);
-    }
-
-    ++it1;
-  }
-}
-
-__host__ __device__ bool addHitsOnEmptyXLayers(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  bool fullFit,
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  const SciFi::Tracking::Arrays* constArrays,
-  PlaneCounter& planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars,
-  int side)
-{
-  // is there an empty plane? otherwise skip here!
-  if (planeCounter.nbDifferent > 11) return true;
-  bool added = false;
-  const float x1 = trackParameters[0]; // mean xRef of this candidate
-  const float xAtRefFromSeed = evalCubicParameterization(xParams_seed, SciFi::Tracking::zReference);
-  const float xWindow = pars.maxXWindow + (fabsf(x1) + fabsf(x1 - xAtRefFromSeed)) * pars.maxXWindowSlope;
-
-  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
-
-  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
-    assert(constArrays->xZones[iZone] / 2 < SciFi::Constants::n_layers);
-    if (planeCounter.nbInPlane(constArrays->xZones[iZone] / 2) != 0) continue;
-
-    const float parsX[4] = {trackParameters[0], trackParameters[1], trackParameters[2], trackParameters[3]};
-
-    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
-    const float zZone = constArrays->xZone_zPos[iZone - iZoneStartingPoint];
-    // predicted x position on this plane based on current candidate
-    const float xPred = evalCubicParameterization(parsX, zZone);
-    const float minX = xPred - xWindow;
-    const float maxX = xPred + xWindow;
-
-    // -- Use a search to find the lower bound of the range of x values
-    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
-    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
-    int x_zone_offset_end = x_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
-    int itH = getLowerBound(scifi_hits.x0, minX, x_zone_offset_begin, x_zone_offset_end);
-    int itEnd = x_zone_offset_end;
-
-    int best = findBestXHitOnEmptyLayer(itEnd, itH, scifi_hits, maxX, xPred);
-
-    if (best > -1) {
-      if (n_coordToFit >= SciFi::Tracking::max_coordToFit) break;
-      assert(n_coordToFit < SciFi::Tracking::max_coordToFit);
-      coordToFit[n_coordToFit++] = best; // add the best hit here
-      planeCounter.addHit(scifi_hits.planeCode(best) / 2);
-      added = true;
-    }
-  }
-  if (!added) return true;
-  if (fullFit) {
-    return quadraticFitX(scifi_hits, trackParameters, coordToFit, n_coordToFit, planeCounter, pars);
-  }
-  fastLinearFit(scifi_hits, trackParameters, coordToFit, n_coordToFit, planeCounter, pars);
-  return true;
-}
diff --git a/cuda/SciFi/PrForward/src/HitUtils.cu b/cuda/SciFi/PrForward/src/HitUtils.cu
deleted file mode 100644
index d0de6e2d17d..00000000000
--- a/cuda/SciFi/PrForward/src/HitUtils.cu
+++ /dev/null
@@ -1,324 +0,0 @@
-#include "HitUtils.cuh"
-
-// match stereo hits to x hits
-__host__ __device__ bool matchStereoHit(
-  const int itUV1,
-  const int uv_zone_offset_end,
-  const SciFi::Hits& scifi_hits,
-  const float xMinUV,
-  const float xMaxUV)
-{
-  for (int stereoHit = itUV1; stereoHit != uv_zone_offset_end; ++stereoHit) {
-    if (scifi_hits.x0[stereoHit] > xMinUV) {
-      return (scifi_hits.x0[stereoHit] < xMaxUV);
-    }
-  }
-  return false;
-}
-
-// match stereo hits to x hits using triangle method
-__host__ __device__ bool matchStereoHitWithTriangle(
-  const int itUV2,
-  const int triangle_zone_offset_end,
-  const float yInZone,
-  const SciFi::Hits& scifi_hits,
-  const float xMinUV,
-  const float xMaxUV,
-  const int side)
-{
-
-  for (int stereoHit = itUV2; stereoHit != triangle_zone_offset_end; ++stereoHit) {
-    if (scifi_hits.x0[stereoHit] > xMinUV) {
-      // Triangle search condition depends on side
-      if (side > 0) { // upper
-        if (scifi_hits.yMax(stereoHit) > yInZone - SciFi::Tracking::yTolUVSearch) {
-          return true;
-        }
-      }
-      else { // lower
-        if (scifi_hits.yMin(stereoHit) < yInZone + SciFi::Tracking::yTolUVSearch) {
-          return true;
-        }
-      }
-    }
-  }
-  return false;
-}
-
-__host__ __device__ void removeOutlier(
-  const SciFi::Hits& scifi_hits,
-  PlaneCounter& planeCounter,
-  int* coordToFit,
-  int& n_coordToFit,
-  const int worst)
-{
-  planeCounter.removeHit(scifi_hits.planeCode(worst) / 2);
-  int coordToFit_temp[SciFi::Tracking::max_stereo_hits];
-  int i_hit_temp = 0;
-  for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-    int hit = coordToFit[i_hit];
-    if (hit != worst) coordToFit_temp[i_hit_temp++] = hit;
-  }
-  n_coordToFit = i_hit_temp;
-  for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-    coordToFit[i_hit] = coordToFit_temp[i_hit];
-  }
-}
-
-__host__ __device__ void countPlanesOfXHits(
-  PlaneCounter& planeCounter,
-  const int it1,
-  const int it2,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits)
-{
-
-  planeCounter.clear();
-  for (int itH = it1; itH != it2; ++itH) {
-    assert(itH < n_x_hits);
-    if (!usedHits[itH]) {
-      const int plane = scifi_hits.planeCode(allXHits[itH]) / 2;
-      planeCounter.addHit(plane);
-    }
-  }
-}
-
-__host__ __device__ void countUnusedXHitsOnPlanes(
-  PlaneCounter& lplaneCounter,
-  const int itWindowStart,
-  const int itWindowEnd,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits)
-{
-  for (int itH = itWindowStart; itH != itWindowEnd; ++itH) {
-    assert(itH < n_x_hits);
-    if (!usedHits[itH]) {
-      lplaneCounter.addHit(scifi_hits.planeCode(allXHits[itH]) / 2);
-    }
-  }
-}
-
-__host__ __device__ void addXHitsForCandidateWithTooFewPlanes(
-  int& itWindowStart,
-  int& itWindowEnd,
-  const int it2,
-  const int itEnd,
-  float& minInterval,
-  PlaneCounter& lplaneCounter,
-  const int nPlanes,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  int& best,
-  int& bestEnd,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits)
-{
-
-  while (itWindowEnd <= it2) {
-    if (lplaneCounter.nbDifferent >= nPlanes) {
-      // have nPlanes, check x distance
-      assert(itWindowEnd - 1 < SciFi::Tracking::max_x_hits);
-      assert(itWindowStart < SciFi::Tracking::max_x_hits);
-      const float dist = coordX[itWindowEnd - 1] - coordX[itWindowStart];
-      if (dist < minInterval) {
-        minInterval = dist;
-        best = itWindowStart;
-        bestEnd = itWindowEnd;
-      }
-    }
-    else {
-      // too few planes, add one hit
-      ++itWindowEnd;
-      if (itWindowEnd > it2) break;
-      assert(itWindowEnd <= n_x_hits);
-      while (itWindowEnd <= it2 && usedHits[itWindowEnd - 1] && itWindowEnd <= n_x_hits)
-        ++itWindowEnd;
-      lplaneCounter.addHit(scifi_hits.planeCode(allXHits[itWindowEnd - 1]) / 2);
-      continue;
-    }
-    // move on to the right
-
-    lplaneCounter.removeHit(scifi_hits.planeCode(allXHits[itWindowStart]) / 2);
-    ++itWindowStart;
-    assert(itWindowStart < itEnd);
-    while (itWindowStart < itWindowEnd && usedHits[itWindowStart] && itWindowStart < n_x_hits)
-      ++itWindowStart;
-    // last hit guaranteed to be not used. Therefore there is always at least one hit to go to. No additional if
-    // required.
-  }
-}
-
-__host__ __device__ void collectXHitsToFit(
-  const int it1,
-  const int it2,
-  const int n_x_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  bool usedHits[SciFi::Tracking::max_x_hits],
-  int coordToFit[SciFi::Tracking::max_x_hits],
-  int& n_coordToFit,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  float& xAtRef)
-{
-
-  for (int itH = it1; it2 != itH; ++itH) {
-    assert(itH < n_x_hits);
-    if (!usedHits[itH]) {
-      if (n_coordToFit >= SciFi::Tracking::max_coordToFit) break;
-      coordToFit[n_coordToFit++] = allXHits[itH];
-      usedHits[itH] = true;
-      xAtRef += coordX[itH];
-    }
-  }
-  xAtRef /= ((float) n_coordToFit);
-}
-
-__host__ __device__ int findBestXHitOnEmptyLayer(
-  const int itEnd,
-  const int itBegin,
-  const SciFi::Hits& scifi_hits,
-  const float maxX,
-  const float xPred)
-{
-
-  float bestChi2 = 1.e9f;
-  int best = -1;
-  for (int itH = itBegin; itEnd != itH; ++itH) {
-    if (scifi_hits.x0[itH] > maxX) break;
-    const float d = scifi_hits.x0[itH] - xPred; // fast distance good enough at this point (?!)
-    const float chi2 = d * d * scifi_hits.w(itH);
-    if (chi2 < bestChi2) {
-      bestChi2 = chi2;
-      best = itH;
-    }
-  }
-  return best;
-}
-
-__host__ __device__ void findStereoHitsWithinXTol(
-  const int itBegin,
-  const int itEnd,
-  const SciFi::Hits& scifi_hits,
-  const float yZone,
-  const float xPred,
-  const float dxTol,
-  const bool triangleSearch,
-  const float dxDySign,
-  int& n_stereoHits,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits])
-{
-
-  for (int itH = itBegin; itEnd != itH; ++itH) {
-    const float dx = scifi_hits.x0[itH] + yZone * scifi_hits.dxdy(itH) - xPred;
-    if (dx > dxTol) break;
-    if (triangleSearch) {
-      if (yZone > scifi_hits.yMax(itH) + SciFi::Tracking::yTolUVSearch) continue;
-      if (yZone < scifi_hits.yMin(itH) - SciFi::Tracking::yTolUVSearch) continue;
-    }
-    if (n_stereoHits >= SciFi::Tracking::max_stereo_hits) break;
-    assert(n_stereoHits < SciFi::Tracking::max_stereo_hits);
-    stereoHits[n_stereoHits] = itH;
-    stereoCoords[n_stereoHits++] = dx * dxDySign;
-  }
-}
-
-// find cluster of stereo hits with certain number of hits from different planes
-// and similar dx value (stored in stereoCoords)
-__host__ __device__ void findStereoHitClusterByDx(
-  PlaneCounter& planeCounter,
-  int& endRange,
-  const SciFi::Tracking::HitSearchCuts& pars,
-  float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  const int n_stereoHits,
-  const SciFi::Hits& scifi_hits,
-  float& sumCoord,
-  int& first_hit)
-{
-
-  while (planeCounter.nbDifferent < pars.minStereoHits ||
-         stereoCoords[endRange] < stereoCoords[first_hit] + SciFi::Tracking::minYGap && endRange < n_stereoHits - 1) {
-    planeCounter.addHit(scifi_hits.planeCode(stereoHits[endRange]) / 2);
-    sumCoord += stereoCoords[endRange];
-    ++endRange;
-    if (endRange == n_stereoHits - 1) break;
-    first_hit = endRange - 1;
-  }
-}
-
-// - remove hits on planes with more than one hit if
-//   the hit is farthest away from the mean
-// - add hit if no hit on that plane is present in the cluster yet
-//   and if the cluster spread is reduced by adding the hit
-__host__ __device__ void cleanStereoHitCluster(
-  int& beginRange,
-  int& endRange,
-  const int n_stereoHits,
-  const int stereoHits[SciFi::Tracking::max_stereo_hits],
-  const float stereoCoords[SciFi::Tracking::max_stereo_hits],
-  float& sumCoord,
-  PlaneCounter& planeCounter,
-  const SciFi::Hits& scifi_hits)
-{
-
-  while (endRange < n_stereoHits - 1) {
-    const float averageCoord = sumCoord / float(endRange - beginRange);
-
-    // remove first if not single and farthest from mean
-    if (
-      planeCounter.nbInPlane(scifi_hits.planeCode(stereoHits[beginRange]) / 2) > 1 &&
-      ((averageCoord - stereoCoords[beginRange]) > 1.0f * (stereoCoords[endRange - 1] - averageCoord))) {
-
-      planeCounter.removeHit(scifi_hits.planeCode(stereoHits[beginRange]) / 2);
-      sumCoord -= stereoCoords[beginRange];
-      beginRange++;
-      continue;
-    }
-
-    if (endRange == n_stereoHits - 1) break; // already at end, cluster cannot be expanded anymore
-    // add next, if it decreases the range size and is empty
-    if ((planeCounter.nbInPlane(scifi_hits.planeCode(stereoHits[beginRange]) / 2) == 0)) {
-      if ((averageCoord - stereoCoords[beginRange] > stereoCoords[endRange] - averageCoord)) {
-        planeCounter.addHit(scifi_hits.planeCode(stereoHits[endRange]) / 2);
-        sumCoord += stereoCoords[endRange];
-        endRange++;
-        continue;
-      }
-    }
-
-    break;
-  }
-}
-
-__host__ __device__ int findBestStereoHitOnEmptyLayer(
-  const int itBegin,
-  const int itEnd,
-  const SciFi::Hits& scifi_hits,
-  const float yZone,
-  const float xPred,
-  const float dxTol,
-  const bool triangleSearch)
-{
-
-  int best = -1;
-  float bestChi2 = SciFi::Tracking::maxChi2Stereo;
-  for (int itH = itBegin; itEnd != itH; ++itH) {
-    const float dx = scifi_hits.x0[itH] + yZone * scifi_hits.dxdy(itH) - xPred;
-    if (dx > dxTol) break;
-    if (triangleSearch) {
-      if (yZone > scifi_hits.yMax(itH) + SciFi::Tracking::yTolUVSearch) continue;
-      if (yZone < scifi_hits.yMin(itH) - SciFi::Tracking::yTolUVSearch) continue;
-    }
-    const float chi2 = dx * dx * scifi_hits.w(itH);
-    if (chi2 < bestChi2) {
-      bestChi2 = chi2;
-      best = itH;
-    }
-  }
-  return best;
-}
diff --git a/cuda/SciFi/PrForward/src/LinearFitting.cu b/cuda/SciFi/PrForward/src/LinearFitting.cu
deleted file mode 100644
index f8d16309a97..00000000000
--- a/cuda/SciFi/PrForward/src/LinearFitting.cu
+++ /dev/null
@@ -1,179 +0,0 @@
-#include "LinearFitting.cuh"
-
-/**
-   Functions related to fitting a straight line
- */
-
-__host__ __device__ float getLineFitDistance(
-  const SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int it)
-{
-  return coordX[it] - (parameters.m_c0 + (scifi_hits.z0[allXHits[it]] - parameters.m_z0) * parameters.m_tc);
-}
-
-__host__ __device__ float getLineFitChi2(
-  const SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int it)
-{
-  float d = getLineFitDistance(parameters, scifi_hits, coordX, allXHits, it);
-  return d * d * coordX[it];
-}
-
-__host__ __device__ void solveLineFit(SciFi::Tracking::LineFitterPars& parameters)
-{
-  float den = (parameters.m_sz * parameters.m_sz - parameters.m_s0 * parameters.m_sz2);
-  parameters.m_c0 = (parameters.m_scz * parameters.m_sz - parameters.m_sc * parameters.m_sz2) / den;
-  parameters.m_tc = (parameters.m_sc * parameters.m_sz - parameters.m_s0 * parameters.m_scz) / den;
-}
-
-__host__ __device__ void incrementLineFitParameters(
-  SciFi::Tracking::LineFitterPars& parameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int it)
-{
-  float c = coordX[it];
-  const int hit = allXHits[it];
-  float w = scifi_hits.w(hit);
-  float z = scifi_hits.z0[hit] - parameters.m_z0;
-  parameters.m_s0 += w;
-  parameters.m_sz += w * z;
-  parameters.m_sz2 += w * z * z;
-  parameters.m_sc += w * c;
-  parameters.m_scz += w * c * z;
-}
-
-__host__ __device__ void fitHitsFromSingleHitPlanes(
-  const int it1,
-  const int it2,
-  const bool usedHits[SciFi::Tracking::max_x_hits],
-  const SciFi::Hits& scifi_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  const PlaneCounter planeCounter,
-  SciFi::Tracking::LineFitterPars& lineFitParameters,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits],
-  int nOtherHits[SciFi::Constants::n_layers])
-{
-
-  for (auto itH = it1; it2 > itH; ++itH) {
-    assert(itH < n_x_hits);
-    if (usedHits[itH]) continue;
-    int planeCode = scifi_hits.planeCode(allXHits[itH]) / 2;
-    if (planeCounter.nbInPlane(planeCode) == 1) {
-      incrementLineFitParameters(lineFitParameters, scifi_hits, coordX, allXHits, itH);
-    }
-    else {
-      if (nOtherHits[planeCode] < SciFi::Tracking::max_other_hits) {
-        assert(nOtherHits[planeCode] < SciFi::Tracking::max_other_hits);
-        otherHits[planeCode][nOtherHits[planeCode]++] = itH;
-      }
-    }
-  }
-  solveLineFit(lineFitParameters);
-}
-
-__host__ __device__ void addAndFitHitsFromMultipleHitPlanes(
-  const int nOtherHits[SciFi::Constants::n_layers],
-  SciFi::Tracking::LineFitterPars& lineFitParameters,
-  const SciFi::Hits& scifi_hits,
-  const float coordX[SciFi::Tracking::max_x_hits],
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int otherHits[SciFi::Constants::n_layers][SciFi::Tracking::max_other_hits])
-{
-
-  for (int i = 0; i < SciFi::Constants::n_layers; i++) {
-    if (nOtherHits[i] == 0) continue;
-
-    float bestChi2 = 1e9f;
-    int best = -1;
-    for (int hit = 0; hit < nOtherHits[i]; ++hit) {
-      const float chi2 = getLineFitChi2(lineFitParameters, scifi_hits, coordX, allXHits, otherHits[i][hit]);
-      if (chi2 < bestChi2) {
-        bestChi2 = chi2;
-        best = hit;
-      }
-    }
-    if (best > -1) {
-      incrementLineFitParameters(lineFitParameters, scifi_hits, coordX, allXHits, otherHits[i][best]);
-    }
-  }
-  solveLineFit(lineFitParameters);
-}
-
-// the track parameterization is cubic in (z-zRef),
-// however only the first two parametres are varied in this fit
-// -> this is a linear fit
-__host__ __device__ void fastLinearFit(
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  PlaneCounter planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-  // re-do fit every time an outlier was removed
-  bool fit = true;
-  while (fit) {
-    //== Fit a line
-    float s0 = 0.f;
-    float sz = 0.f;
-    float sz2 = 0.f;
-    float sd = 0.f;
-    float sdz = 0.f;
-
-    for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-      int hit = coordToFit[i_hit];
-      const float parsX[4] = {trackParameters[0], trackParameters[1], trackParameters[2], trackParameters[3]};
-      const float zHit = scifi_hits.z0[hit];
-      float track_x_at_zHit = evalCubicParameterization(parsX, zHit);
-      const float d = scifi_hits.x0[hit] - track_x_at_zHit;
-      const float w = scifi_hits.w(hit);
-      const float z = zHit - SciFi::Tracking::zReference;
-      s0 += w;
-      sz += w * z;
-      sz2 += w * z * z;
-      sd += w * d;
-      sdz += w * d * z;
-    }
-    float den = (sz * sz - s0 * sz2);
-    if (!(fabsf(den) > 1e-5f)) return;
-    const float da = (sdz * sz - sd * sz2) / den;
-    const float db = (sd * sz - s0 * sdz) / den;
-    trackParameters[0] += da;
-    trackParameters[1] += db;
-    fit = false;
-
-    if (n_coordToFit < pars.minXHits) return;
-
-    int worst = n_coordToFit;
-    float maxChi2 = 0.f;
-    const bool notMultiple = planeCounter.nbDifferent == n_coordToFit;
-    // TODO how many multiple hits do we normaly have?
-    // how often do we do the right thing here?
-    // delete two hits at same time?
-    for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-      int hit = coordToFit[i_hit];
-      // This could certainly be wrapped in some helper function with a lot
-      // of passing around or copying etc...
-      const float parsX[4] = {trackParameters[0], trackParameters[1], trackParameters[2], trackParameters[3]};
-      const float chi2 = chi2XHit(parsX, scifi_hits, hit);
-      if (chi2 > maxChi2 && (notMultiple || planeCounter.nbInPlane(scifi_hits.planeCode(hit) / 2) > 1)) {
-        maxChi2 = chi2;
-        worst = i_hit;
-      }
-    }
-    if (maxChi2 > SciFi::Tracking::maxChi2LinearFit || (!notMultiple && maxChi2 > 4.f)) {
-      removeOutlier(scifi_hits, planeCounter, coordToFit, n_coordToFit, coordToFit[worst]);
-      fit = true;
-    }
-  }
-}
diff --git a/cuda/SciFi/PrForward/src/ParabolaFitting.cu b/cuda/SciFi/PrForward/src/ParabolaFitting.cu
deleted file mode 100644
index e36c0d7afad..00000000000
--- a/cuda/SciFi/PrForward/src/ParabolaFitting.cu
+++ /dev/null
@@ -1,59 +0,0 @@
-#include "ParabolaFitting.cuh"
-
-__host__ __device__ int fitParabola(
-  int* coordToFit,
-  const int n_coordToFit,
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  const bool xFit)
-{
-
-  //== Fit a cubic
-  float s0 = 0.f;
-  float sz = 0.f;
-  float sz2 = 0.f;
-  float sz3 = 0.f;
-  float sz4 = 0.f;
-  float sd = 0.f;
-  float sdz = 0.f;
-  float sdz2 = 0.f;
-
-  for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-    int hit = coordToFit[i_hit];
-    float d = trackToHitDistance(trackParameters, scifi_hits, hit);
-    if (!xFit) d *= -1.f / scifi_hits.dxdy(hit); // TODO multiplication much faster than division!
-    float w = scifi_hits.w(hit);
-    float z = .001f * (scifi_hits.z0[hit] - SciFi::Tracking::zReference);
-    s0 += w;
-    sz += w * z;
-    sz2 += w * z * z;
-    sz3 += w * z * z * z;
-    sz4 += w * z * z * z * z;
-    sd += w * d;
-    sdz += w * d * z;
-    sdz2 += w * d * z * z;
-  }
-  const float b1 = sz * sz - s0 * sz2;
-  const float c1 = sz2 * sz - s0 * sz3;
-  const float d1 = sd * sz - s0 * sdz;
-  const float b2 = sz2 * sz2 - sz * sz3;
-  const float c2 = sz3 * sz2 - sz * sz4;
-  const float d2 = sdz * sz2 - sz * sdz2;
-  const float den = (b1 * c2 - b2 * c1);
-  if (!(fabsf(den) > 1e-5f)) return false;
-  const float db = (d1 * c2 - d2 * c1) / den;
-  const float dc = (d2 * b1 - d1 * b2) / den;
-  const float da = (sd - db * sz - dc * sz2) / s0;
-  if (xFit) {
-    trackParameters[0] += da;
-    trackParameters[1] += db * 1.e-3f;
-    trackParameters[2] += dc * 1.e-6f;
-  }
-  else {
-    trackParameters[4] += da;
-    trackParameters[5] += db * 1.e-3f;
-    trackParameters[6] += dc * 1.e-6f;
-  }
-
-  return true;
-}
diff --git a/cuda/SciFi/PrForward/src/PrForward.cu b/cuda/SciFi/PrForward/src/PrForward.cu
deleted file mode 100644
index 3a7962d3af3..00000000000
--- a/cuda/SciFi/PrForward/src/PrForward.cu
+++ /dev/null
@@ -1,195 +0,0 @@
-// *********************************************************************************
-// ************************ Introduction to Forward Tracking **********************
-// *********************************************************************************
-//
-//  A detailed introduction in Forward tracking (with real pictures!) can be
-//  found here:
-//  (2002) http://cds.cern.ch/record/684710/files/lhcb-2002-008.pdf
-//  (2007) http://cds.cern.ch/record/1033584/files/lhcb-2007-015.pdf
-//  (2014) http://cds.cern.ch/record/1641927/files/LHCb-PUB-2014-001.pdf
-//
-// *** Short Introduction in geometry:
-//
-// The SciFi Tracker Detector, or simple Fibre Tracker (FT) consits out of 3 stations.
-// Each station consists out of 4 planes/layers. Thus there are in total 12 layers,
-// in which a particle can leave a hit. The reasonable maximum number of hits a track
-// can have is thus also 12 (sometimes 2 hits per layer are picked up).
-//
-// Each layer consists out of several Fibre mats. A fibre has a diameter of below a mm.(FIXME)
-// Several fibres are glued alongside each other to form a mat.
-// A Scintilating Fibre produces light, if a particle traverses. This light is then
-// detected on the outside of the Fibre mat.
-//
-// Looking from the collision point, one (X-)layer looks like the following:
-//
-//                    y       6m
-//                    ^  ||||||||||||| Upper side
-//                    |  ||||||||||||| 2.5m
-//                    |  |||||||||||||
-//                   -|--||||||o||||||----> -x
-//                       |||||||||||||
-//                       ||||||||||||| Lower side
-//                       ||||||||||||| 2.5m
-//
-// All fibres are aranged parallel to the y-axis. There are three different
-// kinds of layers, denoted by X,U,V. The U/V layers are rotated with respect to
-// the X-layers by +/- 5 degrees, to also get a handle of the y position of the
-// particle. As due to the magnetic field particles are only deflected in
-// x-direction, this configuration offers the best resolution.
-// The layer structure in the FT is XUVX-XUVX-XUVX.
-//
-// The detector is divided into an upeer and a lower side (>/< y=0). As particles
-// are only deflected in x direction there are only very(!) few particles that go
-// from the lower to the upper side, or vice versa. The reconstruction algorithm
-// can therefore be split into two independent steps: First track reconstruction
-// for tracks in the upper side, and afterwards for tracks in the lower side.
-//
-// Due to construction issues this is NOT true for U/V layers. In these layers the
-// complete(!) fibre modules are rotated, producing a zic-zac pattern at y=0, also
-// called  "the triangles". Therefore for U/V layers it must be explicetly also
-// searched for these hit on the "other side", if the track is close to y=0.
-// Sketch (rotation exagerated!):
-//                                          _.*
-//     y ^   _.*                         _.*
-//       | .*._      Upper side       _.*._
-//       |     *._                 _.*     *._
-//       |--------*._           _.*           *._----------------> x
-//       |           *._     _.*                 *._     _.*
-//                      *._.*       Lower side      *._.*
-//
-//
-//
-//
-//
-//       Zone ordering defined on PrKernel/PrFTInfo.h
-//
-//     y ^
-//       |    1  3  5  7     9 11 13 15    17 19 21 23
-//       |    |  |  |  |     |  |  |  |     |  |  |  |
-//       |    x  u  v  x     x  u  v  x     x  u  v  x   <-- type of layer
-//       |    |  |  |  |     |  |  |  |     |  |  |  |
-//       |------------------------------------------------> z
-//       |    |  |  |  |     |  |  |  |     |  |  |  |
-//       |    |  |  |  |     |  |  |  |     |  |  |  |
-//       |    0  2  4  6     8 10 12 14    16 18 20 22
-//
-//
-// *** Short introduction in the Forward Tracking algorithm
-//
-// The track reconstruction is seperated into several steps:
-//
-// 1) Using only X-hits
-//    1.1) Preselection: collectAllXHits()
-//    1.2) Hough Transformation: xAtRef_SamePlaneHits()
-//    1.3) Cluster search: selectXCandidates()
-//    1.4) Linear and than Cubic Fit of X-Projection
-// 2) Introducing U/V hits or also called stereo hits
-//    2.1) Preselection: collectStereoHits
-//    2.2) Cluster search: selectStereoHits
-//    2.3) Fit Y-Projection
-// 3) Using all (U+V+X) hits
-//    3.1) Fitting X-Projection
-//    3.2) calculating track quality with a Neural Net
-//    3.3) final clone+ghost killing
-//
-// *****************************************************************
-
-#include "PrForward.cuh"
-
-//-----------------------------------------------------------------------------
-// Implementation file for class : PrForward
-//
-// Based on code written by :
-// 2012-03-20 : Olivier Callot
-// 2013-03-15 : Thomas Nikodem
-// 2015-02-13 : Sevda Esen [additional search in the triangles by Marian Stahl]
-// 2016-03-09 : Thomas Nikodem [complete restructuring]
-// 2018-08    : Vava Gligorov [extract code from Rec, make compile within GPU framework
-// 2018-09    : Dorothea vom Bruch [convert to CUDA, runs on GPU]
-//-----------------------------------------------------------------------------
-
-//=============================================================================
-
-// Kernel to call Forward tracking on GPU
-// Loop over veloUT input tracks using threadIdx.x
-__global__ void scifi_pr_forward(
-  uint32_t* dev_scifi_hits,
-  const uint32_t* dev_scifi_hit_count,
-  const int* dev_atomics_velo,
-  const uint* dev_velo_track_hit_number,
-  const char* dev_velo_states,
-  const int* dev_atomics_ut,
-  const char* dev_ut_track_hits,
-  const uint* dev_ut_track_hit_number,
-  const float* dev_ut_qop,
-  const uint* dev_ut_track_velo_indices,
-  SciFi::TrackHits* dev_scifi_tracks,
-  int* dev_atomics_scifi,
-  const SciFi::Tracking::TMVA* dev_tmva1,
-  const SciFi::Tracking::TMVA* dev_tmva2,
-  const SciFi::Tracking::Arrays* dev_constArrays,
-  const float* dev_magnet_polarity,
-  const char* dev_scifi_geometry,
-  const float* dev_inv_clus_res)
-{
-  const uint number_of_events = gridDim.x;
-  const uint event_number = blockIdx.x;
-
-  // Velo consolidated types
-  const Velo::Consolidated::Tracks velo_tracks {
-    (uint*) dev_atomics_velo, (uint*) dev_velo_track_hit_number, event_number, number_of_events};
-  const Velo::Consolidated::States velo_states {(char*) dev_velo_states, velo_tracks.total_number_of_tracks};
-  const uint velo_tracks_offset_event = velo_tracks.tracks_offset(event_number);
-
-  // UT consolidated tracks
-  UT::Consolidated::Tracks ut_tracks {(uint*) dev_atomics_ut,
-                                      (uint*) dev_ut_track_hit_number,
-                                      (float*) dev_ut_qop,
-                                      (uint*) dev_ut_track_velo_indices,
-                                      event_number,
-                                      number_of_events};
-  const int n_veloUT_tracks_event = ut_tracks.number_of_tracks(event_number);
-  const int ut_event_tracks_offset = ut_tracks.tracks_offset(event_number);
-
-  // SciFi un-consolidated track types
-  SciFi::TrackHits* scifi_tracks_event = dev_scifi_tracks + ut_event_tracks_offset * SciFi::Constants::max_SciFi_tracks_per_UT_track;
-  int* atomics_scifi_event = dev_atomics_scifi + event_number;
-
-  // SciFi hits
-  const uint total_number_of_hits = dev_scifi_hit_count[number_of_events * SciFi::Constants::n_mat_groups_and_mats];
-  const SciFi::HitCount scifi_hit_count {(uint32_t*) dev_scifi_hit_count, event_number};
-  const SciFi::SciFiGeometry scifi_geometry {dev_scifi_geometry};
-  SciFi::Hits scifi_hits(dev_scifi_hits, total_number_of_hits, &scifi_geometry, dev_inv_clus_res);
-
-  // initialize atomic SciFi tracks counter
-  if (threadIdx.x == 0) {
-    *atomics_scifi_event = 0;
-  }
-  __syncthreads();
-
-  // Loop over the veloUT input tracks
-  for (int i = 0; i < (n_veloUT_tracks_event + blockDim.x - 1) / blockDim.x; ++i) {
-    const int i_veloUT_track = i * blockDim.x + threadIdx.x;
-    if (i_veloUT_track < n_veloUT_tracks_event) {
-      const float qop_ut = ut_tracks.qop[i_veloUT_track];
-
-      const int i_velo_track = ut_tracks.velo_track[i_veloUT_track];
-      const uint velo_states_index = velo_tracks_offset_event + i_velo_track;
-      const MiniState velo_state = velo_states.getMiniState(velo_states_index);
-
-      find_forward_tracks(
-        scifi_hits,
-        scifi_hit_count,
-        qop_ut,
-        i_veloUT_track,
-        scifi_tracks_event,
-        (uint*) atomics_scifi_event,
-        n_veloUT_tracks_event,
-        dev_tmva1,
-        dev_tmva2,
-        dev_constArrays,
-        dev_magnet_polarity[0],
-        velo_state);
-    }
-  }
-}
diff --git a/cuda/SciFi/PrForward/src/PrForwardTools.cu b/cuda/SciFi/PrForward/src/PrForwardTools.cu
deleted file mode 100644
index a79620c9a79..00000000000
--- a/cuda/SciFi/PrForward/src/PrForwardTools.cu
+++ /dev/null
@@ -1,398 +0,0 @@
-#include "PrForwardTools.cuh"
-
-/* Look first in x layers, then in stereo layers for hits
-   do 1D Hough transform for x- and stereo hits
-   do global 1D Hough transform
-   use TMVAs to obtain track quality */
-__host__ __device__ void find_forward_tracks(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const float qop_ut,
-  const int i_veloUT_track,
-  SciFi::TrackHits* outputTracks,
-  uint* n_forward_tracks,
-  const int ut_event_number_of_tracks,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const MiniState& velo_state)
-{
-
-  // The LHCb framework code had a PT preselection for the VeloUT tracks
-  // here, which I am removing because this should be done explicitly through
-  // track selectors if we do it at all, not hacked inside the tracking code
-
-  const float zRef_track = SciFi::Tracking::zReference;
-  const float xAtRef = xFromVelo(zRef_track, velo_state);
-  const float xParams_seed[4] = {xAtRef, velo_state.tx, 0.f, 0.f};
-  const float yAtRef = yFromVelo(zRef_track, velo_state);
-  const float yParams_seed[4] = {yAtRef, velo_state.ty, 0.f, 0.f};
-
-  // First loop Hough cluster search, set initial search windows
-  SciFi::Tracking::HitSearchCuts pars_first {SciFi::Tracking::minXHits,
-                                             SciFi::Tracking::maxXWindow,
-                                             SciFi::Tracking::maxXWindowSlope,
-                                             SciFi::Tracking::maxXGap,
-                                             4u};
-  SciFi::Tracking::HitSearchCuts pars_second {SciFi::Tracking::minXHits_2nd,
-                                              SciFi::Tracking::maxXWindow_2nd,
-                                              SciFi::Tracking::maxXWindowSlope_2nd,
-                                              SciFi::Tracking::maxXGap_2nd,
-                                              4u};
-
-  int allXHits[2][SciFi::Tracking::max_x_hits];
-  int n_x_hits[2] = {0};
-  float coordX[2][SciFi::Tracking::max_x_hits];
-
-  if (yAtRef > -5.f)
-    collectAllXHits(
-      scifi_hits,
-      scifi_hit_count,
-      allXHits[1],
-      n_x_hits[1],
-      coordX[1],
-      xParams_seed,
-      yParams_seed,
-      constArrays,
-      magnet_polarity,
-      velo_state,
-      qop_ut,
-      1);
-  if (yAtRef < 5.f)
-    collectAllXHits(
-      scifi_hits,
-      scifi_hit_count,
-      allXHits[0],
-      n_x_hits[0],
-      coordX[0],
-      xParams_seed,
-      yParams_seed,
-      constArrays,
-      magnet_polarity,
-      velo_state,
-      qop_ut,
-      -1);
-
-  SciFi::Tracking::Track candidate_tracks[SciFi::Tracking::max_candidate_tracks];
-  int n_candidate_tracks = 0;
-  bool usedHits[2][SciFi::Tracking::max_x_hits] = {false};
-
-  if (yAtRef > -5.f)
-    selectXCandidates(
-      scifi_hits,
-      scifi_hit_count,
-      allXHits[1],
-      n_x_hits[1],
-      usedHits[1],
-      coordX[1],
-      candidate_tracks,
-      n_candidate_tracks,
-      zRef_track,
-      xParams_seed,
-      yParams_seed,
-      velo_state,
-      pars_first,
-      constArrays,
-      1,
-      false);
-  if (yAtRef < 5.f)
-    selectXCandidates(
-      scifi_hits,
-      scifi_hit_count,
-      allXHits[0],
-      n_x_hits[0],
-      usedHits[0],
-      coordX[0],
-      candidate_tracks,
-      n_candidate_tracks,
-      zRef_track,
-      xParams_seed,
-      yParams_seed,
-      velo_state,
-      pars_first,
-      constArrays,
-      -1,
-      false);
-
-  SciFi::Tracking::Track selected_tracks[SciFi::Tracking::max_selected_tracks];
-  int n_selected_tracks = 0;
-
-  selectFullCandidates(
-    scifi_hits,
-    scifi_hit_count,
-    candidate_tracks,
-    n_candidate_tracks,
-    selected_tracks,
-    n_selected_tracks,
-    xParams_seed,
-    yParams_seed,
-    velo_state,
-    qop_ut,
-    pars_first,
-    tmva1,
-    tmva2,
-    constArrays,
-    magnet_polarity,
-    false);
-
-  bool ok = false;
-  for (int i_track = 0; i_track < n_selected_tracks; ++i_track) {
-    if (selected_tracks[i_track].hitsNum > 10) ok = true;
-  }
-  assert(n_selected_tracks < SciFi::Tracking::max_selected_tracks);
-
-  SciFi::Tracking::Track candidate_tracks2[SciFi::Tracking::max_tracks_second_loop];
-  int n_candidate_tracks2 = 0;
-
-  if (!ok && SciFi::Tracking::secondLoop) { // If you found nothing begin the 2nd loop
-    if (yAtRef > -5.f)
-      selectXCandidates(
-        scifi_hits,
-        scifi_hit_count,
-        allXHits[1],
-        n_x_hits[1],
-        usedHits[1],
-        coordX[1],
-        candidate_tracks2,
-        n_candidate_tracks2,
-        zRef_track,
-        xParams_seed,
-        yParams_seed,
-        velo_state,
-        pars_second,
-        constArrays,
-        1,
-        true);
-    if (yAtRef < 5.f)
-      selectXCandidates(
-        scifi_hits,
-        scifi_hit_count,
-        allXHits[0],
-        n_x_hits[0],
-        usedHits[0],
-        coordX[0],
-        candidate_tracks2,
-        n_candidate_tracks2,
-        zRef_track,
-        xParams_seed,
-        yParams_seed,
-        velo_state,
-        pars_second,
-        constArrays,
-        -1,
-        true);
-
-    SciFi::Tracking::Track selected_tracks2[SciFi::Tracking::max_tracks_second_loop];
-    int n_selected_tracks2 = 0;
-
-    selectFullCandidates(
-      scifi_hits,
-      scifi_hit_count,
-      candidate_tracks2,
-      n_candidate_tracks2,
-      selected_tracks2,
-      n_selected_tracks2,
-      xParams_seed,
-      yParams_seed,
-      velo_state,
-      qop_ut,
-      pars_second,
-      tmva1,
-      tmva2,
-      constArrays,
-      magnet_polarity,
-      true);
-
-    for (int i_track = 0; i_track < n_selected_tracks2; ++i_track) {
-      assert(n_selected_tracks < SciFi::Tracking::max_selected_tracks);
-      selected_tracks[n_selected_tracks++] = selected_tracks2[i_track];
-    }
-
-    ok = (n_selected_tracks > 0);
-  }
-
-  if (ok || !SciFi::Tracking::secondLoop) {
-
-    if (n_selected_tracks > 1) {
-      // not using thrust::sort due to temporary_buffer::allocate:: get_temporary_buffer failed" error
-      // thrust::sort( thrust::seq, selected_tracks, selected_tracks + n_selected_tracks, lowerByQuality);
-      sort_tracks(selected_tracks, n_selected_tracks, [](SciFi::Tracking::Track t1, SciFi::Tracking::Track t2) {
-        if (t1.quality < t2.quality) return -1;
-        if (t1.quality == t2.quality) return 0;
-        return 1;
-      });
-    }
-
-    const uint event_hit_offset = scifi_hit_count.event_offset();
-    float minQuality = SciFi::Tracking::maxQuality;
-    for (int i_track = 0; i_track < n_selected_tracks; ++i_track) {
-      SciFi::Tracking::Track& track = selected_tracks[i_track];
-
-      // TODO: We would have to work out a way for the Prforward to have max 12 hits
-      if (track.hitsNum > 12) {
-        track.hitsNum = 12;
-      }
-
-      if (track.quality + SciFi::Tracking::deltaQuality < minQuality)
-        minQuality = track.quality + SciFi::Tracking::deltaQuality;
-      if (!(track.quality > minQuality)) {
-
-        SciFi::TrackHits tr = makeTrack(track);
-        tr.ut_track_index = i_veloUT_track;
-
-        // state at end of SciFi
-        const float z = SciFi::Constants::ZEndT;
-        MiniState scifi_state(track.x(z), track.y(z), z, track.xSlope(z), track.ySlope(z));
-
-        // add LHCbIDs from SciFi part of the track
-        for (int i_hit = 0; i_hit < track.hitsNum; ++i_hit) {
-          // save local hit index within event to be able to use short
-          const int local_hit_index = track.hit_indices[i_hit] - event_hit_offset;
-          tr.add_hit(local_hit_index);
-        }
-
-        if (*n_forward_tracks >= ut_event_number_of_tracks * SciFi::Constants::max_SciFi_tracks_per_UT_track) printf("n_forward_tracks = %u \n", *n_forward_tracks);
-        assert(*n_forward_tracks < ut_event_number_of_tracks * SciFi::Constants::max_SciFi_tracks_per_UT_track);
-#ifndef __CUDA_ARCH__
-        outputTracks[(*n_forward_tracks)++] = tr;
-#else
-        uint n_tracks = atomicAdd(n_forward_tracks, 1);
-        assert(n_tracks < ut_event_number_of_tracks * SciFi::Constants::max_SciFi_tracks_per_UT_track);
-        outputTracks[n_tracks] = tr;
-#endif
-      }
-    }
-  }
-}
-
-// Turn SciFi::Tracking::Track into a SciFi::Track
-__host__ __device__ SciFi::TrackHits makeTrack(SciFi::Tracking::Track track)
-{
-  SciFi::TrackHits tr;
-  tr.qop = track.qop;
-  tr.quality = track.quality;
-
-  return tr;
-}
-
-//=========================================================================
-//  Create Full candidates out of xCandidates
-//  Searching for stereo hits
-//  Fit of all hits
-//  save everything in track candidate folder
-//=========================================================================
-__host__ __device__ void selectFullCandidates(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  SciFi::Tracking::Track* candidate_tracks,
-  int& n_candidate_tracks,
-  SciFi::Tracking::Track* selected_tracks,
-  int& n_selected_tracks,
-  const float xParams_seed[4],
-  const float yParams_seed[4],
-  MiniState velo_state,
-  const float VeloUT_qOverP,
-  SciFi::Tracking::HitSearchCuts& pars,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  const bool secondLoop)
-{
-
-  PlaneCounter planeCounter;
-  planeCounter.clear();
-  float mlpInput[7] = {0};
-
-  for (int i_track = 0; i_track < n_candidate_tracks; ++i_track) {
-    SciFi::Tracking::Track* cand = candidate_tracks + i_track;
-
-    pars.minStereoHits = 4;
-
-    if (cand->hitsNum + pars.minStereoHits < SciFi::Tracking::minTotalHits) {
-      pars.minStereoHits = SciFi::Tracking::minTotalHits - cand->hitsNum;
-    }
-
-    int stereoHits[SciFi::Tracking::max_stereo_hits];
-    int n_stereoHits = 0;
-    float stereoCoords[SciFi::Tracking::max_stereo_hits];
-    collectStereoHits(
-      scifi_hits, scifi_hit_count, *cand, velo_state, pars, constArrays, stereoCoords, stereoHits, n_stereoHits);
-
-    if (n_stereoHits < pars.minStereoHits) continue;
-
-    if (!selectStereoHits(
-          scifi_hits, scifi_hit_count, *cand, constArrays, stereoCoords, stereoHits, n_stereoHits, velo_state, pars))
-      continue;
-
-    planeCounter.clear();
-    for (int i_hit = 0; i_hit < cand->hitsNum; ++i_hit) {
-      int hit = cand->hit_indices[i_hit];
-      planeCounter.addHit(scifi_hits.planeCode(hit) / 2);
-    }
-
-    // make a fit of ALL hits using their x coordinate
-    if (!quadraticFitX(scifi_hits, cand->trackParams, cand->hit_indices, cand->hitsNum, planeCounter, pars)) continue;
-
-    // track has enough hits, calcualte quality and save if good enough
-    if (planeCounter.nbDifferent >= SciFi::Tracking::minTotalHits) {
-
-      const float qOverP = calcqOverP(cand->trackParams[1], constArrays, velo_state, magnet_polarity);
-      // orig params before fitting , TODO faster if only calc once?? mem usage?
-      const float xAtRef = cand->trackParams[0];
-      float dSlope = (velo_state.x + (SciFi::Tracking::zReference - velo_state.z) * velo_state.tx - xAtRef) /
-                     (SciFi::Tracking::zReference - constArrays->zMagnetParams[0]);
-      const float zMagSlope =
-        constArrays->zMagnetParams[2] * pow(velo_state.tx, 2) + constArrays->zMagnetParams[3] * pow(velo_state.ty, 2);
-      const float zMag = constArrays->zMagnetParams[0] + constArrays->zMagnetParams[1] * dSlope * dSlope + zMagSlope;
-      const float xMag = velo_state.x + (zMag - velo_state.z) * velo_state.tx;
-      const float slopeT = (xAtRef - xMag) / (SciFi::Tracking::zReference - zMag);
-      dSlope = slopeT - velo_state.tx;
-      const float dyCoef = dSlope * dSlope * velo_state.ty;
-
-      float bx = slopeT;
-      float ay = velo_state.y + (SciFi::Tracking::zReference - velo_state.z) * velo_state.ty;
-      float by = velo_state.ty + dyCoef * SciFi::Tracking::byParams;
-
-      // ay,by,bx params
-      const float ay1 = cand->trackParams[4];
-      const float by1 = cand->trackParams[5];
-      const float bx1 = cand->trackParams[1];
-
-      mlpInput[0] = planeCounter.nbDifferent;
-      mlpInput[1] = qOverP;
-      mlpInput[2] = VeloUT_qOverP - qOverP;                // veloUT - scifi
-      if (fabsf(VeloUT_qOverP) < 1e-9f) mlpInput[2] = 0.f; // no momentum estiamte
-      mlpInput[3] = pow(velo_state.tx, 2) + pow(velo_state.ty, 2);
-      mlpInput[4] = by - by1;
-      mlpInput[5] = bx - bx1;
-      mlpInput[6] = ay - ay1;
-
-      float quality = 0.f;
-      /// WARNING: if the NN classes straight out of TMVA are used, put a mutex here!
-      if (pars.minXHits > 4)
-        quality = GetMvaValue(mlpInput, tmva1); // 1st loop NN
-      else
-        quality = GetMvaValue(mlpInput, tmva2); // 2nd loop NN
-
-      quality = 1.f - quality; // backward compability
-
-      if (quality < SciFi::Tracking::maxQuality) {
-        cand->quality = quality;
-        cand->qop = qOverP;
-        if (!secondLoop)
-          assert(n_selected_tracks < SciFi::Tracking::max_selected_tracks);
-        else if (secondLoop)
-          assert(n_selected_tracks < SciFi::Tracking::max_tracks_second_loop);
-        selected_tracks[n_selected_tracks++] = *cand;
-        if (!secondLoop) {
-          if (n_selected_tracks >= SciFi::Tracking::max_selected_tracks) break;
-        }
-        else if (secondLoop) {
-          if (n_selected_tracks >= SciFi::Tracking::max_tracks_second_loop) break;
-        }
-      }
-    }
-  }
-}
diff --git a/cuda/SciFi/PrForward/src/ReferencePlaneProjection.cu b/cuda/SciFi/PrForward/src/ReferencePlaneProjection.cu
deleted file mode 100644
index 98328b72f59..00000000000
--- a/cuda/SciFi/PrForward/src/ReferencePlaneProjection.cu
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "ReferencePlaneProjection.cuh"
-
-// project x position of hits from one plane onto the reference plane
-// save it in coordX
-// in the c++ this is vectorized, undoing because no point before CUDA (but vectorization is obvious)
-__host__ __device__ void xAtRef_SamePlaneHits(
-  const SciFi::Hits& scifi_hits,
-  const int allXHits[SciFi::Tracking::max_x_hits],
-  const int n_x_hits,
-  float coordX[SciFi::Tracking::max_x_hits],
-  const float xParams_seed[4],
-  const SciFi::Tracking::Arrays* constArrays,
-  MiniState velo_state,
-  const float zMagSlope,
-  int itH,
-  int itEnd)
-{
-  // this is quite computationally expensive mind, should take care when porting
-  assert(itH < SciFi::Tracking::max_x_hits);
-  const float zHit = scifi_hits.z0[allXHits[itH]]; // all hits in same layer
-  const float xFromVelo_Hit = evalCubicParameterization(xParams_seed, zHit);
-  const float dSlopeDivPart = 1.f / (zHit - constArrays->zMagnetParams[0]);
-  const float dz = 1.e-3f * (zHit - SciFi::Tracking::zReference);
-
-  while (itEnd > itH) {
-    float xHit = scifi_hits.x0[allXHits[itH]];
-    // difference in slope before and after the kick
-    float dSlope = (xFromVelo_Hit - xHit) * dSlopeDivPart;
-    // update zMag now that dSlope is known
-    float zMag = zMagSlope + constArrays->zMagnetParams[1] * dSlope * dSlope;
-    float xMag = xFromVelo_Hit + velo_state.tx * (zMag - zHit);
-    // calculate x position on reference plane (save in coodX)
-    // dxCoef: account for additional bending of track due to fringe field in first station
-    // expressed by quadratic and cubic term in z
-    float dxCoef = dz * dz * (constArrays->xParams[0] + dz * constArrays->xParams[1]) * dSlope;
-    float ratio = (SciFi::Tracking::zReference - zMag) / (zHit - zMag);
-    coordX[itH] = xMag + ratio * (xHit + dxCoef - xMag);
-    itH++;
-  }
-}
diff --git a/cuda/SciFi/PrForward/src/TrackUtils.cu b/cuda/SciFi/PrForward/src/TrackUtils.cu
deleted file mode 100644
index 4114e33d0b9..00000000000
--- a/cuda/SciFi/PrForward/src/TrackUtils.cu
+++ /dev/null
@@ -1,264 +0,0 @@
-#include "TrackUtils.cuh"
-
-// extrapolate x position from given state to z
-__host__ __device__ float xFromVelo(const float z, const MiniState& velo_state)
-{
-  return velo_state.x + (z - velo_state.z) * velo_state.tx;
-}
-
-// extrapolate y position from given state to z
-__host__ __device__ float yFromVelo(const float z, const MiniState& velo_state)
-{
-  return velo_state.y + (z - velo_state.z) * velo_state.ty;
-}
-
-__host__ __device__ float evalCubicParameterization(const float params[4], float z)
-{
-  float dz = z - SciFi::Tracking::zReference;
-  return params[0] + (params[1] + (params[2] + params[3] * dz) * dz) * dz;
-}
-
-__host__ __device__ float evalParameterizationX(const float* params, float z)
-{
-  const float dz = z - SciFi::Tracking::zReference;
-  return params[0] + (params[1] + (params[2] + params[3] * dz) * dz) * dz;
-}
-
-__host__ __device__ float evalParameterizationY(const float* params, float z)
-{
-  const float dz = z - SciFi::Tracking::zReference;
-  return params[0] + (params[1] + params[2] * dz) * dz;
-}
-
-__host__ __device__ bool lowerByQuality(SciFi::Tracking::Track t1, SciFi::Tracking::Track t2)
-{
-  return t1.quality < t2.quality;
-}
-
-__host__ __device__ void getTrackParameters(
-  float xAtRef,
-  const MiniState& velo_state,
-  const SciFi::Tracking::Arrays* constArrays,
-  float trackParams[SciFi::Tracking::nTrackParams])
-{
-  float dSlope = (xFromVelo(SciFi::Tracking::zReference, velo_state) - xAtRef) /
-                 (SciFi::Tracking::zReference - constArrays->zMagnetParams[0]);
-  const float zMagSlope = constArrays->zMagnetParams[2] * velo_state.tx * velo_state.tx +
-                          constArrays->zMagnetParams[3] * velo_state.ty * velo_state.ty;
-  const float zMag = constArrays->zMagnetParams[0] + constArrays->zMagnetParams[1] * dSlope * dSlope + zMagSlope;
-  const float xMag = xFromVelo(zMag, velo_state);
-  const float slopeT = (xAtRef - xMag) / (SciFi::Tracking::zReference - zMag);
-  dSlope = slopeT - velo_state.tx;
-  const float dyCoef = dSlope * dSlope * velo_state.ty;
-
-  trackParams[0] = xAtRef;
-  trackParams[1] = slopeT;
-  trackParams[2] = 1.e-6f * constArrays->xParams[0] * dSlope;
-  trackParams[3] = 1.e-9f * constArrays->xParams[1] * dSlope;
-  trackParams[4] = yFromVelo(SciFi::Tracking::zReference, velo_state);
-  trackParams[5] = velo_state.ty + dyCoef * SciFi::Tracking::byParams;
-  trackParams[6] = dyCoef * SciFi::Tracking::cyParams;
-  trackParams[7] = 0.0f;
-  trackParams[8] = 0.0f; // last elements are chi2 and ndof, as float
-}
-
-__host__ __device__ float calcqOverP(float bx, const SciFi::Tracking::Arrays* constArrays, const MiniState& velo_state, const float magnet_polarity)
-{
-
-  float qop = 1.0f / Gaudi::Units::GeV;
-  const float bx2 = bx * bx;
-  const float ty2 = velo_state.ty * velo_state.ty;
-  const float coef =
-    (constArrays->momentumParams[0] + constArrays->momentumParams[1] * bx2 +
-     constArrays->momentumParams[2] * bx2 * bx2 + constArrays->momentumParams[3] * bx * velo_state.tx +
-     constArrays->momentumParams[4] * ty2 + constArrays->momentumParams[5] * ty2 * ty2);
-  const float tx2 = velo_state.tx * velo_state.tx;
-  float m_slope2 = tx2 + ty2;
-  float proj = sqrtf((1.f + m_slope2) / (1.f + tx2));
-  qop = (velo_state.tx - bx) / (coef * Gaudi::Units::GeV * proj * magnet_polarity);
-  return qop;
-}
-
-// Find z zMag position within the magnet at which the bending ("kick") occurs
-// this is parameterized based on MC
-// the second parameter([1]) is multiplied by the difference in slope before and
-// after the kick, this slope is calculated from zMag and the x position of the track
-// at the reference plane -> it is calculated iteratively later
-__host__ __device__ float zMagnet(const MiniState& velo_state, const SciFi::Tracking::Arrays* constArrays)
-{
-
-  return (
-    constArrays->zMagnetParams[0] + constArrays->zMagnetParams[2] * velo_state.tx * velo_state.tx +
-    constArrays->zMagnetParams[3] * velo_state.ty * velo_state.ty);
-}
-
-// calculate difference between straight line extrapolation and
-// where a track with wrongSignPT (2 GeV) would be on the reference plane (?)
-__host__ __device__ float calcDxRef(float pt, const MiniState& velo_state)
-{
-  const float tx2 = velo_state.tx * velo_state.tx;
-  const float ty2 = velo_state.ty * velo_state.ty;
-  float m_slope2 = tx2 + ty2;
-  return 3973000.f * sqrtf(m_slope2) / pt - 2200.f * ty2 - 1000.f * tx2; // tune this window
-}
-
-__host__ __device__ float
-trackToHitDistance(const float trackParameters[SciFi::Tracking::nTrackParams], const SciFi::Hits& scifi_hits, int hit)
-{
-  const float z_Hit = scifi_hits.z0[hit] + scifi_hits.dzdy(hit) * evalParameterizationY(trackParameters + 4, scifi_hits.z0[hit]);
-  const float x_track = evalParameterizationX(trackParameters, z_Hit);
-  const float y_track = evalParameterizationY(trackParameters + 4, z_Hit);
-  return scifi_hits.x0[hit] + y_track * scifi_hits.dxdy(hit) - x_track;
-}
-
-__host__ __device__ float chi2XHit(const float parsX[4], const SciFi::Hits& scifi_hits, const int hit)
-{
-  float track_x_at_zHit = evalCubicParameterization(parsX, scifi_hits.z0[hit]);
-  float hitdist = scifi_hits.x0[hit] - track_x_at_zHit;
-  return hitdist * hitdist * scifi_hits.w(hit);
-}
-
-// the track parameterization is cubic in (z-zRef),
-// however only the first three parametres are varied in this fit only
-// -> this is a quadratic fit
-__host__ __device__ bool quadraticFitX(
-  const SciFi::Hits& scifi_hits,
-  float trackParameters[SciFi::Tracking::nTrackParams],
-  int coordToFit[SciFi::Tracking::max_coordToFit],
-  int& n_coordToFit,
-  PlaneCounter& planeCounter,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-
-  if (planeCounter.nbDifferent < pars.minXHits) return false;
-  bool doFit = true;
-  while (doFit) {
-
-    fitParabola(coordToFit, n_coordToFit, scifi_hits, trackParameters, true);
-
-    float maxChi2 = 0.f;
-    float totChi2 = 0.f;
-    int nDoF = -3; // fitted 3 parameters
-    const bool notMultiple = planeCounter.nbDifferent == n_coordToFit;
-
-    int worst = n_coordToFit;
-    for (int i_hit = 0; i_hit < n_coordToFit; ++i_hit) {
-      int hit = coordToFit[i_hit];
-      float d = trackToHitDistance(trackParameters, scifi_hits, hit);
-      float chi2 = d * d * scifi_hits.w(hit);
-      totChi2 += chi2;
-      ++nDoF;
-      if (chi2 > maxChi2 && (notMultiple || planeCounter.nbInPlane(scifi_hits.planeCode(hit) / 2) > 1)) {
-        maxChi2 = chi2;
-        worst = i_hit;
-      }
-    }
-    if (nDoF < 1) return false;
-    trackParameters[7] = totChi2;
-    trackParameters[8] = (float) nDoF;
-
-    if (worst == n_coordToFit) {
-      return true;
-    }
-    doFit = false;
-    if (totChi2 / nDoF > SciFi::Tracking::maxChi2PerDoF || maxChi2 > SciFi::Tracking::maxChi2XProjection) {
-      removeOutlier(scifi_hits, planeCounter, coordToFit, n_coordToFit, coordToFit[worst]);
-      if (planeCounter.nbDifferent < pars.minXHits + pars.minStereoHits) return false;
-      doFit = true;
-    }
-  }
-  return true;
-}
-
-__host__ __device__ bool fitYProjection(
-  const SciFi::Hits& scifi_hits,
-  SciFi::Tracking::Track& track,
-  int stereoHits[SciFi::Tracking::max_stereo_hits],
-  int& n_stereoHits,
-  PlaneCounter& planeCounter,
-  const MiniState& velo_state,
-  const SciFi::Tracking::Arrays* constArrays,
-  SciFi::Tracking::HitSearchCuts& pars)
-{
-
-  float maxChi2 = 1.e9f;
-  bool parabola = false; // first linear than parabola
-  //== Fit a line
-  const float txs = track.trackParams[0]; // simplify overgeneral c++ calculation
-  const float tsxz = velo_state.x + (SciFi::Tracking::zReference - velo_state.z) * velo_state.tx;
-  const float tolYMag = SciFi::Tracking::tolYMag + SciFi::Tracking::tolYMagSlope * fabsf(txs - tsxz);
-  const float wMag = 1.f / (tolYMag * tolYMag);
-
-  bool doFit = true;
-  while (doFit) {
-    // Use position in magnet as constrain in fit
-    // although because wMag is quite small only little influence...
-    float zMag = zMagnet(velo_state, constArrays);
-    const float tys = track.trackParams[4] + (zMag - SciFi::Tracking::zReference) * track.trackParams[5];
-    const float tsyz = velo_state.y + (zMag - velo_state.z) * velo_state.ty;
-    const float dyMag = tys - tsyz;
-    zMag -= SciFi::Tracking::zReference;
-    float s0 = wMag;
-    float sz = wMag * zMag;
-    float sz2 = wMag * zMag * zMag;
-    float sd = wMag * dyMag;
-    float sdz = wMag * dyMag * zMag;
-
-    if (parabola) {
-
-      // position in magnet not used for parabola fit, hardly any influence on efficiency
-      fitParabola(stereoHits, n_stereoHits, scifi_hits, track.trackParams, false);
-    }
-    else { // straight line fit
-
-      for (int i_hit = 0; i_hit < n_stereoHits; ++i_hit) {
-        int hit = stereoHits[i_hit];
-        const float d = -trackToHitDistance(track.trackParams, scifi_hits, hit) /
-                        scifi_hits.dxdy(hit); // TODO multiplication much faster than division!
-        const float w = scifi_hits.w(hit);
-        const float z = scifi_hits.z0[hit] - SciFi::Tracking::zReference;
-        s0 += w;
-        sz += w * z;
-        sz2 += w * z * z;
-        sd += w * d;
-        sdz += w * d * z;
-      }
-      const float den = (s0 * sz2 - sz * sz);
-      if (!(fabsf(den) > 1e-5)) {
-        return false;
-      }
-      const float da = (sd * sz2 - sdz * sz) / den;
-      const float db = (sdz * s0 - sd * sz) / den;
-      track.trackParams[4] += da;
-      track.trackParams[5] += db;
-    } // fit end, now doing outlier removal
-
-    int worst = n_stereoHits;
-    maxChi2 = 0.;
-    for (int i_hit = 0; i_hit < n_stereoHits; ++i_hit) {
-      int hit = stereoHits[i_hit];
-      float d = trackToHitDistance(track.trackParams, scifi_hits, hit);
-      float chi2 = d * d * scifi_hits.w(hit);
-      if (chi2 > maxChi2) {
-        maxChi2 = chi2;
-        worst = i_hit;
-      }
-    }
-
-    if (maxChi2 < SciFi::Tracking::maxChi2StereoLinear && !parabola) {
-      parabola = true;
-      maxChi2 = 1.e9f;
-      continue;
-    }
-
-    if (maxChi2 > SciFi::Tracking::maxChi2Stereo) {
-      removeOutlier(scifi_hits, planeCounter, stereoHits, n_stereoHits, stereoHits[worst]);
-      if (planeCounter.nbDifferent < pars.minStereoHits) {
-        return false;
-      }
-      continue;
-    }
-    break;
-  }
-  return true;
-} 
diff --git a/cuda/SciFi/classifiers/README.md b/cuda/SciFi/classifiers/README.md
new file mode 100644
index 00000000000..74ef5519a4e
--- /dev/null
+++ b/cuda/SciFi/classifiers/README.md
@@ -0,0 +1 @@
+# Contains all the classifiers used to discriminate between real and fake tracks after the SciFi reconstruction
diff --git a/cuda/SciFi/PrForward/include/TMVA_Forward.cuh b/cuda/SciFi/classifiers/include/TMVA_Forward.cuh
similarity index 96%
rename from cuda/SciFi/PrForward/include/TMVA_Forward.cuh
rename to cuda/SciFi/classifiers/include/TMVA_Forward.cuh
index 1488f5b71f4..acf2f13ee06 100644
--- a/cuda/SciFi/PrForward/include/TMVA_Forward.cuh
+++ b/cuda/SciFi/classifiers/include/TMVA_Forward.cuh
@@ -5,8 +5,6 @@
 #include <string>
 #include <iostream>
 
-#include "PrForwardConstants.cuh"
-
 namespace SciFi {
 
   namespace Tracking {
diff --git a/cuda/SciFi/PrForward/include/TMVA_Forward_1.cuh b/cuda/SciFi/classifiers/include/TMVA_Forward_1.cuh
similarity index 100%
rename from cuda/SciFi/PrForward/include/TMVA_Forward_1.cuh
rename to cuda/SciFi/classifiers/include/TMVA_Forward_1.cuh
diff --git a/cuda/SciFi/PrForward/include/TMVA_Forward_2.cuh b/cuda/SciFi/classifiers/include/TMVA_Forward_2.cuh
similarity index 100%
rename from cuda/SciFi/PrForward/include/TMVA_Forward_2.cuh
rename to cuda/SciFi/classifiers/include/TMVA_Forward_2.cuh
diff --git a/cuda/SciFi/PrForward/src/TMVA_Forward.cu b/cuda/SciFi/classifiers/src/TMVA_Forward.cu
similarity index 100%
rename from cuda/SciFi/PrForward/src/TMVA_Forward.cu
rename to cuda/SciFi/classifiers/src/TMVA_Forward.cu
diff --git a/cuda/SciFi/common/include/SciFiDefinitions.cuh b/cuda/SciFi/common/include/SciFiDefinitions.cuh
index 52089e76461..506f493f3b3 100644
--- a/cuda/SciFi/common/include/SciFiDefinitions.cuh
+++ b/cuda/SciFi/common/include/SciFiDefinitions.cuh
@@ -8,7 +8,6 @@
 #include "device_launch_parameters.h"
 #include "Common.h"
 #include "Logger.h"
-#include "PrForwardConstants.cuh"
 #include "States.cuh"
 #include "SciFiRaw.cuh"
 
@@ -19,6 +18,97 @@ namespace SciFi {
   // need 3 arrays (size: number_of_events) for copy_and_prefix_sum_scifi_t
   static constexpr int num_atomics = 3;
 
+  namespace Tracking {
+
+    // The base PT threshold which is common to all algorithms
+    constexpr float minPt = 500 * Gaudi::Units::MeV; 
+
+    constexpr int max_scifi_hits = 20;  // for x and u/v layers
+    constexpr int nTrackParams = 9;
+
+    constexpr float tolYMag = 10. * Gaudi::Units::mm;
+    constexpr float tolYMagSlope = 0.015;
+
+    // parameterizations
+    constexpr float byParams = -0.667996;
+    constexpr float cyParams = -3.68424e-05;
+
+    // stereo hit matching
+    constexpr float tolYCollectX = 3.5 * Gaudi::Units::mm;        // 4.1* Gaudi::Units::mm ;
+    constexpr float tolYSlopeCollectX = 0.001 * Gaudi::Units::mm; // 0.0018 * Gaudi::Units::mm ;
+
+    // veloUT momentum estimate
+    constexpr bool useMomentumEstimate = true;
+    constexpr bool useWrongSignWindow = true;
+    constexpr float wrongSignPT = 2000. * Gaudi::Units::MeV;
+
+    // z Reference plane
+    constexpr float zReference = 8520. * Gaudi::Units::mm; // in T2
+    constexpr float zRefInv = 1.f / zReference; 
+
+    // TODO: CHECK THESE VALUES USING FRAMEWORK
+    constexpr float xLim_Max = 3300.;
+    constexpr float yLim_Max = 2500.;
+    constexpr float xLim_Min = -3300.;
+    constexpr float yLim_Min = -25.;
+
+    // TO BE READ FROM XML EVENTUALLY
+    //constexpr float magscalefactor = -1;
+    constexpr int zoneoffsetpar = 6;
+
+    struct Arrays {
+      // Returns whether the current layer is an X plane
+      const bool is_x_plane [12] {1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1};
+
+      // the Magnet Parametrization
+      // parameterized in offset [0], (slope difference due to kick)^2 [1],
+      // tx^2 [2], ty^2 [3]
+      const float zMagnetParams[4] = {5212.38, 406.609, -1102.35, -498.039};
+
+      // more Parametrizations
+      const float xParams[2] = {18.6195, -5.55793};
+
+      // momentum Parametrization
+      const float momentumParams[6] = {1.21014, 0.637339, -0.200292, 0.632298, 3.23793, -27.0259};
+
+      // covariance values
+      const float covarianceValues[5] = {4.0, 400.0, 4.e-6, 1.e-4, 0.1};
+
+      // definition of zones
+      // access upper with offset of 6
+      const int zoneoffsetpar = 6;
+      const int xZones[12] = {0, 6, 8, 14, 16, 22, 1, 7, 9, 15, 17, 23};
+      const int uvZones[12] = {2, 4, 10, 12, 18, 20, 3, 5, 11, 13, 19, 21};
+
+      // ASSORTED GEOMETRY VALUES, eventually read this from some xml
+      const float xZone_zPos[6] = {7826., 8036., 8508., 8718., 9193., 9403.};
+      const float uvZone_zPos[12] =
+        {7896., 7966., 8578., 8648., 9263., 9333., 7896., 7966., 8578., 8648., 9263., 9333.};
+      const float uvZone_dxdy[12] = {0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892,
+                                     0.0874892,
+                                     -0.0874892};
+      const float Zone_dzdy[24] = {0.0036010};
+
+      // this is used by looking_forward_sbt maybe this is not the right place to put it
+      const float uv_dx[6] = {1.6739478541449213,
+                              1.6738495069872612,
+                              1.935683825160498,
+                              1.9529279746403518,
+                              2.246931985749485,
+                              2.2797556995480273};
+    };
+ 
+  } // namespace Tracking
+
   namespace Constants {
     // Detector description
     // There are three stations with four layers each
diff --git a/cuda/SciFi/consolidate/include/ConsolidateSciFi.cuh b/cuda/SciFi/consolidate/include/ConsolidateSciFi.cuh
index 5b0e020bf04..a1c667931fe 100644
--- a/cuda/SciFi/consolidate/include/ConsolidateSciFi.cuh
+++ b/cuda/SciFi/consolidate/include/ConsolidateSciFi.cuh
@@ -8,7 +8,6 @@
 #include "ArgumentsSciFi.cuh"
 #include "ArgumentsUT.cuh"
 #include "LFFitTools.cuh"
-#include "PrForwardConstants.cuh"
 #include "LookingForwardConstants.cuh"
 
 __global__ void consolidate_scifi_tracks(
diff --git a/cuda/SciFi/looking_forward_sbt/collect_candidates/include/LFCollectCandidates.cuh b/cuda/SciFi/looking_forward_sbt/collect_candidates/include/LFCollectCandidates.cuh
index 714fbdefea2..ea380fe634c 100644
--- a/cuda/SciFi/looking_forward_sbt/collect_candidates/include/LFCollectCandidates.cuh
+++ b/cuda/SciFi/looking_forward_sbt/collect_candidates/include/LFCollectCandidates.cuh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "PrForwardConstants.cuh"
 #include "VeloConsolidated.cuh"
 #include "UTConsolidated.cuh"
 #include "SciFiEventModel.cuh"
diff --git a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindows.cuh b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindows.cuh
index 7d9cfc74da2..bea4cd10a88 100644
--- a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindows.cuh
+++ b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindows.cuh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "PrForwardConstants.cuh"
 #include "VeloConsolidated.cuh"
 #include "UTConsolidated.cuh"
 #include "SciFiEventModel.cuh"
@@ -11,6 +10,7 @@
 #include "ArgumentsSciFi.cuh"
 #include "LookingForwardConstants.cuh"
 #include "LookingForwardTools.cuh"
+#include "TrackUtils.cuh"
 
 __global__ void lf_search_initial_windows(
   uint32_t* dev_scifi_hits,
diff --git a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
index 1e9f9fb7dd2..648593a11c1 100644
--- a/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
+++ b/cuda/SciFi/looking_forward_sbt/search_initial_windows/include/LFSearchInitialWindowsImpl.cuh
@@ -6,14 +6,10 @@
 #include <algorithm>
 #include <fstream>
 #include "SciFiDefinitions.cuh"
-#include "PrForwardConstants.cuh"
 #include "UTDefinitions.cuh"
-#include "TrackUtils.cuh"
-#include "HitUtils.cuh"
-#include "LinearFitting.cuh"
-#include "ReferencePlaneProjection.cuh"
 #include "SciFiEventModel.cuh"
 #include "LookingForwardUtils.h"
+#include "TrackUtils.cuh"
 
 __device__ inline float evalCubicParameterization(
   const float value_at_ref,
diff --git a/cuda/SciFi/looking_forward_sbt/triplet_keep_best/include/LFTripletKeepBest.cuh b/cuda/SciFi/looking_forward_sbt/triplet_keep_best/include/LFTripletKeepBest.cuh
index db399acff6c..7ed714930fa 100644
--- a/cuda/SciFi/looking_forward_sbt/triplet_keep_best/include/LFTripletKeepBest.cuh
+++ b/cuda/SciFi/looking_forward_sbt/triplet_keep_best/include/LFTripletKeepBest.cuh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "PrForwardConstants.cuh"
 #include "VeloConsolidated.cuh"
 #include "UTConsolidated.cuh"
 #include "SciFiEventModel.cuh"
diff --git a/cuda/SciFi/looking_forward_sbt/triplet_seeding/include/LFTripletSeeding.cuh b/cuda/SciFi/looking_forward_sbt/triplet_seeding/include/LFTripletSeeding.cuh
index 3d7473cb80e..f5ff86367b6 100644
--- a/cuda/SciFi/looking_forward_sbt/triplet_seeding/include/LFTripletSeeding.cuh
+++ b/cuda/SciFi/looking_forward_sbt/triplet_seeding/include/LFTripletSeeding.cuh
@@ -1,6 +1,5 @@
 #pragma once
 
-#include "PrForwardConstants.cuh"
 #include "VeloConsolidated.cuh"
 #include "UTConsolidated.cuh"
 #include "SciFiEventModel.cuh"
diff --git a/cuda/SciFi/looking_forward_sbt/triplet_seeding/src/LFTripletSeeding.cu b/cuda/SciFi/looking_forward_sbt/triplet_seeding/src/LFTripletSeeding.cu
index 89c5be42c4c..53e60f89895 100644
--- a/cuda/SciFi/looking_forward_sbt/triplet_seeding/src/LFTripletSeeding.cu
+++ b/cuda/SciFi/looking_forward_sbt/triplet_seeding/src/LFTripletSeeding.cu
@@ -1,6 +1,5 @@
 #include "LFTripletSeeding.cuh"
 #include "LFTripletSeedingImpl.cuh"
-#include "TrackUtils.cuh"
 #include "LookingForwardTools.cuh"
 
 __global__ void lf_triplet_seeding(
diff --git a/cuda/SciFi/utils/README.md b/cuda/SciFi/utils/README.md
new file mode 100644
index 00000000000..18a329b1a23
--- /dev/null
+++ b/cuda/SciFi/utils/README.md
@@ -0,0 +1 @@
+# Contains utility functions useful in the SciFi reconstruction
diff --git a/cuda/SciFi/utils/include/HitUtils.cuh b/cuda/SciFi/utils/include/HitUtils.cuh
new file mode 100644
index 00000000000..f6c4f004917
--- /dev/null
+++ b/cuda/SciFi/utils/include/HitUtils.cuh
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "SciFiDefinitions.cuh"
+#include "SciFiEventModel.cuh"
+
+// match stereo hits to x hits
+__host__ __device__ bool matchStereoHit(
+  const int itUV1,
+  const int uv_zone_offset_end,
+  const SciFi::Hits& scifi_hits,
+  const float xMinUV,
+  const float xMaxUV);
+
+// check that val is within [min, max]
+__host__ __device__ inline bool isInside(float val, const float min, const float max)
+{
+  return (val > min) && (val < max);
+}
+
+// get lowest index where range[index] > value, within [start,end] of range
+__host__ __device__ inline int getLowerBound(float range[], float value, int start, int end)
+{
+  int i = start;
+  for (; i < end; i++) {
+    if (range[i] > value) break;
+  }
+  return i;
+}
diff --git a/cuda/SciFi/utils/include/TrackUtils.cuh b/cuda/SciFi/utils/include/TrackUtils.cuh
new file mode 100644
index 00000000000..d50dbeaf262
--- /dev/null
+++ b/cuda/SciFi/utils/include/TrackUtils.cuh
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <cmath>
+#include "SciFiEventModel.cuh"
+#
+/**
+   Helper functions related to track properties
+ */
+
+// extrapolate x position from given state to z
+__host__ __device__ float xFromVelo(const float z, const MiniState& velo_state);
+
+// extrapolate y position from given state to z
+__host__ __device__ float yFromVelo(const float z, const MiniState& velo_state);
+
+__host__ __device__ float evalCubicParameterization(const float params[4], float z);
+
+__host__ __device__ float zMagnet(const MiniState& velo_state, const SciFi::Tracking::Arrays* constArrays);
+
+__host__ __device__ float calcDxRef(float pt, const MiniState& velo_state);
+
+__host__ __device__ float calcqOverP(float bx, const SciFi::Tracking::Arrays* constArrays, const MiniState& velo_state, const float magnet_polarity);
+
+__host__ __device__ float evalParameterizationX(const float* params, float z);
+
+__host__ __device__ float evalParameterizationY(const float* params, float z);
+
+__host__ __device__ void getTrackParameters(
+  float xAtRef,
+  const MiniState& velo_state,
+  const SciFi::Tracking::Arrays* constArrays,
+  float trackParams[SciFi::Tracking::nTrackParams]);
+
+__host__ __device__ float
+trackToHitDistance(const float trackParameters[SciFi::Tracking::nTrackParams], const SciFi::Hits& scifi_hits, int hit);
diff --git a/cuda/SciFi/utils/src/HitUtils.cu b/cuda/SciFi/utils/src/HitUtils.cu
new file mode 100644
index 00000000000..722efa6bad2
--- /dev/null
+++ b/cuda/SciFi/utils/src/HitUtils.cu
@@ -0,0 +1,17 @@
+#include "HitUtils.cuh"
+
+// match stereo hits to x hits
+__host__ __device__ bool matchStereoHit(
+  const int itUV1,
+  const int uv_zone_offset_end,
+  const SciFi::Hits& scifi_hits,
+  const float xMinUV,
+  const float xMaxUV)
+{
+  for (int stereoHit = itUV1; stereoHit != uv_zone_offset_end; ++stereoHit) {
+    if (scifi_hits.x0[stereoHit] > xMinUV) {
+      return (scifi_hits.x0[stereoHit] < xMaxUV);
+    }
+  }
+  return false;
+}
diff --git a/cuda/SciFi/utils/src/TrackUtils.cu b/cuda/SciFi/utils/src/TrackUtils.cu
new file mode 100644
index 00000000000..69c0066c00b
--- /dev/null
+++ b/cuda/SciFi/utils/src/TrackUtils.cu
@@ -0,0 +1,108 @@
+#include "TrackUtils.cuh"
+
+// extrapolate x position from given state to z
+__host__ __device__ float xFromVelo(const float z, const MiniState& velo_state)
+{
+  return velo_state.x + (z - velo_state.z) * velo_state.tx;
+}
+
+// extrapolate y position from given state to z
+__host__ __device__ float yFromVelo(const float z, const MiniState& velo_state)
+{
+  return velo_state.y + (z - velo_state.z) * velo_state.ty;
+}
+
+__host__ __device__ float evalCubicParameterization(const float params[4], float z)
+{
+  float dz = z - SciFi::Tracking::zReference;
+  return params[0] + (params[1] + (params[2] + params[3] * dz) * dz) * dz;
+}
+
+// Find z zMag position within the magnet at which the bending ("kick") occurs
+// this is parameterized based on MC
+// the second parameter([1]) is multiplied by the difference in slope before and
+// after the kick, this slope is calculated from zMag and the x position of the track
+// at the reference plane -> it is calculated iteratively later
+__host__ __device__ float zMagnet(const MiniState& velo_state, const SciFi::Tracking::Arrays* constArrays)
+{
+
+  return (
+    constArrays->zMagnetParams[0] + constArrays->zMagnetParams[2] * velo_state.tx * velo_state.tx +
+    constArrays->zMagnetParams[3] * velo_state.ty * velo_state.ty);
+}
+
+// calculate difference between straight line extrapolation and
+// where a track with wrongSignPT (2 GeV) would be on the reference plane (?)
+__host__ __device__ float calcDxRef(float pt, const MiniState& velo_state)
+{
+  const float tx2 = velo_state.tx * velo_state.tx;
+  const float ty2 = velo_state.ty * velo_state.ty;
+  float m_slope2 = tx2 + ty2;
+  return 3973000.f * sqrtf(m_slope2) / pt - 2200.f * ty2 - 1000.f * tx2; // tune this window
+}
+
+__host__ __device__ float calcqOverP(float bx, const SciFi::Tracking::Arrays* constArrays, const MiniState& velo_state, const float magnet_polarity)
+{
+
+  float qop = 1.0f / Gaudi::Units::GeV;
+  const float bx2 = bx * bx;
+  const float ty2 = velo_state.ty * velo_state.ty;
+  const float coef =
+    (constArrays->momentumParams[0] + constArrays->momentumParams[1] * bx2 +
+     constArrays->momentumParams[2] * bx2 * bx2 + constArrays->momentumParams[3] * bx * velo_state.tx +
+     constArrays->momentumParams[4] * ty2 + constArrays->momentumParams[5] * ty2 * ty2);
+  const float tx2 = velo_state.tx * velo_state.tx;
+  float m_slope2 = tx2 + ty2;
+  float proj = sqrtf((1.f + m_slope2) / (1.f + tx2));
+  qop = (velo_state.tx - bx) / (coef * Gaudi::Units::GeV * proj * magnet_polarity);
+  return qop;
+}
+
+__host__ __device__ float evalParameterizationX(const float* params, float z)
+{
+  const float dz = z - SciFi::Tracking::zReference;
+  return params[0] + (params[1] + (params[2] + params[3] * dz) * dz) * dz;
+}
+
+__host__ __device__ float evalParameterizationY(const float* params, float z)
+{
+  const float dz = z - SciFi::Tracking::zReference;
+  return params[0] + (params[1] + params[2] * dz) * dz;
+}
+
+__host__ __device__ void getTrackParameters(
+  float xAtRef,
+  const MiniState& velo_state,
+  const SciFi::Tracking::Arrays* constArrays,
+  float trackParams[SciFi::Tracking::nTrackParams])
+{
+  float dSlope = (xFromVelo(SciFi::Tracking::zReference, velo_state) - xAtRef) /
+                 (SciFi::Tracking::zReference - constArrays->zMagnetParams[0]);
+  const float zMagSlope = constArrays->zMagnetParams[2] * velo_state.tx * velo_state.tx +
+                          constArrays->zMagnetParams[3] * velo_state.ty * velo_state.ty;
+  const float zMag = constArrays->zMagnetParams[0] + constArrays->zMagnetParams[1] * dSlope * dSlope + zMagSlope;
+  const float xMag = xFromVelo(zMag, velo_state);
+  const float slopeT = (xAtRef - xMag) / (SciFi::Tracking::zReference - zMag);
+  dSlope = slopeT - velo_state.tx;
+  const float dyCoef = dSlope * dSlope * velo_state.ty;
+
+  trackParams[0] = xAtRef;
+  trackParams[1] = slopeT;
+  trackParams[2] = 1.e-6f * constArrays->xParams[0] * dSlope;
+  trackParams[3] = 1.e-9f * constArrays->xParams[1] * dSlope;
+  trackParams[4] = yFromVelo(SciFi::Tracking::zReference, velo_state);
+  trackParams[5] = velo_state.ty + dyCoef * SciFi::Tracking::byParams;
+  trackParams[6] = dyCoef * SciFi::Tracking::cyParams;
+  trackParams[7] = 0.0f;
+  trackParams[8] = 0.0f; // last elements are chi2 and ndof, as float
+}
+
+__host__ __device__ float
+trackToHitDistance(const float trackParameters[SciFi::Tracking::nTrackParams], const SciFi::Hits& scifi_hits, int hit)
+{
+  const float z_Hit = scifi_hits.z0[hit] + scifi_hits.dzdy(hit) * evalParameterizationY(trackParameters + 4, scifi_hits.z0[hit]);
+  const float x_track = evalParameterizationX(trackParameters, z_Hit);
+  const float y_track = evalParameterizationY(trackParameters + 4, z_Hit);
+  return scifi_hits.x0[hit] + y_track * scifi_hits.dxdy(hit) - x_track;
+}
+
diff --git a/cuda/associate/CMakeLists.txt b/cuda/associate/CMakeLists.txt
index 76f5d2e27f5..b1575b153dd 100644
--- a/cuda/associate/CMakeLists.txt
+++ b/cuda/associate/CMakeLists.txt
@@ -3,7 +3,6 @@ include_directories(include)
 include_directories(${CMAKE_SOURCE_DIR}/main/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/associate/include)
diff --git a/cuda/global_event_cut/CMakeLists.txt b/cuda/global_event_cut/CMakeLists.txt
index 83074cb4f61..3bc76e4076c 100644
--- a/cuda/global_event_cut/CMakeLists.txt
+++ b/cuda/global_event_cut/CMakeLists.txt
@@ -7,7 +7,6 @@ include_directories(include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 
 add_library(GlobalEventCut STATIC
   ${global_event_cut}
diff --git a/cuda/kalman/CMakeLists.txt b/cuda/kalman/CMakeLists.txt
index 0bc451b61a8..74984fa38de 100644
--- a/cuda/kalman/CMakeLists.txt
+++ b/cuda/kalman/CMakeLists.txt
@@ -3,7 +3,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/PrVeloUT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
diff --git a/cuda/muon/CMakeLists.txt b/cuda/muon/CMakeLists.txt
index cbc307e0873..883b67a6a10 100644
--- a/cuda/muon/CMakeLists.txt
+++ b/cuda/muon/CMakeLists.txt
@@ -13,7 +13,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/main/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/utils/sorting/include)
diff --git a/cuda/selections/CMakeLists.txt b/cuda/selections/CMakeLists.txt
index b8d89779947..2f217ccbb0e 100644
--- a/cuda/selections/CMakeLists.txt
+++ b/cuda/selections/CMakeLists.txt
@@ -6,7 +6,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/beamlinePV/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/vertex_fit/common/include)
diff --git a/cuda/utils/CMakeLists.txt b/cuda/utils/CMakeLists.txt
index 9abefb046fd..172e35a1b19 100644
--- a/cuda/utils/CMakeLists.txt
+++ b/cuda/utils/CMakeLists.txt
@@ -14,7 +14,6 @@ include_directories(${CMAKE_SOURCE_DIR}/stream/gear/include)
 include_directories(${CMAKE_SOURCE_DIR}/stream/setup/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/muon/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/muon/decoding/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/kalman/ParKalman/include)
diff --git a/cuda/vertex_fit/CMakeLists.txt b/cuda/vertex_fit/CMakeLists.txt
index eb692eea66f..46dd03486d4 100644
--- a/cuda/vertex_fit/CMakeLists.txt
+++ b/cuda/vertex_fit/CMakeLists.txt
@@ -7,7 +7,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/beamlinePV/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/main/include)
diff --git a/integration/non_event_data/CMakeLists.txt b/integration/non_event_data/CMakeLists.txt
index f71b3d37713..fc4d404fce2 100644
--- a/integration/non_event_data/CMakeLists.txt
+++ b/integration/non_event_data/CMakeLists.txt
@@ -11,7 +11,7 @@ target_include_directories(NonEventData PUBLIC
   ${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include
   ${CMAKE_SOURCE_DIR}/cuda/muon/common/include
   ${CMAKE_SOURCE_DIR}/cuda/muon/decoding/include
-  ${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include
+  ${CMAKE_SOURCE_DIR}/cuda/SciFi/classifiers/include
   ${CMAKE_SOURCE_DIR}/cuda/UT/common/include
   ${CMAKE_SOURCE_DIR}/stream/sequence/include
   ${CMAKE_SOURCE_DIR}/checker/tracking/include
diff --git a/mdf/CMakeLists.txt b/mdf/CMakeLists.txt
index 3530c43f690..fa2a3beff39 100644
--- a/mdf/CMakeLists.txt
+++ b/mdf/CMakeLists.txt
@@ -58,7 +58,6 @@ target_include_directories(${name} PUBLIC
   ${CMAKE_SOURCE_DIR}/cuda/velo/common/include
   ${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include
   ${CMAKE_SOURCE_DIR}/cuda/muon/common/include
-  ${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include
   ${CMAKE_SOURCE_DIR}/cuda/UT/common/include
   ${CMAKE_SOURCE_DIR}/cuda/UT/PrVeloUT/include
   ${CMAKE_SOURCE_DIR}/checker/tracking/include)
diff --git a/stream/CMakeLists.txt b/stream/CMakeLists.txt
index 6477e2a843f..6f5a2a053bd 100644
--- a/stream/CMakeLists.txt
+++ b/stream/CMakeLists.txt
@@ -29,7 +29,8 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/search_by_triplet/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/simplified_kalman_filter/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/preprocessing/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/classifiers/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/utils/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/calculate_first_layer_window/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/calculate_second_layer_window/include)
@@ -66,7 +67,6 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/PV/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/muon/decoding/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/velo/clustering/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/UT/PrVeloUT/include)
-include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/LookingForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/MomentumForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/x86/PV/beamlinePV/include)
@@ -145,7 +145,6 @@ target_link_libraries(Stream PRIVATE
   Hlt1
   SciFi
   x86MuonDecoding
-  x86Forward
   x86LookingForward
   x86MomentumForward
   x86VeloUT
diff --git a/stream/checkers/include/SciFiSequenceCheckers_impl.cuh b/stream/checkers/include/SciFiSequenceCheckers_impl.cuh
index a7c2dc91093..0e45cf34c66 100644
--- a/stream/checkers/include/SciFiSequenceCheckers_impl.cuh
+++ b/stream/checkers/include/SciFiSequenceCheckers_impl.cuh
@@ -1,5 +1,4 @@
-#include "PrForward.cuh"
-#include "RunForwardCPU.h"
+#include "PrepareTracks.h"
 
 /**
  * @brief Specialization when invoking scifi_pr_forward_t as last step.
diff --git a/stream/checkers/include/UTSequenceCheckers_impl.cuh b/stream/checkers/include/UTSequenceCheckers_impl.cuh
index 0e23020ac00..44912186e87 100644
--- a/stream/checkers/include/UTSequenceCheckers_impl.cuh
+++ b/stream/checkers/include/UTSequenceCheckers_impl.cuh
@@ -1,6 +1,7 @@
 #include "MomentumForwardStudies.h"
 #include "LookingForwardStudies.h"
 #include "TrackChecker.h"
+#include "PrepareTracks.h"
 
 /**
  * @brief Specialization for any Velo reconstruction algorithm invoking
diff --git a/stream/checkers/include/VeloSequenceCheckers_impl.cuh b/stream/checkers/include/VeloSequenceCheckers_impl.cuh
index 0e6473b07ed..e008f10635a 100644
--- a/stream/checkers/include/VeloSequenceCheckers_impl.cuh
+++ b/stream/checkers/include/VeloSequenceCheckers_impl.cuh
@@ -1,5 +1,6 @@
 #include "ConsolidateVelo.cuh"
 #include "TrackChecker.h"
+#include "PrepareTracks.h"
 
 /**
  * @brief Specialization for any Velo reconstruction algorithm invoking
diff --git a/stream/sequence/include/Constants.cuh b/stream/sequence/include/Constants.cuh
index ba0f286ea8a..420592d5a5a 100644
--- a/stream/sequence/include/Constants.cuh
+++ b/stream/sequence/include/Constants.cuh
@@ -8,7 +8,6 @@
 #include "VeloDefinitions.cuh"
 #include "ClusteringDefinitions.cuh"
 #include "ClusteringCommon.h"
-#include "PrForwardConstants.cuh"
 #include "TMVA_Forward_1.cuh"
 #include "TMVA_Forward_2.cuh"
 #include "UTDefinitions.cuh"
diff --git a/stream/setup/include/ConfiguredSequence.cuh b/stream/setup/include/ConfiguredSequence.cuh
index 343e9d16e75..e90f0c6f500 100644
--- a/stream/setup/include/ConfiguredSequence.cuh
+++ b/stream/setup/include/ConfiguredSequence.cuh
@@ -28,7 +28,6 @@
 #include "ConsolidateSciFi.cuh"
 #include "SearchWindows.cuh"
 #include "CompassUT.cuh"
-#include "PrForward.cuh"
 #include "VeloKalmanFilter.cuh"
 #include "GetSeeds.cuh"
 #include "FitSeeds.cuh"
@@ -37,7 +36,6 @@
 #include "pv_beamline_peak.cuh"
 #include "pv_beamline_multi_fitter.cuh"
 #include "pv_beamline_cleanup.cuh"
-#include "RunForwardCPU.h"
 #include "VeloPVIP.cuh"
 #include "RunMomentumForwardCPU.h"
 #include "RunBeamlinePVOnCPU.h"
diff --git a/stream/visitors/SciFi/src/CpuSciFiMomentumForwardVisitor.cu b/stream/visitors/SciFi/src/CpuSciFiMomentumForwardVisitor.cu
index 89d519545dd..3213fa293fe 100644
--- a/stream/visitors/SciFi/src/CpuSciFiMomentumForwardVisitor.cu
+++ b/stream/visitors/SciFi/src/CpuSciFiMomentumForwardVisitor.cu
@@ -1,5 +1,4 @@
 #include "SequenceVisitor.cuh"
-#include "RunForwardCPU.h"
 #include "RunMomentumForwardCPU.h"
 #include "Tools.h"
 
diff --git a/stream/visitors/SciFi/src/CpuSciFiPrForwardVisitor.cu b/stream/visitors/SciFi/src/CpuSciFiPrForwardVisitor.cu
deleted file mode 100644
index e3c32bb50bf..00000000000
--- a/stream/visitors/SciFi/src/CpuSciFiPrForwardVisitor.cu
+++ /dev/null
@@ -1,90 +0,0 @@
-#include "SequenceVisitor.cuh"
-#include "RunForwardCPU.h"
-#include "Tools.h"
-
-template<>
-void SequenceVisitor::set_arguments_size<cpu_scifi_pr_forward_t>(
-  cpu_scifi_pr_forward_t::arguments_t arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  const HostBuffers& host_buffers)
-{
-  arguments.set_size<dev_scifi_tracks>(host_buffers.host_number_of_reconstructed_ut_tracks[0] * SciFi::Constants::max_SciFi_tracks_per_UT_track);
-  arguments.set_size<dev_atomics_scifi>(host_buffers.host_number_of_selected_events[0] * SciFi::num_atomics);
-}
-
-template<>
-void SequenceVisitor::visit<cpu_scifi_pr_forward_t>(
-  cpu_scifi_pr_forward_t& state,
-  const cpu_scifi_pr_forward_t::arguments_t& arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  HostBuffers& host_buffers,
-  cudaStream_t& cuda_stream,
-  cudaEvent_t& cuda_generic_event)
-{
-  // Synchronize previous CUDA transmissions
-  cudaEventRecord(cuda_generic_event, cuda_stream);
-  cudaEventSynchronize(cuda_generic_event);
-
-  // Run Forward on x86 architecture
-  // ATTENTION: when using SciFi raw bank version 5,
-  // need: 2*host_buffers.host_number_of_selected_events[0]*...
-  host_buffers.host_velo_states.resize(arguments.size<dev_velo_states>());
-  host_buffers.host_scifi_hits.resize(arguments.size<dev_scifi_hits>());
-  host_buffers.host_scifi_hit_count.resize(arguments.size<dev_scifi_hit_count>());
-
-  cudaCheck(cudaMemcpy(
-    host_buffers.host_scifi_hits.data(),
-    arguments.offset<dev_scifi_hits>(),
-    arguments.size<dev_scifi_hits>(),
-    cudaMemcpyDeviceToHost));
-
-  cudaCheck(cudaMemcpy(
-    host_buffers.host_scifi_hit_count.data(),
-    arguments.offset<dev_scifi_hit_count>(),
-    arguments.size<dev_scifi_hit_count>(),
-    cudaMemcpyDeviceToHost));
-
-  cudaCheck(cudaMemcpy(
-    host_buffers.host_velo_states.data(),
-    arguments.offset<dev_velo_states>(),
-    arguments.size<dev_velo_states>(),
-    cudaMemcpyDeviceToHost));
-
-  // TODO: Maybe use this rv somewhere?
-  int rv = state.invoke(
-    host_buffers.scifi_tracks_events.data(),
-    host_buffers.host_atomics_scifi,
-    host_buffers.host_scifi_hits.data(),
-    host_buffers.host_scifi_hit_count.data(),
-    constants.host_scifi_geometry.data(),
-    constants.host_inv_clus_res,
-    host_buffers.host_atomics_velo,
-    host_buffers.host_velo_track_hit_number,
-    host_buffers.host_velo_states.data(),
-    host_buffers.host_atomics_ut,
-    host_buffers.host_ut_track_hit_number,
-    host_buffers.host_ut_qop,
-    host_buffers.host_ut_track_velo_indices,
-    host_buffers.host_number_of_selected_events[0]);
-
-  if (logger::ll.verbosityLevel >= logger::debug) {
-    for (int i = 0; i < host_buffers.host_number_of_selected_events[0]; ++i) {
-      debug_cout << "Visitor: found " << host_buffers.host_atomics_scifi[i] << " tracks in event " << i << std::endl;
-    }
-  }
-
-  // copy SciFi track to device for consolidation
-  cudaCheck(cudaMemcpy(
-    arguments.offset<dev_atomics_scifi>(),
-    host_buffers.host_atomics_scifi,
-    arguments.size<dev_atomics_scifi>(),
-    cudaMemcpyHostToDevice));
-
-  cudaCheck(cudaMemcpy(
-    arguments.offset<dev_scifi_tracks>(),
-    host_buffers.scifi_tracks_events.data(),
-    arguments.size<dev_scifi_tracks>(),
-    cudaMemcpyHostToDevice));
-}
diff --git a/stream/visitors/SciFi/src/SciFiPrForwardVisitor.cu b/stream/visitors/SciFi/src/SciFiPrForwardVisitor.cu
deleted file mode 100644
index e9664d732fc..00000000000
--- a/stream/visitors/SciFi/src/SciFiPrForwardVisitor.cu
+++ /dev/null
@@ -1,48 +0,0 @@
-#include "PrForward.cuh"
-#include "SequenceVisitor.cuh"
-
-template<>
-void SequenceVisitor::set_arguments_size<scifi_pr_forward_t>(
-  scifi_pr_forward_t::arguments_t arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  const HostBuffers& host_buffers)
-{
-  arguments.set_size<dev_scifi_tracks>(host_buffers.host_number_of_reconstructed_ut_tracks[0] * SciFi::Constants::max_SciFi_tracks_per_UT_track);
-  arguments.set_size<dev_atomics_scifi>(host_buffers.host_number_of_selected_events[0] * SciFi::num_atomics);
-}
-
-template<>
-void SequenceVisitor::visit<scifi_pr_forward_t>(
-  scifi_pr_forward_t& state,
-  const scifi_pr_forward_t::arguments_t& arguments,
-  const RuntimeOptions& runtime_options,
-  const Constants& constants,
-  HostBuffers& host_buffers,
-  cudaStream_t& cuda_stream,
-  cudaEvent_t& cuda_generic_event)
-{
-  state.set_opts(dim3(host_buffers.host_number_of_selected_events[0]), dim3(32), cuda_stream);
-  state.set_arguments(
-    arguments.offset<dev_scifi_hits>(),
-    arguments.offset<dev_scifi_hit_count>(),
-    arguments.offset<dev_atomics_velo>(),
-    arguments.offset<dev_velo_track_hit_number>(),
-    arguments.offset<dev_velo_states>(),
-    arguments.offset<dev_atomics_ut>(),
-    arguments.offset<dev_ut_track_hits>(),
-    arguments.offset<dev_ut_track_hit_number>(),
-    arguments.offset<dev_ut_qop>(),
-    arguments.offset<dev_ut_track_velo_indices>(),
-    arguments.offset<dev_scifi_tracks>(),
-    arguments.offset<dev_atomics_scifi>(),
-    constants.dev_scifi_tmva1,
-    constants.dev_scifi_tmva2,
-    constants.dev_scifi_constArrays,
-    constants.dev_magnet_polarity,
-    constants.dev_scifi_geometry,
-    constants.dev_inv_clus_res);
-
-  state.invoke();
-
-}
diff --git a/x86/SciFi/CMakeLists.txt b/x86/SciFi/CMakeLists.txt
index d0bfdc8dab9..22cebb5eb65 100644
--- a/x86/SciFi/CMakeLists.txt
+++ b/x86/SciFi/CMakeLists.txt
@@ -1,3 +1,2 @@
-add_subdirectory(PrForward)
 add_subdirectory(LookingForward)
 add_subdirectory(MomentumForward)
diff --git a/x86/SciFi/LookingForward/CMakeLists.txt b/x86/SciFi/LookingForward/CMakeLists.txt
index 7537e4ec159..340f5b4f9b0 100644
--- a/x86/SciFi/LookingForward/CMakeLists.txt
+++ b/x86/SciFi/LookingForward/CMakeLists.txt
@@ -12,7 +12,8 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/classifiers/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/utils/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/utils/binary_search/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/common/include)
 include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
diff --git a/x86/SciFi/LookingForward/include/LookingForwardConstants.h b/x86/SciFi/LookingForward/include/LookingForwardConstants.h
index 230c6dfe258..a28950c5dce 100644
--- a/x86/SciFi/LookingForward/include/LookingForwardConstants.h
+++ b/x86/SciFi/LookingForward/include/LookingForwardConstants.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "SystemOfUnits.h"
-#include "PrForwardConstants.cuh"
+#include "SciFiDefinitions.cuh"
 
 namespace SciFi {
   namespace LookingForward {
diff --git a/x86/SciFi/LookingForward/include/LookingForwardSbt.h b/x86/SciFi/LookingForward/include/LookingForwardSbt.h
index bfaca590320..c358457f18d 100644
--- a/x86/SciFi/LookingForward/include/LookingForwardSbt.h
+++ b/x86/SciFi/LookingForward/include/LookingForwardSbt.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "LookingForwardUtils.h"
-#include "FindXHits.cuh"
+#include "HitUtils.cuh"
 
 // Quick class for tracklets
 struct Tracklet {
diff --git a/x86/SciFi/LookingForward/include/LookingForwardStudies.h b/x86/SciFi/LookingForward/include/LookingForwardStudies.h
index d5c321362ff..5cd489bdf63 100644
--- a/x86/SciFi/LookingForward/include/LookingForwardStudies.h
+++ b/x86/SciFi/LookingForward/include/LookingForwardStudies.h
@@ -19,6 +19,7 @@
 #include "UTConsolidated.cuh"
 #include "SciFiDefinitions.cuh"
 #include "SciFiParametrization.h"
+#include "TrackUtils.cuh"
 
 #include "LookingForwardUtils.h"
 #include "LookingForwardConstants.h"
diff --git a/x86/SciFi/LookingForward/include/LookingForwardUtils.h b/x86/SciFi/LookingForward/include/LookingForwardUtils.h
index 73a0380587b..8257b48e94b 100644
--- a/x86/SciFi/LookingForward/include/LookingForwardUtils.h
+++ b/x86/SciFi/LookingForward/include/LookingForwardUtils.h
@@ -9,13 +9,13 @@
 
 #include <cassert>
 
+#include "HitUtils.cuh"
 #include "SciFiDefinitions.cuh"
 #include "SciFiEventModel.cuh"
 #include "LookingForwardConstants.h"
 #include "MomentumForwardUtils.h"
 #include "BinarySearch.cuh"
 #include "SciFiParametrization.h"
-#include "TrackUtils.cuh"
 #include "LookingForwardFitting.h"
 #include "TMVA_Forward.cuh"
 #include "TMVA_Forward_1.cuh"
@@ -225,3 +225,18 @@ void single_track_quality_update(
   const SciFi::Tracking::TMVA* tmva2,
   const SciFi::Hits& scifi_hits,
   const int event_offset);
+
+__host__ void collectAllXHits_proto_p(
+  const SciFi::Hits& scifi_hits,
+  const SciFi::HitCount& scifi_hit_count,
+  const SciFi::Tracking::Arrays* constArrays,
+  const float magnet_polarity,
+  const MiniState& velo_state,
+  const MiniState& UT_state,
+  const float qOverP,
+  int side, 
+  std::array<int, 2 * 6>& windows_x,
+  std::array<int, 2 * 6>& windows_uv,
+  std::array<float, 4 * 6>& parameters_uv,
+  const SciFiWindowsParams& window_params,
+  const std::array<int, 12> true_scifi_indices_per_layer);
diff --git a/x86/SciFi/LookingForward/src/LookingForwardStudies.cpp b/x86/SciFi/LookingForward/src/LookingForwardStudies.cpp
index 7b9b15d6e38..2f9132fe01d 100644
--- a/x86/SciFi/LookingForward/src/LookingForwardStudies.cpp
+++ b/x86/SciFi/LookingForward/src/LookingForwardStudies.cpp
@@ -1,6 +1,4 @@
 #include "LookingForwardStudies.h"
-#include "TrackUtils.cuh"
-#include "FindXHits.cuh"
 #include "LookingForwardSbt.h"
 #include "LookingForwardConstants.cuh"
 #include <numeric>
diff --git a/x86/SciFi/LookingForward/src/LookingForwardUtils.cpp b/x86/SciFi/LookingForward/src/LookingForwardUtils.cpp
index fe1b294374c..a25c77b0a4f 100644
--- a/x86/SciFi/LookingForward/src/LookingForwardUtils.cpp
+++ b/x86/SciFi/LookingForward/src/LookingForwardUtils.cpp
@@ -924,3 +924,161 @@ void filter_tracks_with_TMVA(
     selected_tracks.push_back(tracks[best_track]);
   }
 }
+
+
+__host__ void collectAllXHits_proto_p(
+  const SciFi::Hits& scifi_hits,
+  const SciFi::HitCount& scifi_hit_count,
+  const SciFi::Tracking::Arrays* constArrays,
+  const float magnet_polarity,
+  const MiniState& velo_state,
+  const MiniState& UT_state,
+  const float qOverP,
+  int side,
+  std::array<int, 2 * 6>& windows_x,
+  std::array<int, 2 * 6>& windows_uv,
+  std::array<float, 4 * 6>& parameters_uv,
+  const SciFiWindowsParams& window_params,
+  const std::array<int, 12> true_scifi_indices_per_layer)
+{
+  const float tx2 = velo_state.tx*velo_state.tx;
+  const float ty2 = velo_state.ty*velo_state.ty;
+  const float slope2 = tx2 + ty2;
+  const float pt = sqrtf(slope2 / (1.f + slope2) ) / fabsf(qOverP);
+  const float p = 1.f / std::abs(qOverP);
+
+  /* OPTIMIZE: possibly use these variables for wrong sign treatment */
+  // const float q = qOverP > 0.f ? 1.f : -1.f;
+  // const bool wSignTreatment = pt > SciFi::Tracking::wrongSignPT;
+  // float zMag = zMagnet(velo_state, constArrays);
+  // const float qop_WS = sqrtf(slope2 / (1.f + slope2) ) / pt;
+  // float dxRefWS = 0.f;
+  // if ( wSignTreatment ) {
+  //   dxRefWS = 0.9f * calcDxRef(SciFi::Tracking::wrongSignPT, velo_state);
+  // }
+  // const float dir = q * SciFi::Tracking::magscalefactor * (-1.f); // needed for wrong sign treatment
+  // const float xTolWS = dx_calc(velo_state, qop_WS, window_params);
+
+  //const float q = qOverP > 0.f ? 1.f : -1.f;
+  //const float dir = q * magnet_polarity * (-1.f);
+
+  //const bool wSignTreatment = pt > SciFi::Tracking::wrongSignPT;
+  float zMag = zMagnet(velo_state, constArrays);
+  const float qop_WS = sqrtf(slope2 / (1.f + slope2) ) / pt;
+  // float dxRefWS = 0.f;
+  // if ( wSignTreatment ) {
+  //   dxRefWS = 0.9f * calcDxRef(SciFi::Tracking::wrongSignPT, velo_state);
+  // }
+  const float xAtRef = xFromVelo(SciFi::Tracking::zReference, UT_state);
+  float xParams_seed[4] {xAtRef, UT_state.tx, 0, 0};
+
+  // use parametrization to propagate from UT to SciFi
+  const auto state_zRef = propagate_state_from_velo(UT_state, qOverP, 5);  // zRef is between layers 4 and 5
+  const float xTol = dx_calc(velo_state, qOverP, window_params);
+  int iZoneStartingPoint = side > 0 ? constArrays->zoneoffsetpar : 0;
+
+  for (unsigned int iZone = iZoneStartingPoint; iZone < iZoneStartingPoint + constArrays->zoneoffsetpar; iZone++) {
+    assert(iZone - iZoneStartingPoint < SciFi::Constants::n_zones);
+    assert(iZone - iZoneStartingPoint < 12);
+
+    const auto izone_rel = iZone - iZoneStartingPoint;
+    const float zZone = constArrays->xZone_zPos[izone_rel];
+
+    //const int layer = constArrays->xZones[iZone] / 2;
+    const float dz_x = (zZone - SciFi::Tracking::zReference);
+    const float xInZone = scifi_propagation(state_zRef.x, UT_state.tx, qOverP, dz_x);
+    const float yInZone = yFromVelo(zZone, velo_state);
+
+    const float xInZoneStraight = evalCubicParameterization(xParams_seed, zZone);
+
+    if (side > 0) {
+      if (
+        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
+        !isInside(yInZone, SciFi::Tracking::yLim_Min, SciFi::Tracking::yLim_Max))
+        continue;
+    }
+    else {
+      if (
+        !isInside(xInZone, SciFi::Tracking::xLim_Min, SciFi::Tracking::xLim_Max) ||
+        !isInside(yInZone, side * SciFi::Tracking::yLim_Max, side * SciFi::Tracking::yLim_Min))
+        continue;
+    }
+
+    float xMin = xInZone - xTol;
+    float xMax = xInZone + xTol;
+
+    /* OPTIMIZE: how do we take care of wrong sign tracks with momentum windows? */
+    //float xTolWS = 0.0;
+    // if (wSignTreatment) {
+    //   // xTolWS = (zZone < SciFi::Tracking::zReference) ?
+    //   //   dxRefWS * zZone / SciFi::Tracking::zReference :
+    //   //   dxRefWS * (zZone - zMag) / (SciFi::Tracking::zReference - zMag);
+    //   // if (dir > 0) {
+    //   //   xMin = xInZone - xTolWS;
+    //   // }
+    //   // else {
+    //   //   xMax = xInZone + xTolWS;
+    //   // }
+
+    //   debug_cout << "\t before WS treatment: xMin = " << xMin << ", xMax = " << xMax << ", WS = " << int(wSignTreatment) << ", pt = " << pt << std::endl;
+    //   if (dir > 0) {
+    //     xMin = -1.f * xInZone - xTolWS;
+    //   }
+    //   else {
+    //     xMax = xInZone + xTolWS;
+    //   }
+    //   debug_cout << "\t after WS treatment: xMin = " << xMin << ", xMax = " << xMax << std::endl;
+    // }
+
+    // Get the hits within the bounds
+    assert(iZone < SciFi::Constants::n_layers);
+    assert(constArrays->xZones[iZone] < SciFi::Constants::n_zones);
+    int x_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->xZones[iZone]);
+    int x_zone_offset_end = x_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->xZones[iZone]);
+    const int itH = getLowerBound(scifi_hits.x0, xMin, x_zone_offset_begin, x_zone_offset_end);
+    const int itEnd = getLowerBound(scifi_hits.x0, xMax, x_zone_offset_begin, x_zone_offset_end);
+    assert(itH >= x_zone_offset_begin && itH <= x_zone_offset_end);
+    assert(itEnd >= x_zone_offset_begin && itEnd <= x_zone_offset_end);
+
+    windows_x[2*izone_rel] = itH;
+    windows_x[2*izone_rel+1] = itEnd - itH;
+
+    // Now match the stereo hits
+    const float this_uv_z = constArrays->uvZone_zPos[izone_rel];
+    const float dz_uv = this_uv_z - SciFi::Tracking::zReference;
+    const float yInUVZone = yFromVelo(this_uv_z, velo_state);
+    const float dx = yInUVZone * constArrays->uvZone_dxdy[izone_rel];
+    const float xPredUv = scifi_propagation(state_zRef.x, UT_state.tx, qOverP, dz_uv) - dx;
+    const int uv_layer = constArrays->uvZones[iZone] / 2;
+    // To Do: study this window
+    const float xBound = 70.f * window_params.extrapolation_stddev[uv_layer];
+    const float maxDx = xBound; // * ratio;
+
+    const float xMinUV = xPredUv - maxDx;
+    const float xMaxUV = xPredUv + maxDx;
+
+    // Get bounds in UV layers
+    // do one search on the same side as the x module
+    // if we are close to y = 0, also look within a region on the other side module ("triangle search")
+    assert(constArrays->uvZones[iZone] < SciFi::Constants::n_zones);
+    const int uv_zone_offset_begin = scifi_hit_count.zone_offset(constArrays->uvZones[iZone]);
+    const int uv_zone_offset_end =
+      uv_zone_offset_begin + scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone]);
+    /* OPTIMIZE: check how large the effect on the efficiency is to include the triangle hits */
+    //    const int triangleOffset = side > 0 ? -1 : 1;
+    //assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
+    // const int triangle_zone_offset_begin =
+    //   scifi_hit_count.zone_offset(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
+    // assert(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset] < SciFi::Constants::n_zones);
+    // const int triangle_zone_offset_end =
+    //   triangle_zone_offset_begin +
+    //   scifi_hit_count.zone_number_of_hits(constArrays->uvZones[iZone + constArrays->zoneoffsetpar * triangleOffset]);
+    int itUVStart = getLowerBound(scifi_hits.x0, xMinUV, uv_zone_offset_begin, uv_zone_offset_end);
+    int itUVEnd = getLowerBound(scifi_hits.x0, xMaxUV, uv_zone_offset_begin, uv_zone_offset_end);
+    //    int itUV2 = getLowerBound(scifi_hits.x0, xMinUV, triangle_zone_offset_begin, triangle_zone_offset_end);
+
+    windows_uv[2*izone_rel] = itUVStart;
+    windows_uv[2*izone_rel+1] = itUVEnd;
+
+  }
+}
diff --git a/x86/SciFi/MomentumForward/CMakeLists.txt b/x86/SciFi/MomentumForward/CMakeLists.txt
index 2c33bcd8195..ed98cb7844e 100644
--- a/x86/SciFi/MomentumForward/CMakeLists.txt
+++ b/x86/SciFi/MomentumForward/CMakeLists.txt
@@ -11,7 +11,7 @@ include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
+include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/classifiers/include)
 include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
 
 file(GLOB x86MomentumForward "src/*cpp" )
@@ -20,8 +20,6 @@ add_library(x86MomentumForward STATIC
   ${x86MomentumForward}
 )
 
-set_property(TARGET x86Forward PROPERTY
-             CUDA_SEPARABLE_COMPILATION ON)
 set_property(TARGET x86MomentumForward PROPERTY
              CUDA_RESOLVE_DEVICE_SYMBOLS ON)
 
diff --git a/x86/SciFi/MomentumForward/include/MomentumForwardConstants.h b/x86/SciFi/MomentumForward/include/MomentumForwardConstants.h
index 73bd1c667d8..a1cf1569f94 100644
--- a/x86/SciFi/MomentumForward/include/MomentumForwardConstants.h
+++ b/x86/SciFi/MomentumForward/include/MomentumForwardConstants.h
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "SystemOfUnits.h"
-#include "PrForwardConstants.cuh"
+#include "SciFiDefinitions.cuh"
 
 namespace SciFi {
   namespace MomentumForward {
diff --git a/x86/SciFi/PrForward/CMakeLists.txt b/x86/SciFi/PrForward/CMakeLists.txt
deleted file mode 100644
index 45de4aada34..00000000000
--- a/x86/SciFi/PrForward/CMakeLists.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-include_directories(include)
-include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/looking_forward/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/checker/tracking/include)
-include_directories(${CMAKE_SOURCE_DIR}/main/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/PrVeloUT/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/UTDecoding/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/velo/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/UT/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/event_model/SciFi/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/utils/sorting)
-include_directories(${CMAKE_SOURCE_DIR}/stream/gear/include)
-include_directories(${CMAKE_SOURCE_DIR}/stream/setup/include)
-include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/LookingForward/include)
-include_directories(${CMAKE_SOURCE_DIR}/x86/SciFi/MomentumForward/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/utils/binary_search/include)
-
-
-file(GLOB x86Forward_src "src/*cpp")
-
-add_library(x86Forward STATIC
-  ${x86Forward_src}
-)
-
-set_property(TARGET x86Forward PROPERTY
-             CUDA_SEPARABLE_COMPILATION ON)
-set_property(TARGET x86Forward PROPERTY
-             CUDA_RESOLVE_DEVICE_SYMBOLS ON)
-
-if ( ROOT_FOUND )
-  target_compile_definitions(x86Forward PUBLIC WITH_ROOT)
-  target_include_directories(x86Forward BEFORE PRIVATE
-    ${ROOT_INCLUDE_DIRS}
-  )
-endif()
diff --git a/x86/SciFi/PrForward/include/PrForwardWrapper.h b/x86/SciFi/PrForward/include/PrForwardWrapper.h
deleted file mode 100644
index 058ffd00202..00000000000
--- a/x86/SciFi/PrForward/include/PrForwardWrapper.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-#include "PrForwardTools.cuh"
-
-void PrForwardWrapper(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const Velo::Consolidated::States& velo_states,
-  const uint event_tracks_offset,
-  const UT::Consolidated::Tracks& ut_tracks,
-  const int n_veloUT_tracks,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  SciFi::TrackHits outputTracks[SciFi::Constants::max_tracks],
-  uint* n_forward_tracks);
diff --git a/x86/SciFi/PrForward/include/RunForwardCPU.h b/x86/SciFi/PrForward/include/RunForwardCPU.h
deleted file mode 100644
index 8252af53601..00000000000
--- a/x86/SciFi/PrForward/include/RunForwardCPU.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include "Common.h"
-#include "VeloDefinitions.cuh"
-#include "TrackChecker.h"
-#include "PrForwardWrapper.h"
-#include "VeloEventModel.cuh"
-#include "CpuHandler.cuh"
-#include "PrepareTracks.h"
-#include "ArgumentsCommon.cuh"
-#include "ArgumentsVelo.cuh"
-#include "ArgumentsUT.cuh"
-#include "ArgumentsSciFi.cuh"
-
-int run_forward_on_CPU(
-  SciFi::TrackHits* host_scifi_tracks_events,
-  int* host_scifi_n_tracks,
-  const uint* host_scifi_hits,
-  const uint* host_scifi_hit_count,
-  const char* host_scifi_geometry,
-  const std::array<float, 9>& host_inv_clus_res,
-  const uint* host_velo_tracks_atomics,
-  const uint* host_velo_track_hit_number,
-  const char* host_velo_states,
-  const int* host_atomics_ut,
-  const uint* host_ut_track_hit_number,
-  const float* host_ut_qop,
-  const uint* host_ut_track_velo_indices,
-  const uint number_of_events);
-
-CPU_ALGORITHM(
-  run_forward_on_CPU,
-  cpu_scifi_pr_forward_t,
-  ARGUMENTS(
-    dev_scifi_tracks,
-    dev_atomics_scifi,
-    dev_scifi_selected_track_indices,
-    dev_scifi_hits,
-    dev_scifi_hit_count,
-    dev_atomics_velo,
-    dev_velo_track_hit_number,
-    dev_velo_states,
-    dev_atomics_ut,
-    dev_ut_track_hits,
-    dev_ut_track_hit_number,
-    dev_ut_qop,
-    dev_ut_track_velo_indices))
diff --git a/x86/SciFi/PrForward/src/PrForwardWrapper.cpp b/x86/SciFi/PrForward/src/PrForwardWrapper.cpp
deleted file mode 100644
index aeebab54bce..00000000000
--- a/x86/SciFi/PrForward/src/PrForwardWrapper.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "PrForwardWrapper.h"
-
-void PrForwardWrapper(
-  const SciFi::Hits& scifi_hits,
-  const SciFi::HitCount& scifi_hit_count,
-  const Velo::Consolidated::States& velo_states,
-  const uint event_tracks_offset,
-  const UT::Consolidated::Tracks& ut_tracks,
-  const int n_veloUT_tracks,
-  const SciFi::Tracking::TMVA* tmva1,
-  const SciFi::Tracking::TMVA* tmva2,
-  const SciFi::Tracking::Arrays* constArrays,
-  const float magnet_polarity,
-  SciFi::TrackHits outputTracks[SciFi::Constants::max_tracks],
-  uint* n_forward_tracks)
-{
-  // Loop over the veloUT input tracks
-  for (int i_veloUT_track = 0; i_veloUT_track < n_veloUT_tracks; ++i_veloUT_track) {
-    const float qop_ut = ut_tracks.qop[i_veloUT_track];
-
-    const int i_velo_track = ut_tracks.velo_track[i_veloUT_track];
-    const uint velo_states_index = event_tracks_offset + i_velo_track;
-    const MiniState velo_state = velo_states.get(velo_states_index);
-
-    find_forward_tracks(
-      scifi_hits,
-      scifi_hit_count,
-      qop_ut,
-      i_veloUT_track,
-      outputTracks,
-      n_forward_tracks,
-      n_veloUT_tracks,
-      tmva1,
-      tmva2,
-      constArrays,
-      magnet_polarity,
-      velo_state);
-  }
-}
diff --git a/x86/SciFi/PrForward/src/RunForwardCPU.cpp b/x86/SciFi/PrForward/src/RunForwardCPU.cpp
deleted file mode 100644
index 5e2c4383bb8..00000000000
--- a/x86/SciFi/PrForward/src/RunForwardCPU.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-#include "RunForwardCPU.h"
-
-#ifdef WITH_ROOT
-#include "TH1D.h"
-#include "TFile.h"
-#include "TTree.h"
-#endif
-
-int run_forward_on_CPU(
-  SciFi::TrackHits* host_scifi_tracks,
-  int* host_scifi_n_tracks,
-  const uint* host_scifi_hits,
-  const uint* host_scifi_hit_count,
-  const char* host_scifi_geometry,
-  const std::array<float, 9>& host_inv_clus_res,
-  const uint* host_velo_tracks_atomics,
-  const uint* host_velo_track_hit_number,
-  const char* host_velo_states,
-  const int* host_atomics_ut,
-  const uint* host_ut_track_hit_number,
-  const float* host_ut_qop,
-  const uint* host_ut_track_velo_indices,
-  const uint number_of_events)
-{
-  // #ifdef WITH_ROOT
-  //   // Histograms only for checking and debugging
-  //   TFile* f = new TFile("../output/scifi.root", "RECREATE");
-  //   TTree* t_Forward_tracks = new TTree("Forward_tracks", "Forward_tracks");
-  //   TTree* t_statistics = new TTree("statistics", "statistics");
-  //   TTree* t_scifi_hits = new TTree("scifi_hits", "scifi_hits");
-  //   uint planeCode, LHCbID;
-  //   float x0, z0, w, dxdy, dzdy, yMin, yMax;
-  //   float qop;
-  //   int n_tracks;
-  //   float state_x, state_y, state_z, state_tx, state_ty;
-
-  //   t_Forward_tracks->Branch("qop", &qop);
-  //   t_Forward_tracks->Branch("state_x", &state_x);
-  //   t_Forward_tracks->Branch("state_y", &state_y);
-  //   t_Forward_tracks->Branch("state_z", &state_z);
-  //   t_Forward_tracks->Branch("state_tx", &state_tx);
-  //   t_Forward_tracks->Branch("state_ty", &state_ty);
-  //   t_statistics->Branch("n_tracks", &n_tracks);
-  //   t_scifi_hits->Branch("planeCode", &planeCode);
-  //   t_scifi_hits->Branch("LHCbID", &LHCbID);
-  //   t_scifi_hits->Branch("x0", &x0);
-  //   t_scifi_hits->Branch("z0", &z0);
-  //   t_scifi_hits->Branch("w", &w);
-  //   t_scifi_hits->Branch("dxdy", &dxdy);
-  //   t_scifi_hits->Branch("dzdy", &dzdy);
-  //   t_scifi_hits->Branch("yMin", &yMin);
-  //   t_scifi_hits->Branch("yMax", &yMax);
-  // #endif
-
-  // // to do: set from configuration
-  // const float magnet_polarity = -1.f;
-
-  //   for (uint i_event = 0; i_event < number_of_events; ++i_event) {
-
-  //     // Velo consolidated types
-  //     const Velo::Consolidated::Tracks velo_tracks {
-  //       (uint*) host_velo_tracks_atomics, (uint*) host_velo_track_hit_number, i_event, number_of_events};
-  //     const uint event_tracks_offset = velo_tracks.tracks_offset(i_event);
-  //     const Velo::Consolidated::States host_velo_states_event {(char*) host_velo_states,
-  //                                                              velo_tracks.total_number_of_tracks};
-
-  //     // UT consolidated types
-  //     UT::Consolidated::Tracks ut_tracks {(uint*) host_atomics_ut,
-  //                                         (uint*) host_ut_track_hit_number,
-  //                                         (float*) host_ut_qop,
-  //                                         (uint*) host_ut_track_velo_indices,
-  //                                         i_event,
-  //                                         number_of_events};
-  //     const int n_veloUT_tracks_event = ut_tracks.number_of_tracks(i_event);
-
-  //     // SciFi non-consolidated types
-  //     int* n_forward_tracks = host_scifi_n_tracks + i_event;
-  //     SciFi::TrackHits* scifi_tracks_event = host_scifi_tracks + i_event * SciFi::Constants::max_tracks;
-  //  MiniState* scifi_states_event;
-
-  //     const uint total_number_of_hits = host_scifi_hit_count[number_of_events *
-  //     SciFi::Constants::n_mat_groups_and_mats]; SciFi::HitCount scifi_hit_count {(uint32_t*) host_scifi_hit_count,
-  //     i_event};
-
-  //     const SciFi::SciFiGeometry scifi_geometry(host_scifi_geometry);
-
-  //     SciFi::Hits scifi_hits(
-  //       (uint*) host_scifi_hits,
-  //       total_number_of_hits,
-  //       &scifi_geometry,
-  //       reinterpret_cast<const float*>(host_inv_clus_res.data()));
-
-  // #ifdef WITH_ROOT
-  //     // store hit variables in tree
-  //     for (size_t zone = 0; zone < SciFi::Constants::n_zones; zone++) {
-  //       const auto zone_offset = scifi_hit_count.zone_offset(zone);
-  //       for (size_t hit = 0; hit < scifi_hit_count.zone_number_of_hits(zone); hit++) {
-  //         const auto hit_offset = zone_offset + hit;
-
-  //         planeCode = scifi_hits.planeCode(hit_offset);
-  //         LHCbID = scifi_hits.LHCbID(hit_offset);
-  //         x0 = scifi_hits.x0[hit_offset];
-  //         z0 = scifi_hits.z0[hit_offset];
-  //         w = scifi_hits.w(hit_offset);
-  //         dxdy = scifi_hits.dxdy(hit_offset);
-  //         dzdy = scifi_hits.dzdy(hit_offset);
-  //         yMin = scifi_hits.yMin(hit_offset);
-  //         yMax = scifi_hits.yMax(hit_offset);
-  //         t_scifi_hits->Fill();
-  //       }
-  //     }
-  // #endif
-
-  //     // initialize TMVA vars
-  //     SciFi::Tracking::TMVA tmva1;
-  //     SciFi::Tracking::TMVA1_Init(tmva1);
-  //     SciFi::Tracking::TMVA tmva2;
-  //     SciFi::Tracking::TMVA2_Init(tmva2);
-
-  //     SciFi::Tracking::Arrays constArrays;
-
-  //     PrForwardWrapper(
-  //       scifi_hits,
-  //       scifi_hit_count,
-  //       host_velo_states_event,
-  //       event_tracks_offset,
-  //       ut_tracks,
-  //       n_veloUT_tracks_event,
-  //       &tmva1,
-  //       &tmva2,
-  //       &constArrays,
-  //       magnet_polarity,
-  //       scifi_tracks_event,
-  //       (uint*) n_forward_tracks);
-
-  // #ifdef WITH_ROOT
-  //     // store qop in tree
-  //     for (int i_track = 0; i_track < *n_forward_tracks; ++i_track) {
-  //       qop = scifi_tracks_event[i_track].qop;
-  //       state_x = scifi_tracks_event[i_track].state.x;
-  //       state_y = scifi_tracks_event[i_track].state.y;
-  //       state_z = scifi_tracks_event[i_track].state.z;
-  //       state_tx = scifi_tracks_event[i_track].state.tx;
-  //       state_ty = scifi_tracks_event[i_track].state.ty;
-  //       t_Forward_tracks->Fill();
-  //     }
-  //     n_tracks = n_forward_tracks[i_event];
-  //     t_statistics->Fill();
-  // #endif
-  //   }
-
-  // #ifdef WITH_ROOT
-  //   f->Write();
-  //   f->Close();
-  // #endif
-
-  return 0;
-}
diff --git a/x86/global_event_cut/CMakeLists.txt b/x86/global_event_cut/CMakeLists.txt
index 0973aa29a48..31ae99b9375 100644
--- a/x86/global_event_cut/CMakeLists.txt
+++ b/x86/global_event_cut/CMakeLists.txt
@@ -7,7 +7,6 @@ include_directories(${CMAKE_SOURCE_DIR}/stream/setup/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/velo/common/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/UT/common/include)
-include_directories(${CMAKE_SOURCE_DIR}/cuda/SciFi/PrForward/include)
 include_directories(${CMAKE_SOURCE_DIR}/cuda/global_event_cut/include)
 
 add_library(CpuGEC STATIC
-- 
GitLab


From 158bb13c6ec7203ef90ec1d7c5b9d23053cc2d8e Mon Sep 17 00:00:00 2001
From: gligorov <vladimir.gligorov@cern.ch>
Date: Fri, 21 Jun 2019 15:22:46 +0200
Subject: [PATCH 6/8] fix typo

---
 cuda/UT/compassUT/src/UTFastFitter.cu | 85 +++++++++++++--------------
 1 file changed, 42 insertions(+), 43 deletions(-)

diff --git a/cuda/UT/compassUT/src/UTFastFitter.cu b/cuda/UT/compassUT/src/UTFastFitter.cu
index 035427c9c9d..bfeae4a4350 100644
--- a/cuda/UT/compassUT/src/UTFastFitter.cu
+++ b/cuda/UT/compassUT/src/UTFastFitter.cu
@@ -47,51 +47,50 @@ __host__ __device__ float fastfitter(
   const float zKink = UT::Constants::magFieldParams[0] - ty*ty*UT::Constants::magFieldParams[1] - ty*ty*ty*ty*UT::Constants::magFieldParams[2];
   const float xMidField = velo_state.x + velo_state.tx*(zKink-velo_state.z);
 
-    const float zDiff     = 0.001f * (zKink - UT::Constants::zMidUT);
-
-    // -- This is to avoid division by zero...
-    const float pHelper   = std::max( float(std::abs(best_params.qp * qpxz2p)), float(1e-9));
-    const float invP      = pHelper*sqrtf(1.0f+ty*ty);
-    
-    // these resolution are semi-empirical, could be tuned and might not be correct for low momentum.
-    // this is the resolution due to multiple scattering between Velo and UT
-    const float error1    = 0.14f + 10000.0f*invP; 
-    // this is the resolution due to the finite Velo resolution
-    const float error2    = 0.12f + 3000.0f*invP;  
-    const float error     = error1*error1 + error2*error2;
-    const float weight    = 1.0f/error;
-    
-    float mat[6]          = {weight, weight * zDiff, weight * zDiff * zDiff, 0.0f, 0.0f, 0.0f};
-    float rhs[3]          = {weight * xMidField, weight * xMidField * zDiff, 0.0f };
-
-    const float yyProto = velo_state.y - velo_state.ty * velo_state.z;
-    
-    for (int i = 0; i < UT::Constants::n_layers; ++i) {
-      if (best_hits[i] != -1) {
-        const auto hit = best_hits[i];
-        
-        const int plane_code = i;
-        const float dxDy = ut_dxDy[plane_code];
-        const float yy = yyProto + (velo_state.ty * ut_hits.zAtYEq0[hit]);
-        const float ui = ut_hits.xAt(hit, yy, dxDy);
-        const float dz = 0.001f * (ut_hits.zAtYEq0[hit] - UT::Constants::zMidUT);
-        const float w = ut_hits.weight[hit];  
-        const float t = ut_hits.sinT(hit, dxDy); 
-        
-        mat[0] += w;
-        mat[1] += w * dz; 
-        mat[2] += w * dz * dz; 
-        mat[3] += w * t; 
-        mat[4] += w * dz * t; 
-        mat[5] += w * t * t; 
-
-        rhs[0] += w * ui; 
-        rhs[1] += w * ui * dz; 
-        rhs[2] += w * ui * t; 
-      }
+  const float zDiff     = 0.001f * (zKink - UT::Constants::zMidUT);
+
+  // -- This is to avoid division by zero...
+  const float pHelper   = std::max( float(std::abs(best_params.qp * qpxz2p)), float(1e-9));
+  const float invP      = pHelper*sqrtf(1.0f+ty*ty);
+  
+  // these resolution are semi-empirical, could be tuned and might not be correct for low momentum.
+  // this is the resolution due to multiple scattering between Velo and UT
+  const float error1    = 0.14f + 10000.0f*invP; 
+  // this is the resolution due to the finite Velo resolution
+  const float error2    = 0.12f + 3000.0f*invP;  
+  const float error     = error1*error1 + error2*error2;
+  const float weight    = 1.0f/error;
+  
+  float mat[6]          = {weight, weight * zDiff, weight * zDiff * zDiff, 0.0f, 0.0f, 0.0f};
+  float rhs[3]          = {weight * xMidField, weight * xMidField * zDiff, 0.0f };
+
+  const float yyProto = velo_state.y - velo_state.ty * velo_state.z;
+  
+  for (int i = 0; i < UT::Constants::n_layers; ++i) {
+    if (best_hits[i] != -1) {
+      const auto hit = best_hits[i];
+      
+      const int plane_code = i;
+      const float dxDy = ut_dxDy[plane_code];
+      const float yy = yyProto + (velo_state.ty * ut_hits.zAtYEq0[hit]);
+      const float ui = ut_hits.xAt(hit, yy, dxDy);
+      const float dz = 0.001f * (ut_hits.zAtYEq0[hit] - UT::Constants::zMidUT);
+      const float w = ut_hits.weight[hit];  
+      const float t = ut_hits.sinT(hit, dxDy); 
+      
+      mat[0] += w;
+      mat[1] += w * dz; 
+      mat[2] += w * dz * dz; 
+      mat[3] += w * t; 
+      mat[4] += w * dz * t; 
+      mat[5] += w * t * t; 
+
+      rhs[0] += w * ui; 
+      rhs[1] += w * ui * dz; 
+      rhs[2] += w * ui * t; 
     }
   }
-
+  
   const float a11 = mat[2] * mat[5] - mat[4] * mat[4];
   const float a12 = mat[4] * mat[3] - mat[1] * mat[5];
   const float a13 = mat[1] * mat[4] - mat[2] * mat[3];
-- 
GitLab


From 189aa7bb03fd119443a1847af72d8f670e3d9841 Mon Sep 17 00:00:00 2001
From: gligorov <vladimir.gligorov@cern.ch>
Date: Fri, 21 Jun 2019 16:06:51 +0200
Subject: [PATCH 7/8] fix final problem hopefully

---
 integration/non_event_data/include/Consumers.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/integration/non_event_data/include/Consumers.h b/integration/non_event_data/include/Consumers.h
index 03b58f46cc7..be29d3174cf 100644
--- a/integration/non_event_data/include/Consumers.h
+++ b/integration/non_event_data/include/Consumers.h
@@ -40,19 +40,11 @@ namespace Consumers {
 
   struct UTLookupTables final : public Allen::NonEventData::Consumer {
   public:
-<<<<<<< HEAD
-
-=======
->>>>>>> 14ca1f567707df93f55218f870f1d2808083af3d
     UTLookupTables(UTMagnetTool*& tool);
 
     void consume(std::vector<char> const& data) override;
 
   private:
-<<<<<<< HEAD
-
-=======
->>>>>>> 14ca1f567707df93f55218f870f1d2808083af3d
     std::reference_wrapper<UTMagnetTool*> m_tool;
     size_t m_size = 0;
   };
-- 
GitLab


From dd0872687460ebe16bf1275474dc90489fac32e1 Mon Sep 17 00:00:00 2001
From: gligorov <vladimir.gligorov@cern.ch>
Date: Mon, 24 Jun 2019 22:26:57 +0200
Subject: [PATCH 8/8] add back PrForward history

---
 cuda/SciFi/README.md | 107 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)
 create mode 100644 cuda/SciFi/README.md

diff --git a/cuda/SciFi/README.md b/cuda/SciFi/README.md
new file mode 100644
index 00000000000..b8cb83696ec
--- /dev/null
+++ b/cuda/SciFi/README.md
@@ -0,0 +1,107 @@
+// *********************************************************************************
+// ************************ Introduction to Forward Tracking **********************
+// *********************************************************************************
+//
+//  A detailed introduction in Forward tracking (with real pictures!) can be
+//  found here:
+//  (2002) http://cds.cern.ch/record/684710/files/lhcb-2002-008.pdf
+//  (2007) http://cds.cern.ch/record/1033584/files/lhcb-2007-015.pdf
+//  (2014) http://cds.cern.ch/record/1641927/files/LHCb-PUB-2014-001.pdf
+//
+// *** Short Introduction in geometry:
+//
+// The SciFi Tracker Detector, or simple Fibre Tracker (FT) consits out of 3 stations.
+// Each station consists out of 4 planes/layers. Thus there are in total 12 layers,
+// in which a particle can leave a hit. The reasonable maximum number of hits a track
+// can have is thus also 12 (sometimes 2 hits per layer are picked up).
+//
+// Each layer consists out of several Fibre mats. A fibre has a diameter of below a mm.(FIXME)
+// Several fibres are glued alongside each other to form a mat.
+// A Scintilating Fibre produces light, if a particle traverses. This light is then
+// detected on the outside of the Fibre mat.
+//
+// Looking from the collision point, one (X-)layer looks like the following:
+//
+//                    y       6m
+//                    ^  ||||||||||||| Upper side
+//                    |  ||||||||||||| 2.5m
+//                    |  |||||||||||||
+//                   -|--||||||o||||||----> -x
+//                       |||||||||||||
+//                       ||||||||||||| Lower side
+//                       ||||||||||||| 2.5m
+//
+// All fibres are aranged parallel to the y-axis. There are three different
+// kinds of layers, denoted by X,U,V. The U/V layers are rotated with respect to
+// the X-layers by +/- 5 degrees, to also get a handle of the y position of the
+// particle. As due to the magnetic field particles are only deflected in
+// x-direction, this configuration offers the best resolution.
+// The layer structure in the FT is XUVX-XUVX-XUVX.
+//
+// The detector is divided into an upeer and a lower side (>/< y=0). As particles
+// are only deflected in x direction there are only very(!) few particles that go
+// from the lower to the upper side, or vice versa. The reconstruction algorithm
+// can therefore be split into two independent steps: First track reconstruction
+// for tracks in the upper side, and afterwards for tracks in the lower side.
+//
+// Due to construction issues this is NOT true for U/V layers. In these layers the
+// complete(!) fibre modules are rotated, producing a zic-zac pattern at y=0, also
+// called  "the triangles". Therefore for U/V layers it must be explicetly also
+// searched for these hit on the "other side", if the track is close to y=0.
+// Sketch (rotation exagerated!):
+//                                          _.*
+//     y ^   _.*                         _.*
+//       | .*._      Upper side       _.*._
+//       |     *._                 _.*     *._
+//       |--------*._           _.*           *._----------------> x
+//       |           *._     _.*                 *._     _.*
+//                      *._.*       Lower side      *._.*
+//
+//
+//
+//
+//
+//       Zone ordering defined on PrKernel/PrFTInfo.h
+//
+//     y ^
+//       |    1  3  5  7     9 11 13 15    17 19 21 23
+//       |    |  |  |  |     |  |  |  |     |  |  |  |
+//       |    x  u  v  x     x  u  v  x     x  u  v  x   <-- type of layer
+//       |    |  |  |  |     |  |  |  |     |  |  |  |
+//       |------------------------------------------------> z
+//       |    |  |  |  |     |  |  |  |     |  |  |  |
+//       |    |  |  |  |     |  |  |  |     |  |  |  |
+//       |    0  2  4  6     8 10 12 14    16 18 20 22
+//
+//
+// *** Short introduction in the Forward Tracking algorithm
+//
+// The track reconstruction is seperated into several steps:
+//
+// 1) Using only X-hits
+//    1.1) Preselection: collectAllXHits()
+//    1.2) Hough Transformation: xAtRef_SamePlaneHits()
+//    1.3) Cluster search: selectXCandidates()
+//    1.4) Linear and than Cubic Fit of X-Projection
+// 2) Introducing U/V hits or also called stereo hits
+//    2.1) Preselection: collectStereoHits
+//    2.2) Cluster search: selectStereoHits
+//    2.3) Fit Y-Projection
+// 3) Using all (U+V+X) hits
+//    3.1) Fitting X-Projection
+//    3.2) calculating track quality with a Neural Net
+//    3.3) final clone+ghost killing
+//
+// *****************************************************************
+
+//-----------------------------------------------------------------------------
+// This description has been copied from the x86 PrForward code whose history is
+//
+// Based on code written by :
+// 2012-03-20 : Olivier Callot
+// 2013-03-15 : Thomas Nikodem
+// 2015-02-13 : Sevda Esen [additional search in the triangles by Marian Stahl]
+// 2016-03-09 : Thomas Nikodem [complete restructuring]
+// 2018-08    : Vava Gligorov [extract code from Rec, make compile within GPU framework
+// 2018-09    : Dorothea vom Bruch [convert to CUDA, runs on GPU]
+//-----------------------------------------------------------------------------
-- 
GitLab