diff --git a/Device/Beam/Beam.h b/Device/Beam/Beam.h
index f780dab16453b0df9006865287d3405e4c88967b..0407e4ea581d209dd741b286550f52bb2240442a 100644
--- a/Device/Beam/Beam.h
+++ b/Device/Beam/Beam.h
@@ -97,7 +97,6 @@ private:
     //! Deprecated for direct use; prefer factory functions InBeam or UnitBeam.
     Beam(double intensity, double wavelength, double alpha, double phi = 0);
     Beam(std::vector<double> P);
-#endif // SWIG
 
     void precompute();
 
@@ -113,6 +112,7 @@ private:
     R3 m_k;
 
     friend class DepthprobeSimulationTest;
+#endif // SWIG
 };
 
 // Factory functions in global namespace:
diff --git a/Sim/Scan/AlphaScan.cpp b/Sim/Scan/AlphaScan.cpp
index ebe43ef8c9dc7afae242bdf5b114563003f31753..c2cb81e99acb9035882be55a5bed53d1dbb69637 100644
--- a/Sim/Scan/AlphaScan.cpp
+++ b/Sim/Scan/AlphaScan.cpp
@@ -58,6 +58,7 @@ AlphaScan* AlphaScan::clone() const
     auto* result = new AlphaScan(*m_axis);
     result->setIntensity(intensity());
     result->setFootprint(m_footprint.get());
+    result->setAlphaOffset(alphaOffset());
 
     if (m_lambda_distrib)
         result->m_lambda_distrib.reset(m_lambda_distrib->clone());
@@ -99,7 +100,7 @@ std::vector<SpecularElement> AlphaScan::generateElements() const
         const std::vector<ParameterSample> alphaDistrib = drawDistribution(m_alpha_distrib.get());
         const std::vector<ParameterSample> lambdaDistrib = drawDistribution(m_lambda_distrib.get());
         for (size_t j = 0; j < alphaDistrib.size(); ++j) {
-            const double alpha = m_axis->binCenters()[i] + alphaDistrib[j].value;
+            const double alpha = m_axis->binCenters()[i] + alphaDistrib[j].value + m_alpha_offset;
             for (size_t k = 0; k < lambdaDistrib.size(); ++k) {
                 const double lambda = m_lambda_distrib ? lambdaDistrib[k].value : wavelength();
                 const bool computable = lambda >= 0 && alpha >= 0 && alpha <= M_PI_2;
diff --git a/Sim/Scan/AlphaScan.h b/Sim/Scan/AlphaScan.h
index 7e66442720296ea728f1b35914888226e3b5240b..c1c384b89229c0a726fb74c1ee07643093915fb3 100644
--- a/Sim/Scan/AlphaScan.h
+++ b/Sim/Scan/AlphaScan.h
@@ -36,6 +36,7 @@ public:
     void setAngleDistribution(const IDistribution1D& distr);
 
     void setWavelength(double lambda);
+    void setAlphaOffset(double offset) { m_alpha_offset = offset; }
 
 #ifndef SWIG
     //! Generates simulation elements for specular simulations
@@ -55,11 +56,18 @@ public:
         return m_alpha_distrib.get();
     }
 
+    double alphaOffset() const
+    {
+        return m_alpha_offset;
+    }
+
 private:
     void checkInitialization();
 
     std::unique_ptr<const IDistribution1D> m_lambda_distrib;
     std::unique_ptr<const IDistribution1D> m_alpha_distrib;
+
+    double m_alpha_offset{0};
 #endif // SWIG
 };
 
diff --git a/Sim/Simulation/DepthprobeSimulation.cpp b/Sim/Simulation/DepthprobeSimulation.cpp
index a053413461f6782926e0dc96406410249a4e3d45..dba6eca9ad075da31253d9d39fec0f8dbee50445 100644
--- a/Sim/Simulation/DepthprobeSimulation.cpp
+++ b/Sim/Simulation/DepthprobeSimulation.cpp
@@ -15,10 +15,8 @@
 #include "Sim/Simulation/DepthprobeSimulation.h"
 #include "Base/Axis/Bin.h"
 #include "Base/Axis/FixedBinAxis.h"
-#include "Base/Axis/Frame.h"
 #include "Base/Math/Constants.h"
 #include "Base/Util/Assert.h"
