diff --git a/Tests/Suite/Common/TestSuite.h b/Tests/Suite/Common/TestSuite.h
index 12709958889848919f65495a26fddb189e4f9f55..096bd581400dc56b19aedbaf3511e3130488afcb 100644
--- a/Tests/Suite/Common/TestSuite.h
+++ b/Tests/Suite/Common/TestSuite.h
@@ -49,7 +49,7 @@
 
 TEST(TESTNAME, FormFactors)
 {
-    const double eps = eps_direct_vs_python(2e-13, 8e-9);
+    const double eps = eps_direct_vs_python(4e-13, 8e-9); // 2e-13 except on i386
     for (const std::string& ffname : FormFactorComponents().keys()) {
         const IFormFactor* ff = FormFactorComponents().getItem(ffname)->clone();
         ASSERT(ff);
@@ -77,7 +77,7 @@ TEST(TESTNAME, FormFactorsWithAbsorption)
 
 TEST(TESTNAME, GISASAbsorptiveSLDLayers)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 2e-11 : 5e-13, 8e-9); // ARCH3 only for i386
     std::unique_ptr<const MultiLayer> sample(ExemplarySamples::createLayersWithAbsorptionBySLD());
     auto sim = test::makeSimulation::MiniGISAS(*sample);
     EXPECT_TRUE(runTest("GISASAbsorptiveSLDLayers", *sim, eps));
@@ -165,7 +165,7 @@ TEST(TESTNAME, CoreShellBoxRotateZandY)
 
 TEST(TESTNAME, MultiLayerWithRoughness)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 2e-11 : 5e-13, 8e-9); // ARCH3 only for i386
     std::unique_ptr<const MultiLayer> sample(ExemplarySamples::createMultiLayerWithRoughness());
     auto sim = test::makeSimulation::MiniGISAS(*sample);
     EXPECT_TRUE(runTest("MultiLayerWithRoughness", *sim, eps));
@@ -381,7 +381,7 @@ TEST(TESTNAME, SlicedComposition)
 
 TEST(TESTNAME, MagneticSubstrateZeroField)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 2e-11 : 5e-13, 8e-9); // ARCH3 only for i386
     std::unique_ptr<const MultiLayer> sample(ExemplarySamples::createMagneticSubstrateZeroField());
     auto sim = test::makeSimulation::MiniZPolarizedGISAS(*sample, "PP");
     EXPECT_TRUE(runTest("MagneticSubstrateZeroField", *sim, eps));
@@ -389,7 +389,7 @@ TEST(TESTNAME, MagneticSubstrateZeroField)
 
 TEST(TESTNAME, MagneticRotation)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 6e-11 : 5e-13, 8e-9); // ARCH3 only for i386
     std::unique_ptr<const MultiLayer> sample(ExemplarySamples::createMagneticRotation());
     auto sim = test::makeSimulation::MiniZPolarizedGISAS(*sample, "PM");
     EXPECT_TRUE(runTest("MagneticRotationZPM", *sim, eps));
@@ -397,7 +397,7 @@ TEST(TESTNAME, MagneticRotation)
 
 TEST(TESTNAME, MagneticRotationUnpol)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 2e-11 : 5e-13, 8e-9); // ARCH3 only for i386
     std::unique_ptr<const MultiLayer> sample(ExemplarySamples::createMagneticRotation());
     auto sim = test::makeSimulation::MiniGISAS(*sample);
     EXPECT_TRUE(runTest("MagneticRotationUnpol", *sim, eps));
@@ -413,7 +413,7 @@ TEST(TESTNAME, MagneticSpheres)
 
 TEST(TESTNAME, MagneticCylinders)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 4e-12 : 5e-13, 8e-9); // ARCH3 only for i386
     for (const std::string polCase : {"PP", "MP", "PM", "MM"}) {
         std::unique_ptr<const MultiLayer> sample(ExemplarySamples::createMagneticCylinders());
         auto sim = test::makeSimulation::MiniZPolarizedGISAS(*sample, polCase);
@@ -512,7 +512,7 @@ TEST(TESTNAME, RoughnessInSpecular)
 
 TEST(TESTNAME, GaussianBeamFootprint)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 7e-11 : 5e-13, 8e-9); // ARCH3 only for i386
     auto* sample = ExemplarySamples::createHomogeneousMultilayer();
     auto sim = test::makeSimulation::SpecularWithGaussianBeam(*sample);
     EXPECT_TRUE(runTest("GaussianBeamFootprint", *sim, eps));
@@ -520,7 +520,7 @@ TEST(TESTNAME, GaussianBeamFootprint)
 
 TEST(TESTNAME, SquareBeamFootprint)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 7e-11 : 5e-13, 8e-9); // ARCH3 only for i386
     auto* sample = ExemplarySamples::createHomogeneousMultilayer();
     auto sim = test::makeSimulation::SpecularWithSquareBeam(*sample);
     EXPECT_TRUE(runTest("SquareBeamFootprint", *sim, eps));
