diff --git a/Base/Util/ConversionUtil.cpp b/Base/Util/ConversionUtil.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..28437a029630d3aff9756fcf56a784cf62d96ca8
--- /dev/null
+++ b/Base/Util/ConversionUtil.cpp
@@ -0,0 +1,29 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      Base/Util/ConversionUtil.cpp
+//! @brief     Implements namespace Conversion.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2023
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+//  ************************************************************************************************
+
+#include "Base/Util/ConversionUtil.h"
+#include "Base/Util/Assert.h"
+#include <cmath>
+#include <numbers>
+
+double Conversion::Refl::qz2alpha(double lambda, double qz)
+{
+    return std::asin(qz * lambda / 4.0 / std::numbers::pi);
+}
+
+double Conversion::Refl::qz2lambda(double alpha, double qz)
+{
+    return 4.0 * std::numbers::pi * std::sin(alpha) / qz;
+}
+
diff --git a/Base/Util/ConversionUtil.h b/Base/Util/ConversionUtil.h
new file mode 100644
index 0000000000000000000000000000000000000000..67bb7747669deaeb2b1d395a86f4172b6037e66d
--- /dev/null
+++ b/Base/Util/ConversionUtil.h
@@ -0,0 +1,26 @@
+//  ************************************************************************************************
+//
+//  BornAgain: simulate and fit reflection and scattering
+//
+//! @file      Base/Util/ConversionUtil.h
+//! @brief     Implements namespace Conversion.
+//!
+//! @homepage  http://www.bornagainproject.org
+//! @license   GNU General Public License v3 or higher (see COPYING)
+//! @copyright Forschungszentrum Jülich GmbH 2023
+//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
+//
+//  ************************************************************************************************
+
+#ifndef BORNAGAIN_BASE_UTIL_CONVERSIONUTIL_H
+#define BORNAGAIN_BASE_UTIL_CONVERSIONUTIL_H
+
+namespace Conversion::Refl {
+
+double qz2alpha(double lambda, double qz);
+
+double qz2lambda(double alpha, double qz);
+
+}
+
+#endif // BORNAGAIN_BASE_UTIL_CONVERSIONUTIL_H
diff --git a/Sim/Scan/QzScan.cpp b/Sim/Scan/QzScan.cpp
index 865f44f14d048fcf5a004ce38d7433fe19023e06..9a4c8a63e7faf173c4f72c587ba3a90ff857f24a 100644
--- a/Sim/Scan/QzScan.cpp
+++ b/Sim/Scan/QzScan.cpp
@@ -16,6 +16,7 @@
 #include "Base/Axis/MakeScale.h"
 #include "Base/Axis/Scale.h"
 #include "Base/Util/Assert.h"
+#include "Base/Util/ConversionUtil.h"
 #include "Device/Pol/PolFilter.h"
 #include "Param/Distrib/Distributions.h"
 #include "Param/Distrib/ParameterSample.h"
@@ -36,9 +37,7 @@ QzScan::QzScan(Scale* qs_nm)
     m_beams.clear();
     for (size_t i = 0; i < nScan(); i++) {
         // Qz scan is internally understood as wavelength scan
-        // TODO use some shared function "qz2lambda"
-        double lambda =
-            4.0 * std::numbers::pi * std::sin(defaultInclination) / m_axis->binCenter(i);
+        double lambda = Conversion::Refl::qz2lambda(defaultInclination, m_axis->binCenter(i));
         auto* beam = new Beam(defaultIntensity, lambda, defaultInclination);
         // Since the grazing geometry is not clear in q-space, the footprint should not be used
         beam->setFootprint(nullptr);