diff --git a/Framework/Geometry/BaseVector.h b/Framework/Geometry/BaseVector.h
index 2cd1c3e490be90485164a060cefc708dbd64806e..c16e83bb87c2d2677e87b2b11b06bd1aa958be22 100644
--- a/Framework/Geometry/BaseVector.h
+++ b/Framework/Geometry/BaseVector.h
@@ -31,6 +31,10 @@ namespace corsika::geometry {
     BaseVector(CoordinateSystem const& pCS, QuantityVector<dim> pQVector)
         : qVector(pQVector)
         , cs(&pCS) {}
+        
+    auto const& GetCoordinateSystem() const {
+        return *cs;
+    }
   };
 
 } // namespace corsika::geometry
diff --git a/Framework/Geometry/CoordinateSystem.h b/Framework/Geometry/CoordinateSystem.h
index 6f0584f5e015aa521a0031919e0b0dda98d8d224..49deebc648bbca7a3fef5d7f8137c499c225f6fa 100644
--- a/Framework/Geometry/CoordinateSystem.h
+++ b/Framework/Geometry/CoordinateSystem.h
@@ -41,7 +41,7 @@ namespace corsika::geometry {
   protected:
     static auto CreateCS() { return CoordinateSystem(); }
     friend corsika::geometry::RootCoordinateSystem; /// this is the only class that can
-                                                    /// creat ONE unique root CS
+                                                    /// create ONE unique root CS
 
   public:
     static EigenTransform GetTransformation(CoordinateSystem const& c1,
diff --git a/Framework/Utilities/CMakeList.txt b/Framework/Utilities/CMakeList.txt
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/Framework/Utilities/CMakeLists.txt b/Framework/Utilities/CMakeLists.txt
index ab6c148d9311817456198282eb1757a25264952e..5ba7827be04ef4320da6374a5b52f0fbce79be13 100644
--- a/Framework/Utilities/CMakeLists.txt
+++ b/Framework/Utilities/CMakeLists.txt
@@ -1,14 +1,13 @@
 
 set (
   UTILITIES_SOURCES  
-  Dummy.cc
+  COMBoost.cc
   )
 
 set (
   UTILITIES_HEADERS
-  Dummy.h
+  COMBoost.h
   Bit.h
-  Test.h
   Singleton.h
   )
 
@@ -29,8 +28,11 @@ set_target_properties (
   )
 
 # target dependencies on other libraries (also the header onlys)
-#target_link_libraries (
-#  )
+target_link_libraries (
+  CORSIKAutilities
+  CORSIKAgeometry
+  CORSIKAunits
+  )
 
 target_include_directories (
   CORSIKAutilities
@@ -49,13 +51,13 @@ install (
 
 # --------------------
 # code unit testing
-# add_executable (testBit testBit.cc)
+add_executable (testCOMBoost testCOMBoost.cc)
 
-# target_link_libraries (
-#   testBit
-#   CORSIKAutilities
-#   CORSIKAthirdparty # for catch2
-#   )
+target_link_libraries (
+  testCOMBoost
+  CORSIKAutilities
+  CORSIKAthirdparty # for catch2
+  )
 
-# add_test (NAME testBit COMMAND testBit)
+add_test (NAME testCOMBoost COMMAND testCOMBoost)
 
diff --git a/Framework/Utilities/COMBoost.cc b/Framework/Utilities/COMBoost.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4e8a9688ea07cb6ccd8a09e3f49d3f525effc360
--- /dev/null
+++ b/Framework/Utilities/COMBoost.cc
@@ -0,0 +1,78 @@
+/**
+ * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#include <corsika/utl/COMBoost.h>
+
+using namespace corsika::utl;
+using namespace corsika::units::si;
+
+COMBoost::COMBoost(EnergyType eProjectile, COMBoost::MomentumVector const& pProjectile,
+                   MassType mTarget)
+    : fRotation(Eigen::Matrix3d::Identity())
+    , fCS(pProjectile.GetCoordinateSystem()) {
+  // calculate matrix for rotating pProjectile to z-axis first
+  // TODO: handle the case when pProjectile ~ (0, 0, -1)
+  auto const pProjNorm = pProjectile.norm();
+  auto const a = (pProjectile / pProjNorm).GetComponents().eVector;
+
+  Eigen::Vector3d const b{0, 0, 1};
+  auto const v = a.cross(b);
+
+  Eigen::Matrix3d vHat;
+  vHat << 0, -v(2), v(1), v(2), 0, -v(0), -v(1), v(0), 0;
+
+  fRotation += vHat + vHat * vHat / (1 + a.dot(b));
+
+  // calculate boost
+  double const x = pProjNorm * units::constants::c /
+                   (eProjectile + mTarget * units::constants::cSquared);
+
+  /* Accurracy matters here, x = 1 - epsilon for ultra-relativistic boosts */
+  double const coshEta = 1 / std::sqrt((1 + x) * (1 - x));
+  //~ double const coshEta = 1 / std::sqrt((1-x*x));
+  double const sinhEta = -x * coshEta;
+
+  fBoost << coshEta, sinhEta, sinhEta, coshEta;
+
+  fInverseBoost << coshEta, -sinhEta, -sinhEta, coshEta;
+}
+
+std::tuple<EnergyType, corsika::geometry::QuantityVector<momentum_d>> COMBoost::toCoM(
+    EnergyType E, COMBoost::MomentumVector p) const {
+  corsika::geometry::QuantityVector<momentum_d> pComponents = p.GetComponents(fCS);
+  Eigen::Vector3d eVecRotated = fRotation * pComponents.eVector;
+  Eigen::Vector2d lab;
+
+  lab << (E * (1 / 1_GeV)), (eVecRotated(2) * (units::constants::c / 1_GeV).magnitude());
+
+  auto const boostedZ = fBoost * lab;
+  auto const E_CoM = boostedZ(0) * 1_GeV;
+
+  eVecRotated(2) = boostedZ(1) * (1_GeV / units::constants::c).magnitude();
+
+  return std::make_tuple(E_CoM,
+                         corsika::geometry::QuantityVector<momentum_d>{eVecRotated});
+}
+
+std::tuple<EnergyType, COMBoost::MomentumVector> COMBoost::fromCoM(
+    EnergyType E, corsika::geometry::QuantityVector<units::si::momentum_d> pCoM) const {
+  Eigen::Vector2d com;
+  com << (E * (1 / (units::constants::c * 1_Ns))),
+      (pCoM.eVector(2) * (1 / 1_Ns).magnitude());
+
+  auto const boostedZ = fInverseBoost * com;
+  auto const E_CoM = boostedZ(0) * (1_Ns * units::constants::c);
+
+  auto pLab = pCoM;
+  pLab.eVector(2) = boostedZ(1) * (1_Ns).magnitude();
+  pLab.eVector = fRotation.transpose() * pLab.eVector;
+
+  return std::make_tuple(E_CoM, MomentumVector(fCS, pLab));
+}
diff --git a/Framework/Utilities/COMBoost.h b/Framework/Utilities/COMBoost.h
new file mode 100644
index 0000000000000000000000000000000000000000..6250d422dc256c4cad102bb93bd596e9a0df2a30
--- /dev/null
+++ b/Framework/Utilities/COMBoost.h
@@ -0,0 +1,44 @@
+/**
+ * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#ifndef _include_corsika_utilties_comboost_h_
+#define _include_corsika_utilties_comboost_h_
+
+#include <corsika/geometry/CoordinateSystem.h>
+#include <corsika/geometry/QuantityVector.h>
+#include <corsika/geometry/Vector.h>
+#include <corsika/units/PhysicalUnits.h>
+#include <Eigen/Dense>
+#include <tuple>
+
+namespace corsika::utl {
+  class COMBoost {
+    Eigen::Matrix3d fRotation;
+    Eigen::Matrix2d fBoost, fInverseBoost;
+    corsika::geometry::CoordinateSystem const& fCS;
+    using MomentumVector = corsika::geometry::Vector<units::si::momentum_d>;
+
+  public:
+    //! construct a COMBoost given energy and momentum of projectile and mass of target
+    COMBoost(units::si::EnergyType eProjectile, MomentumVector const& pProjectile,
+             units::si::MassType mTarget);
+
+    //! transforms a 4-momentum from lab frame to the center-of-mass frame
+    std::tuple<units::si::EnergyType, geometry::QuantityVector<units::si::momentum_d>>
+    toCoM(units::si::EnergyType E, MomentumVector p) const;
+
+    //! transforms a 4-momentum from the center-of-mass frame back to lab frame
+    std::tuple<units::si::EnergyType, MomentumVector> fromCoM(
+        units::si::EnergyType E,
+        geometry::QuantityVector<units::si::momentum_d> pCoM) const;
+  };
+} // namespace corsika::utl
+
+#endif
diff --git a/Framework/Utilities/Dummy.cc b/Framework/Utilities/Dummy.cc
deleted file mode 100644
index fd578b8e09c10e3b26932dbc1dfdc1c36a1030b9..0000000000000000000000000000000000000000
--- a/Framework/Utilities/Dummy.cc
+++ /dev/null
@@ -1,5 +0,0 @@
-#include <corsika/utl/Dummy.h>
-
-using namespace corsika::utl;
-
-// big void...
diff --git a/Framework/Utilities/Dummy.h b/Framework/Utilities/Dummy.h
deleted file mode 100644
index dac2021b49df401d221c5160f825909440468e22..0000000000000000000000000000000000000000
--- a/Framework/Utilities/Dummy.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _include_corsika_utilties_dummy_h_
-#define _include_corsika_utilties_dummy_h_
-
-namespace corsika::utl {
-
-  // void....
-}
-
-#endif
diff --git a/Framework/Utilities/Test.h b/Framework/Utilities/Test.h
deleted file mode 100644
index 41c7cecd7a9856e2c5b68f845d22a25f64a3cf0a..0000000000000000000000000000000000000000
--- a/Framework/Utilities/Test.h
+++ /dev/null
@@ -1,237 +0,0 @@
-#ifndef _utl_Test_h_
-#define _utl_Test_h_
-
-/**
-   \file
-   Tools to do simple testing in a readable way
-
-   \author Lukas Nellen
-   \author Darko Veberic
-   \version $Id: Test.h 31925 2018-09-25 16:02:12Z darko $
-   \date 08 Feb 2004
-
-   \ingroup testing
-*/
-
-#include <utl/Triple.h>
-#include <boost/format.hpp>
-#include <boost/tuple/tuple.hpp>
-#include <boost/tuple/tuple_comparison.hpp>
-#include <boost/tuple/tuple_io.hpp>
-#include <cmath>
-
-namespace utl {
-
-  //! Predicate used in STL for searching for whitespace
-  struct IsSpace {
-    bool operator()(const char x) const {
-      return x == ' ' || x == '\r' || x == '\n' || x == '\t';
-    }
-  };
-
-  /// Predicate for equality
-  class Equal {
-  public:
-    template <typename T>
-    bool operator()(const T& lhs, const T& rhs) const {
-      return lhs == rhs;
-    }
-
-    static const char* Name() { return "equal"; }
-  };
-
-  /// Predicate for less
-  class Less {
-  public:
-    template <typename T>
-    bool operator()(const T& lhs, const T& rhs) const {
-      return lhs < rhs;
-    }
-
-    static const char* Name() { return "less"; }
-  };
-
-  /// Predicate for less or equal
-  class LessOrEqual {
-  public:
-    template <typename T>
-    bool operator()(const T& lhs, const T& rhs) const {
-      return lhs <= rhs;
-    }
-
-    static const char* Name() { return "less or equal"; }
-  };
-
-  /// Predicate for greater
-  class Greater {
-  public:
-    template <typename T>
-    bool operator()(const T& lhs, const T& rhs) const {
-      return lhs > rhs;
-    }
-
-    static const char* Name() { return "greater"; }
-  };
-
-  /// Predicate for greater or equal
-  class GreaterOrEqual {
-  public:
-    template <typename T>
-    bool operator()(const T& lhs, const T& rhs) const {
-      return lhs >= rhs;
-    }
-
-    static const char* Name() { return "greater or equal"; }
-  };
-
-  /// Predicate for approximate equality (for floating point)
-  /** The default precision is 1e-6, but it can be changed at
-      construction time.
-   */
-  class CloseTo {
-  public:
-    CloseTo(const double eps = 1e-6)
-        : fEpsilon(eps) {}
-
-    template <typename T>
-    bool operator()(const T& lhs, const T& rhs) const {
-      return IsCloseTo(lhs, rhs);
-    }
-
-    boost::format Name() const { return boost::format("close (@%g) to") % fEpsilon; }
-
-  protected:
-    template <typename T>
-    bool IsCloseAbs(const T& lhs, const T& rhs) const {
-      return std::abs(double(lhs) - double(rhs)) < fEpsilon;
-    }
-
-    bool IsCloseAbs(const utl::Triple& lhs, const utl::Triple& rhs) const {
-      return std::sqrt(TupleDist2(lhs, rhs)) < fEpsilon;
-    }
-
-    template <typename T>
-    bool IsCloseRel(const T& lhs, const T& rhs) const {
-      return 2 * std::abs(double(lhs) - double(rhs)) /
-                 (std::abs(double(lhs)) + std::abs(double(rhs))) <
-             fEpsilon;
-    }
-
-    bool IsCloseRel(const utl::Triple& lhs, const utl::Triple& rhs) const {
-      return (2 * sqrt(TupleDist2(lhs, rhs)) /
-              (sqrt(TupleDist2(lhs, utl::Triple(0, 0, 0))) +
-               sqrt(TupleDist2(rhs, utl::Triple(0, 0, 0))))) < fEpsilon;
-    }
-
-    template <typename T>
-    bool IsCloseTo(const T& lhs, const T& rhs) const {
-      if (IsCloseAbs(lhs, rhs))
-        return true;
-      else
-        return IsCloseRel(lhs, rhs);
-    }
-
-    // tuple distance
-    template <typename Head, typename Tail>
-    static double TupleDist2(const boost::tuples::cons<Head, Tail>& lhs,
-                             const boost::tuples::cons<Head, Tail>& rhs) {
-      const double t = lhs.get_head() - rhs.get_head();
-      return t * t + TupleDist2(lhs.get_tail(), rhs.get_tail());
-    }
-
-    static double TupleDist2(const boost::tuples::null_type& /*lhs*/,
-                             const boost::tuples::null_type& /*rhs*/) {
-      return 0;
-    }
-
-    double fEpsilon;
-  };
-
-  class CloseAbs : public CloseTo {
-  public:
-    CloseAbs(const double eps = 1e-6)
-        : CloseTo(eps) {}
-
-    template <typename T>
-    bool operator()(const T& lhs, const T& rhs) const {
-      return IsCloseAbs(lhs, rhs);
-    }
-
-    boost::format Name() const {
-      return boost::format("absolutely close (@%g) to") % fEpsilon;
-    }
-  };
-
-  class CloseRel : public CloseTo {
-  public:
-    CloseRel(const double eps = 1e-6)
-        : CloseTo(eps) {}
-
-    template <typename T>
-    bool operator()(const T& lhs, const T& rhs) const {
-      return IsCloseRel(lhs, rhs);
-    }
-
-    boost::format Name() const {
-      return boost::format("relatively close (@%g) to") % fEpsilon;
-    }
-  };
-
-  template <typename Predicate>
-  class Not : public Predicate {
-  public:
-    Not()
-        : Predicate() {}
-
-    Not(const double eps)
-        : Predicate(eps) {}
-
-    template <typename T>
-    bool operator()(const T& x) const {
-      return !Predicate::operator()(x);
-    }
-
-    template <typename T, typename U>
-    bool operator()(const T& x, const U& y) const {
-      return !Predicate::operator()(x, y);
-    }
-
-    template <typename T, typename U, typename W>
-    bool operator()(const T& x, const U& y, const W& z) const {
-      return !Predicate::operator()(x, y, z);
-    }
-
-    static boost::format Name() { return boost::format("not-%s") % Predicate().Name(); }
-  };
-
-  inline utl::Triple Diff(const utl::Triple& lhs, const utl::Triple& rhs) {
-    return utl::Triple(lhs.get<0>() - rhs.get<0>(), lhs.get<1>() - rhs.get<1>(),
-                       lhs.get<2>() - rhs.get<2>());
-  }
-
-  /// Test condition by evaluating a predicate
-  /** If the predicate evaluates to false, we print a failure message
-      with the values of the left- and right-hand side and the name of
-      the predicate. This information is normally not available when
-      using the CPPUNIT_ASSERT macro.
-   */
-  template <class Predicate, typename T>
-  inline bool Test(const Predicate& pred, const T& lhs, const T& rhs) {
-    return pred(lhs, rhs);
-  }
-
-  /// Main test function
-  template <class Predicate, typename T>
-  inline bool Test(const T& lhs, const T& rhs) {
-    return Test(Predicate(), lhs, rhs);
-  }
-
-  /// Test function for predicates that take an option
-  template <class Predicate, typename T, typename U>
-  inline bool Test(const T& lhs, const T& rhs, const U& eps) {
-    return Test(Predicate(eps), lhs, rhs);
-  }
-
-} // namespace utl
-
-#endif
diff --git a/Framework/Utilities/testBit.cc b/Framework/Utilities/testBit.cc
deleted file mode 100644
index a4d36d1bcae35a23c3baaa0fa96a0c05821c8fa5..0000000000000000000000000000000000000000
--- a/Framework/Utilities/testBit.cc
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
-  \file
-  Test Bit functions
-
-  \author Hans Dembinski
-  \version $Id: testBit.cc 25126 2014-02-03 22:13:10Z darko $
-  \date 27 Jan 2014
-
-  \ingroup testing
-*/
-
-#include <corsika/utl/Test.h>
-#include <cppunit/extensions/HelperMacros.h>
-#include <tst/Verify.h>
-#include <utl/Bit.h>
-#include <bitset>
-#include <cstdio>
-#include <iostream>
-
-using namespace tst;
-using namespace utl;
-using namespace std;
-
-/**
-  \ingroup testing
-*/
-class TestBit : public CppUnit::TestFixture {
-
-  CPPUNIT_TEST_SUITE(TestBit);
-  CPPUNIT_TEST(TestGet);
-  CPPUNIT_TEST(TestSet);
-  CPPUNIT_TEST(TestMask);
-  CPPUNIT_TEST_SUITE_END();
-
-public:
-  void setUp() {}
-
-  void tearDown() {}
-
-  void TestGet() {
-    const int size = sizeof(int) * 8;
-    const int bc2 = 12345;
-    int b2 = bc2;
-    bitset<size> b1(bc2);
-
-    ostringstream out1;
-    ostringstream out2;
-    ostringstream out3;
-    for (int i = 0; i < size; ++i) {
-      out1 << (b1[i] ? '^' : '.');
-      out2 << (AsBitArray(bc2)[i] ? '^' : '.');
-      out3 << (AsBitArray(b2)[i] ? '^' : '.');
-    }
-
-    CPPUNIT_ASSERT(Verify<Equal>(out1.str(), out2.str()));
-    CPPUNIT_ASSERT(Verify<Equal>(out1.str(), out3.str()));
-  }
-
-  void TestSet() {
-    const int size = sizeof(int) * 8;
-    const int number = 12345;
-    bitset<size> b1(number);
-    int b2 = 11111;
-
-    for (int i = 0; i < size; ++i) AsBitArray(b2)[i] = b1[i];
-
-    CPPUNIT_ASSERT(Verify<Equal>(b2, number));
-  }
-
-  void TestMask() {
-    const int n = (1 << 18) | (1 << 5);
-    int m = 0;
-
-    AsBitArray(m)[18] = true;
-    AsBitArray(m)[5] = true;
-    CPPUNIT_ASSERT(Verify<Equal>(n, m));
-
-    for (unsigned int i = 0; i < 8 * sizeof(int); ++i) AsBitArray(m)[i] = 0;
-    CPPUNIT_ASSERT(Verify<Equal>(m, 0));
-
-    m = 1;
-    AsBitArray(m).Mask(n, true);
-    CPPUNIT_ASSERT(Verify<Equal>(m, n + 1));
-
-    AsBitArray(m).Mask(n, false);
-    CPPUNIT_ASSERT(Verify<Equal>(m, 1));
-  }
-};
-
-CPPUNIT_TEST_SUITE_REGISTRATION(TestBit);
diff --git a/Framework/Utilities/testCOMBoost.cc b/Framework/Utilities/testCOMBoost.cc
new file mode 100644
index 0000000000000000000000000000000000000000..814d63e1f2f44463e2861f08d4b6ae5d3730af8e
--- /dev/null
+++ b/Framework/Utilities/testCOMBoost.cc
@@ -0,0 +1,81 @@
+/**
+ * (c) Copyright 2018 CORSIKA Project, corsika-project@lists.kit.edu
+ *
+ * See file AUTHORS for a list of contributors.
+ *
+ * This software is distributed under the terms of the GNU General Public
+ * Licence version 3 (GPL Version 3). See file LICENSE for a full version of
+ * the license.
+ */
+
+#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one
+                          // cpp file
+#include <catch2/catch.hpp>
+
+#include <corsika/geometry/RootCoordinateSystem.h>
+#include <corsika/units/PhysicalUnits.h>
+#include <corsika/utl/COMBoost.h>
+#include <iostream>
+
+using namespace corsika::geometry;
+using namespace corsika::utl;
+using namespace corsika::units::si;
+using corsika::units::constants::c;
+using corsika::units::constants::cSquared;
+
+double constexpr absMargin = 1e-6;
+
+TEST_CASE("boosts") {
+  CoordinateSystem& rootCS =
+      RootCoordinateSystem::GetInstance().GetRootCoordinateSystem();
+
+  // relativistic energy
+  auto energy = [](MassType m, Vector<momentum_d> const& p) {
+    return sqrt(m * m * cSquared * cSquared + p.squaredNorm() * cSquared);
+  };
+
+  // mandelstam-s
+  auto s = [](EnergyType E, QuantityVector<momentum_d> const& p) {
+    return E * E / cSquared - p.squaredNorm();
+  };
+
+  // define projectile kinematics in lab frame
+  MassType const projectileMass = 1._GeV / cSquared;
+  Vector<momentum_d> pProjectileLab{rootCS, {0_GeV / c, 1_PeV / c, 0_GeV / c}};
+  EnergyType const eProjectileLab = energy(projectileMass, pProjectileLab);
+
+  // define target kinematics in lab frame
+  MassType const targetMass = 1_GeV / cSquared;
+  Vector<momentum_d> pTargetLab{rootCS, {0_Ns, 0_Ns, 0_Ns}};
+  EnergyType const eTargetLab = energy(targetMass, pTargetLab);
+
+  // define boost to com frame
+  COMBoost boost(eProjectileLab, pProjectileLab, targetMass);
+
+  // boost projecticle
+  auto const [eProjectileCoM, pProjectileCoM] =
+      boost.toCoM(eProjectileLab, pProjectileLab);
+      
+  // boost target
+  auto const [eTargetCoM, pTargetCoM] = boost.toCoM(eTargetLab, pTargetLab);
+
+  // sum of momenta in CoM, should be 0
+  auto const sumPCoM = pProjectileCoM + pTargetCoM;
+  CHECK(sumPCoM[2] / (1_GeV / c) == Approx(0).margin(absMargin));
+
+  // mandelstam-s should be invariant under transformation
+  CHECK(s(eProjectileLab + eTargetLab,
+          pProjectileLab.GetComponents() + pTargetLab.GetComponents()) /
+            (1_GeV / c) / (1_GeV / c) ==
+        Approx(s(eProjectileCoM + eTargetCoM, pProjectileCoM + pTargetCoM) / (1_GeV / c) /
+               (1_GeV / c)));
+
+  // boost back...
+  auto const [eProjectileBack, pProjectileBack] =
+      boost.fromCoM(eProjectileCoM, pProjectileCoM);
+
+  // ...should yield original values before the boosts
+  CHECK(eProjectileBack / eProjectileLab == Approx(1));
+  CHECK((pProjectileBack - pProjectileLab).norm() / pProjectileLab.norm() ==
+        Approx(0).margin(absMargin));
+}