-#include "Device/Beam/Beam.h"
 #include "Device/Beam/IFootprintFactor.h"
 #include "Device/Coord/CoordSystem2D.h"
 #include "Device/Data/Datafield.h"
@@ -28,13 +26,14 @@
 #include "Resample/Element/DepthprobeElement.h"
 #include "Sim/Computation/DepthprobeComputation.h"
 #include "Sim/Scan/AlphaScan.h"
+#include <iostream>
 
 DepthprobeSimulation::DepthprobeSimulation(const IBeamScan& scan, const MultiLayer& sample)
     : ISimulation(sample)
-    , m_scan(scan.clone())
-    , m_beam(InBeam(1., scan.wavelength(), 0., 0.).clone())
-    , m_alpha_axis(scan.coordinateAxis()->clone())
+    , m_scan(dynamic_cast<AlphaScan*>(scan.clone()))
 {
+    if (!m_scan)
+        throw std::runtime_error("DepthprobeSimulation not implemented for non-alpha scan");
 }
 
 DepthprobeSimulation::~DepthprobeSimulation() = default;
@@ -49,7 +48,7 @@ void DepthprobeSimulation::setzSpan(size_t n_bins, double z_min, double z_max)
 
 const ICoordSystem* DepthprobeSimulation::simCoordSystem() const
 {
-    std::vector<const IAxis*> axes({m_alpha_axis->clone(), m_z_axis->clone()});
+    std::vector<const IAxis*> axes({m_scan->coordinateAxis()->clone(), m_z_axis->clone()});
     return new DepthprobeCoords(axes, M_TWOPI / m_scan->wavelength()); // TODO mv conversion
 }
 