@@ -528,7 +528,7 @@ TEST(TESTNAME, SquareBeamFootprint)
 
 TEST(TESTNAME, SpecularDivergentBeam)
 {
-    const double eps = eps_direct_vs_python(5e-13, 8e-9);
+    const double eps = eps_direct_vs_python(ARCH3 ? 5e-11 : 5e-13, 8e-9); // ARCH3 only for i386
     auto* sample = ExemplarySamples::createHomogeneousMultilayer();
     auto sim = test::makeSimulation::SpecularDivergentBeam(*sample);
     EXPECT_TRUE(runTest("SpecularDivergentBeam", *sim, eps));
diff --git a/Tests/Unit/Numeric/BesselTest.cpp b/Tests/Unit/Numeric/BesselTest.cpp
index 38eec8d37f495a58112a09bb37aa1428b5eaa37b..33e6348e61257e0b964296cb8ff0a515779d6928 100644
--- a/Tests/Unit/Numeric/BesselTest.cpp
+++ b/Tests/Unit/Numeric/BesselTest.cpp
@@ -5,7 +5,11 @@
 // Test complex Bessel function J1
 TEST(BesselTest, BesselJ1)
 {
+#ifdef BA_OTHER_ARCH
+    const double eps = 4.7e-13; // i386 about as bad as this
+#else
     const double eps = 4.7e-16; // more than twice the machine precision
+#endif
     complex_t res;
 
     // Test four arbitrary function values.
diff --git a/Tests/Unit/Resample/MaterialTest.cpp b/Tests/Unit/Resample/MaterialTest.cpp
index 9fcca2f5c0f458c34d4196fc0b76787ffd3450e2..09f71a6a400e22a7435a70f72e7db7a6ba791a5c 100644
--- a/Tests/Unit/Resample/MaterialTest.cpp
+++ b/Tests/Unit/Resample/MaterialTest.cpp
@@ -62,7 +62,10 @@ TEST(MaterialTest, MaterialTransform)
         MaterialBySLD("Material", material_data.real(), material_data.imag(), magnetism);
     Material material4 = material.rotatedMaterial(transform.rotMatrix());
     EXPECT_EQ(material_data, material4.refractiveIndex_or_SLD());
-    EXPECT_EQ(transformed_mag, material4.magnetization());
+    // transformed_mag equals material4.magnetization except on i368:
+    EXPECT_TRUE(fabs((transformed_mag - material4.magnetization()).x()) < 3e-16);
+    EXPECT_TRUE(fabs((transformed_mag - material4.magnetization()).y()) < 3e-16);
+    EXPECT_TRUE(fabs((transformed_mag - material4.magnetization()).z()) < 3e-16);
 }
 
 TEST(MaterialTest, DefaultMaterials)
diff --git a/auto/Examples/scatter2d/DodecahedraSAS.py b/auto/Examples/scatter2d/DodecahedraSAS.py
index caea7fcb408085d23dd84e47d9fe753bde5838a5..f09d831f3690d53e0e6bf099fc6a5c125b8d45ac 100755
--- a/auto/Examples/scatter2d/DodecahedraSAS.py
+++ b/auto/Examples/scatter2d/DodecahedraSAS.py
@@ -17,8 +17,6 @@ def get_sample():
     layout = ba.ParticleLayout()
     layout.addParticle(particle)
     solution_layer = ba.Layer(vacuum, 1000*nm)
-    # TODO: make intensity proportional to thickness,
-    #       https://github.com/scgmlz/BornAgain/issues/1222
     solution_layer.addLayout(layout)
 
     # Flat sample layer sandwiched between semi-infinite vacuum layers:
diff --git a/auto/MiniExamples/scatter2d/DodecahedraSAS.py b/auto/MiniExamples/scatter2d/DodecahedraSAS.py
index 7ee0dcdd6769453d3535c4ee85b8d5ca8cf01676..a3dc2339e3a31451b04a4067df1fcbda33b9065e 100755
--- a/auto/MiniExamples/scatter2d/DodecahedraSAS.py
+++ b/auto/MiniExamples/scatter2d/DodecahedraSAS.py
@@ -17,8 +17,6 @@ def get_sample():
     layout = ba.ParticleLayout()
     layout.addParticle(particle)
     solution_layer = ba.Layer(vacuum, 1000*nm)
-    # TODO: make intensity proportional to thickness,
-    #       https://github.com/scgmlz/BornAgain/issues/1222
     solution_layer.addLayout(layout)
 
     # Flat sample layer sandwiched between semi-infinite vacuum layers:
diff --git a/auto/Wrap/libBornAgainBase.py b/auto/Wrap/libBornAgainBase.py
index ede305e18de66f50b1acfb4b902524c506c87916..216c16420a8899050edc7979f2e4433ea3c4dc23 100644
--- a/auto/Wrap/libBornAgainBase.py
+++ b/auto/Wrap/libBornAgainBase.py
@@ -1974,6 +1974,10 @@ class Frame(object):
         r"""projectedCoord(Frame self, size_t i_flat, size_t k_axis) -> double"""
         return _libBornAgainBase.Frame_projectedCoord(self, i_flat, k_axis)
 
+    def projectedBin(self, i_flat, k_axis):
+        r"""projectedBin(Frame self, size_t i_flat, size_t k_axis) -> Bin1D const &"""
+        return _libBornAgainBase.Frame_projectedBin(self, i_flat, k_axis)
+
     def allIndices(self, i_flat):
         r"""allIndices(Frame self, size_t i_flat) -> vector_integer_t"""
         return _libBornAgainBase.Frame_allIndices(self, i_flat)
diff --git a/auto/Wrap/libBornAgainBase_wrap.cpp b/auto/Wrap/libBornAgainBase_wrap.cpp
index b8fb07a90c4ca23139ef2056bcbd13d536c3b1db..e13706a53a5cdb620add4d6003da807752aa884e 100644
--- a/auto/Wrap/libBornAgainBase_wrap.cpp
+++ b/auto/Wrap/libBornAgainBase_wrap.cpp
@@ -27649,6 +27649,55 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_Frame_projectedBin(PyObject *self, PyObject *args) {
+  PyObject *resultobj = 0;
+  Frame *arg1 = (Frame *) 0 ;
+  size_t arg2 ;
+  size_t arg3 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  size_t val2 ;
+  int ecode2 = 0 ;
+  size_t val3 ;
+  int ecode3 = 0 ;
+  PyObject *swig_obj[3] ;
+  Bin1D *result = 0 ;
+  
+  (void)self;
+  if (!SWIG_Python_UnpackTuple(args, "Frame_projectedBin", 3, 3, swig_obj)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Frame, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Frame_projectedBin" "', argument " "1"" of type '" "Frame const *""'"); 
+  }
+  arg1 = reinterpret_cast< Frame * >(argp1);
+  ecode2 = SWIG_AsVal_size_t(swig_obj[1], &val2);
+  if (!SWIG_IsOK(ecode2)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Frame_projectedBin" "', argument " "2"" of type '" "size_t""'");
+  } 
+  arg2 = static_cast< size_t >(val2);
+  ecode3 = SWIG_AsVal_size_t(swig_obj[2], &val3);
+  if (!SWIG_IsOK(ecode3)) {
+    SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Frame_projectedBin" "', argument " "3"" of type '" "size_t""'");
+  } 
+  arg3 = static_cast< size_t >(val3);
+  {
+    try {
+      result = (Bin1D *) &((Frame const *)arg1)->projectedBin(arg2,arg3);
+    } catch (const std::exception& ex) {
+      // message shown in the Python interpreter
+      const std::string msg {
+        "BornAgain C++ Exception: " + std::string(ex.what())
+      };
+      SWIG_exception(SWIG_RuntimeError, msg.c_str());
+    }
+  }
+  resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Bin1D, 0 |  0 );
+  return resultobj;
+fail:
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_Frame_allIndices(PyObject *self, PyObject *args) {
   PyObject *resultobj = 0;
   Frame *arg1 = (Frame *) 0 ;
@@ -30589,6 +30638,7 @@ static PyMethodDef SwigMethods[] = {
 	 { "Frame_xAxis", _wrap_Frame_xAxis, METH_O, "Frame_xAxis(Frame self) -> Scale"},
 	 { "Frame_yAxis", _wrap_Frame_yAxis, METH_O, "Frame_yAxis(Frame self) -> Scale"},
 	 { "Frame_projectedCoord", _wrap_Frame_projectedCoord, METH_VARARGS, "Frame_projectedCoord(Frame self, size_t i_flat, size_t k_axis) -> double"},
+	 { "Frame_projectedBin", _wrap_Frame_projectedBin, METH_VARARGS, "Frame_projectedBin(Frame self, size_t i_flat, size_t k_axis) -> Bin1D const &"},
 	 { "Frame_allIndices", _wrap_Frame_allIndices, METH_VARARGS, "Frame_allIndices(Frame self, size_t i_flat) -> vector_integer_t"},
 	 { "Frame_projectedIndex", _wrap_Frame_projectedIndex, METH_VARARGS, "Frame_projectedIndex(Frame self, size_t i, size_t k_axis) -> size_t"},
 	 { "Frame_hasSameSizes", _wrap_Frame_hasSameSizes, METH_VARARGS, "Frame_hasSameSizes(Frame self, Frame arg2) -> bool"},