@@ -68,10 +67,11 @@ void DepthprobeSimulation::initDistributionHandler()
     for (const auto& distribution : distributionHandler().paramDistributions()) {
 
         switch (distribution.whichParameter()) {
-        case ParameterDistribution::BeamInclinationAngle:
+        case ParameterDistribution::BeamInclinationAngle: {
             distributionHandler().defineCallbackForDistribution(
-                &distribution, [&](double d) { m_beam->setInclination(d); });
+                &distribution, [&](double d) { m_scan->setAlphaOffset(d); });
             break;
+        }
         case ParameterDistribution::BeamWavelength:
             distributionHandler().defineCallbackForDistribution(
                 &distribution, [&](double d) { m_scan->setWavelength(d); });
@@ -84,7 +84,7 @@ void DepthprobeSimulation::initDistributionHandler()
 
 void DepthprobeSimulation::runComputation(const ReSample& re_sample, size_t i, double weight)
 {
-    const double result_angle = m_alpha_axis->bin(i).center() + m_beam->alpha_i();
+    const double result_angle = m_scan->coordinateAxis()->bin(i).center() + m_scan->alphaOffset();
     DepthprobeElement ele(m_scan->wavelength(), -result_angle, m_z_axis.get(),
                           0 < result_angle && result_angle < M_PI_2);
 
diff --git a/Sim/Simulation/DepthprobeSimulation.h b/Sim/Simulation/DepthprobeSimulation.h
index a8d833a0097c623da7f7341c9c269a9782d54027..3c67ad1f882d3da553699266b214ac187387cec6 100644
--- a/Sim/Simulation/DepthprobeSimulation.h
+++ b/Sim/Simulation/DepthprobeSimulation.h
@@ -17,8 +17,7 @@
 
 #include "Sim/Simulation/ISimulation.h"
 
-class Beam;
-class DepthprobeElement;
+class AlphaScan;
 class IAxis;
 class IBeamScan;
 class IFootprintFactor;
@@ -43,7 +42,7 @@ public:
 
 #ifndef SWIG
 
-    const IBeamScan& scan() const
+    const AlphaScan& scan() const
     {
         return *m_scan;
     }
@@ -74,13 +73,8 @@ private:
     SimulationResult packResult() override;
 
     //... Model components:
-    std::unique_ptr<IBeamScan> m_scan;
-    std::unique_ptr<Beam> m_beam;
-
-    //... Caches:
-    std::unique_ptr<IAxis> m_alpha_axis;
+    std::unique_ptr<AlphaScan> m_scan;
     std::unique_ptr<IAxis> m_z_axis;
-    std::vector<DepthprobeElement> m_depth_eles;
 #endif // SWIG
 };
 
diff --git a/Sim/Simulation/OffspecSimulation.cpp b/Sim/Simulation/OffspecSimulation.cpp
index 146e2654b01efe50eb79269bfd6cd0e865e4b97d..0e98c4c56b62d284a91c019e8f919edeae965b62 100644
--- a/Sim/Simulation/OffspecSimulation.cpp
+++ b/Sim/Simulation/OffspecSimulation.cpp
@@ -33,7 +33,6 @@ OffspecSimulation::OffspecSimulation(const IBeamScan& scan, const MultiLayer& sa
     : ISimulation(sample)
     , m_scan(scan.clone())
     , m_detector(detector.clone())
-    , m_alpha_i_axis(scan.coordinateAxis()->clone())
 {
 }
 
@@ -50,8 +49,6 @@ std::vector<const INode*> OffspecSimulation::nodeChildren() const
 
 void OffspecSimulation::prepareSimulation()
 {
-    ASSERT(m_alpha_i_axis);
-    ASSERT(m_alpha_i_axis->size() >= 1);
     m_pixels.reserve(m_detector->totalSize());
     for (size_t i = 0; i < m_detector->totalSize(); ++i)
         m_pixels.emplace_back(m_detector->createPixel(i));
@@ -122,22 +119,20 @@ bool OffspecSimulation::force_polarized() const
 
 size_t OffspecSimulation::nElements() const
 {
-    return m_detector->totalSize() * m_alpha_i_axis->size();
+    return m_detector->totalSize() * m_scan->coordinateAxis()->size();
 }
 
 SimulationResult OffspecSimulation::packResult()
 {
 
     // update intensity map
-    ASSERT(m_alpha_i_axis);
-    Datafield intensity_map({m_alpha_i_axis->clone(), m_detector->axis(1).clone()});
+    Datafield intensity_map({m_scan->coordinateAxis()->clone(), m_detector->axis(1).clone()});
     intensity_map.setAllTo(0.);
 
     size_t ny = m_detector->axis(1).size();
 
-    // Normalize, apply detector resolution and transfer detector image corresponding to
-    // alpha_i = m_alpha_i_axis->bin(index)
-    for (size_t j = 0; j < m_alpha_i_axis->size(); ++j) {
+    // Normalize, apply detector resolution and transfer detector image
+    for (size_t j = 0; j < m_scan->coordinateAxis()->size(); ++j) {
         Datafield detector_image({m_detector->axis(0).clone(), m_detector->axis(1).clone()});
         size_t N = detector_image.size();
         for (size_t i = 0; i < N; ++i)
diff --git a/Sim/Simulation/OffspecSimulation.h b/Sim/Simulation/OffspecSimulation.h
index a7130133e590eb68480882a8599ca4aabb67cc4e..3f05b11f6c5a1bd83a19e100413f4fbeb67d0548 100644
--- a/Sim/Simulation/OffspecSimulation.h
+++ b/Sim/Simulation/OffspecSimulation.h
@@ -18,10 +18,7 @@
 #include "Base/Types/OwningVector.h"
 #include "Sim/Simulation/ISimulation.h"
 
-class Beam;
 class Datafield;
-class DiffuseElement;
-class IAxis;
 class IBeamScan;
 class IPixel;
 class OffspecDetector;
@@ -78,10 +75,8 @@ private:
     std::unique_ptr<OffspecDetector> m_detector;
 
     //... Caches:
-    std::vector<DiffuseElement> m_eles;
     OwningVector<const IPixel> m_pixels; //!< All unmasked pixels inside ROI.
-    std::unique_ptr<const IAxis> m_alpha_i_axis;
-#endif // SWIG
+#endif                                   // SWIG
 };
 
 #endif // BORNAGAIN_SIM_SIMULATION_OFFSPECSIMULATION_H
diff --git a/Sim/Simulation/ScatteringSimulation.h b/Sim/Simulation/ScatteringSimulation.h
index 221fc563a851489e5078622b06846c72538d12b8..73fd544bf164c7044ac39e520b4d3d3d73a6f699 100644
--- a/Sim/Simulation/ScatteringSimulation.h
+++ b/Sim/Simulation/ScatteringSimulation.h
@@ -19,7 +19,6 @@
 #include "Sim/Simulation/ISimulation.h"
 
 class Beam;
-class DiffuseElement;
 class IDetector;
 class IPixel;
 class IShape2D;
@@ -89,7 +88,6 @@ private:
     std::unique_ptr<IDetector> m_detector;
 
     //... Caches:
-    std::vector<DiffuseElement> m_eles;
     std::vector<size_t> m_active_indices; //!< The sequence of bin indices (unmasked, in ROI)
     OwningVector<const IPixel> m_pixels;  //!< All unmasked pixels inside ROI.
 
diff --git a/auto/Wrap/libBornAgainSim.py b/auto/Wrap/libBornAgainSim.py
index 2dffe6b981877d7057510e6ccc5e9010069c9ec6..419a708af68affb8fec00bce4c82e951a46f5c2c 100644
--- a/auto/Wrap/libBornAgainSim.py
+++ b/auto/Wrap/libBornAgainSim.py
@@ -2600,6 +2600,10 @@ class AlphaScan(IBeamScan):
         r"""setWavelength(AlphaScan self, double _lambda)"""
         return _libBornAgainSim.AlphaScan_setWavelength(self, _lambda)
 
+    def setAlphaOffset(self, offset):
+        r"""setAlphaOffset(AlphaScan self, double offset)"""
+        return _libBornAgainSim.AlphaScan_setAlphaOffset(self, offset)
+
 # Register AlphaScan in _libBornAgainSim:
 _libBornAgainSim.AlphaScan_swigregister(AlphaScan)
 class QzScan(IBeamScan):
diff --git a/auto/Wrap/libBornAgainSim_wrap.cpp b/auto/Wrap/libBornAgainSim_wrap.cpp
index 748084f39cb3def050ad89299e7ba35fd3cb19dc..a8c522258ed96a93767334d632c3bc756e6457e5 100644
--- a/auto/Wrap/libBornAgainSim_wrap.cpp
+++ b/auto/Wrap/libBornAgainSim_wrap.cpp
@@ -32441,6 +32441,35 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_AlphaScan_setAlphaOffset(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  AlphaScan *arg1 = (AlphaScan *) 0 ;
+  double arg2 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  double val2 ;
+  int ecode2 = 0 ;
+  PyObject *swig_obj[2] ;
+  
+  if (!SWIG_Python_UnpackTuple(args, "AlphaScan_setAlphaOffset", 2, 2, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_AlphaScan, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AlphaScan_setAlphaOffset" "', argument " "1"" of type '" "AlphaScan *""'"); 
+  }
+  arg1 = reinterpret_cast< AlphaScan * >(argp1);
+  ecode2 = SWIG_AsVal_double(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "AlphaScan_setAlphaOffset" "', argument " "2"" of type '" "double""'");
+  } 
+  arg2 = static_cast< double >(val2);
+  (arg1)->setAlphaOffset(arg2);
+  resultobj = SWIG_Py_Void();
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *AlphaScan_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *obj;
   if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
@@ -36153,6 +36182,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "AlphaScan_setWavelengthDistribution", _wrap_AlphaScan_setWavelengthDistribution, METH_VARARGS, "AlphaScan_setWavelengthDistribution(AlphaScan self, IDistribution1D const & distr)"},
 	 { "AlphaScan_setAngleDistribution", _wrap_AlphaScan_setAngleDistribution, METH_VARARGS, "AlphaScan_setAngleDistribution(AlphaScan self, IDistribution1D const & distr)"},
 	 { "AlphaScan_setWavelength", _wrap_AlphaScan_setWavelength, METH_VARARGS, "AlphaScan_setWavelength(AlphaScan self, double _lambda)"},
+	 { "AlphaScan_setAlphaOffset", _wrap_AlphaScan_setAlphaOffset, METH_VARARGS, "AlphaScan_setAlphaOffset(AlphaScan self, double offset)"},
 	 { "AlphaScan_swigregister", AlphaScan_swigregister, METH_O, NULL},
 	 { "AlphaScan_swiginit", AlphaScan_swiginit, METH_VARARGS, NULL},
 	 { "new_QzScan", _wrap_new_QzScan, METH_VARARGS, "\n"