diff --git a/Base/Util/Assert.h b/Base/Util/Assert.h
index 8379ecfc6bc9da3bc0052b63e56d39a8d245876a..24a05cb62fbe055179a4fdb2626088d696dfd9ed 100644
--- a/Base/Util/Assert.h
+++ b/Base/Util/Assert.h
@@ -46,7 +46,7 @@
         throw std::runtime_error("Forbidden case ... and we should never get here");               \
     }
 
-#else // BA_DEBUG
+#else // not BA_DEBUG
 
 #include <stdexcept>
 
diff --git a/GUI/Model/Descriptor/DoubleProperty.cpp b/GUI/Model/Descriptor/DoubleProperty.cpp
index 59d93d13ff7e4b177e48efc899d9fb4dd030982f..9ec883cb87d6d71c5d746dc1507b42732fa9a9f0 100644
--- a/GUI/Model/Descriptor/DoubleProperty.cpp
+++ b/GUI/Model/Descriptor/DoubleProperty.cpp
@@ -44,16 +44,6 @@ void DoubleProperty::init(const QString& label, const QString& tooltip, double v
         m_uid = QUuid::createUuid().toString();
 }
 
-void DoubleProperty::setTooltip(const QString& tooltip)
-{
-    m_tooltip = tooltip;
-}
-
-void DoubleProperty::setLimits(const RealLimits& limits)
-{
-    m_limits = limits;
-}
-
 bool DoubleProperty::isInitialized() const
 {
     return !m_uid.isEmpty();
diff --git a/GUI/Model/Descriptor/DoubleProperty.h b/GUI/Model/Descriptor/DoubleProperty.h
index a0ce7da5f2316758f5e8118d954c95923cb73d3e..a640d82ea211c79f5f678543d1904e5067ec0496 100644
--- a/GUI/Model/Descriptor/DoubleProperty.h
+++ b/GUI/Model/Descriptor/DoubleProperty.h
@@ -56,10 +56,9 @@ public:
     void setDecimals(uint decimals) { m_decimals = decimals; }
 
     QString tooltip() const { return m_tooltip; }
-    void setTooltip(const QString& tooltip);
 
     RealLimits limits() const { return m_limits; }
-    void setLimits(const RealLimits& limits);
+    void setLimits(const RealLimits& limits) { m_limits = limits; }
 
     //! True if one of the init methods has been called (checks for a valid uid).
     bool isInitialized() const;
diff --git a/GUI/Model/Descriptor/SpanProperty.h b/GUI/Model/Descriptor/SpanProperty.h
index 773e3a16d633d02a37164387aafaa6fed875a9a7..5911d593bc00af66c521827e576dca5944755eb1 100644
--- a/GUI/Model/Descriptor/SpanProperty.h
+++ b/GUI/Model/Descriptor/SpanProperty.h
@@ -45,9 +45,9 @@ public:
     void setCenter(double v) { m_center.setValue(v); }
 
     void initWidth(const QString& label, const QString& tooltip, double value,
-                   const RealLimits& limits = RealLimits::nonnegative(), uint decimals = 3);
+                   const RealLimits& limits, uint decimals = 3);
     void initCenter(const QString& label, const QString& tooltip, double value,
-                    const RealLimits& limits = RealLimits::nonnegative(), uint decimals = 3);
+                    const RealLimits& limits, uint decimals = 3);
 
     Scale createAxis(const std::string& name) const;
 
diff --git a/GUI/View/Device/SpanPropertyForm.cpp b/GUI/View/Device/SpanPropertyForm.cpp
index 43d7ac611d0ed2af9a742505b598dde3b6009734..c4b34798b16aea48319ff32ed3b07209f3ad9b76 100644
--- a/GUI/View/Device/SpanPropertyForm.cpp
+++ b/GUI/View/Device/SpanPropertyForm.cpp
@@ -44,10 +44,10 @@ SpanPropertyForm::SpanPropertyForm(QWidget* parent, const QString& groupTitle,
 
     connect(m_widthSpinBox, &DoubleSpinBox::baseValueChanged, [this](double v) {
         ASSERT(v >= 0); // spin box should have got limits from property
-        if (m_spanProperty->width() == v)
-            return;
-        m_spanProperty->setWidth(v);
-        emit dataChanged();
+        if (m_spanProperty->width() != v) {
+            m_spanProperty->setWidth(v);
+            emit dataChanged();
+        }
     });
 
     connect(m_centerSpinBox, &DoubleSpinBox::baseValueChanged, [this](double v) {
diff --git a/Resample/Processed/ReSample.cpp b/Resample/Processed/ReSample.cpp
index eb76a376dea3e1620a0aa00f286b3469d4ff269a..5be718867e4ba6c8467a8e302aa47ad5aa31f885 100644
--- a/Resample/Processed/ReSample.cpp
+++ b/Resample/Processed/ReSample.cpp
@@ -35,6 +35,7 @@
 #include "Sample/Particle/IParticle.h"
 #include <iomanip>
 #include <iostream>
+#include <stdexcept>
 
 namespace {
 
@@ -241,8 +242,11 @@ ReLayout* makeReLayout(const ParticleLayout& layout, const SliceStack& slices, d
                        const SimulationOptions& options, bool polarized)
 {
     const double layout_abundance = layout.totalAbundance();
-    ASSERT(layout_abundance > 0);
+    if (layout_abundance <= 0)
+        throw std::runtime_error("Particle layout has invalid total abundance <= 0");
     const double surface_density = layout.totalParticleSurfaceDensity();
+    if (surface_density <= 0)
+        throw std::runtime_error("Particle layout has invalid surface density <= 0");
 
     OwningVector<const CoheringSubparticles> coherentParticles;
 
diff --git a/Tests/Examples/CMakeLists.txt b/Tests/Examples/CMakeLists.txt
index 2d3a1c890bb2933ec7aaeb7d72d853f6738d2e50..79c876e6431f906806aba4deb96c923e1fa3e999 100644
--- a/Tests/Examples/CMakeLists.txt
+++ b/Tests/Examples/CMakeLists.txt
@@ -197,6 +197,7 @@ run_example(scatter2d/PositionVariance) # TODO -> test
 test_example(scatter2d/RectangularGrating 0.6)
 test_example(scatter2d/Resolution 2e-8) # reduced accuracy on Win and Mac
 test_example(scatter2d/RotatedPyramids 2e-10)
+test_example(scatter2d/RoughAndSpecular 0.3) # ISSUE 864
 test_example(scatter2d/SlicedLayer 2e-10)
 test_example(scatter2d/SpheresAtHexLattice 2e-10)
 test_example(scatter2d/TriangularRipple 2e-10)
diff --git a/Tests/ReferenceData/MiniExamples/scatter2d/RoughAndSpecular.int b/Tests/ReferenceData/MiniExamples/scatter2d/RoughAndSpecular.int
new file mode 100644
index 0000000000000000000000000000000000000000..af2b440d42aab637b3aaf2b823dc7123584df3b3
--- /dev/null
+++ b/Tests/ReferenceData/MiniExamples/scatter2d/RoughAndSpecular.int
@@ -0,0 +1,21 @@
+# BornAgain Intensity Data
+
+# axis-0
+EquiDivision("phi_f (rad)", 11, -0.0349065850398866, 0.0349065850398866)
+
+# axis-1
+EquiDivision("alpha_f (rad)", 11, -0.010471975511966, 0.0244346095279206)
+
+# data
+3.125908936134e-13 2.618427637463e-12 1.218815228706e-06 4.447049250491e-01 7.840127199784e+00 1.165244994996e+00 4.613523194949e-01 2.221292120027e-01 1.134150897895e-01 5.322633678391e-02 2.288511677892e-02
+1.202402359478e-12 -2.462099274623e-12 2.161483608884e-06 7.886554109959e-01 1.390394122242e+01 2.066484500601e+00 8.181769783931e-01 3.939300070782e-01 2.011320584661e-01 9.439127967658e-02 4.058350078893e-02
+6.779553991327e-13 2.126753912338e-12 4.496141197366e-06 1.640493384847e+00 2.892177728108e+01 4.298523551842e+00 1.701898788538e+00 8.194134097221e-01 4.183689485371e-01 1.963356250783e-01 8.441085554015e-02
+-1.575628516548e-12 -6.366462912410e-12 1.235401775546e-05 4.507574966892e+00 7.946826614252e+01 1.181104416795e+01 4.676284185925e+00 2.251456087107e+00 1.149487123189e+00 5.394038268741e-01 2.318799587197e-01
+1.528657140163e-12 -2.822851020723e-12 6.056660950189e-05 2.209876407028e+01 3.896013701467e+02 5.790498840760e+01 2.292559216915e+01 1.103705463519e+01 5.634094865621e+00 2.643030512331e+00 1.135612050921e+00
+1.140055053453e-12 -6.100078081714e-12 4.876137579466e-04 1.779142200329e+02 3.137128879973e+03 1.570960440946e+05 1.849874265793e+02 8.881720328924e+01 4.529768043801e+01 2.121350723259e+01 9.088627874077e+00
+7.704495496282e-13 -9.379005576722e-13 6.056661043293e-05 2.209876407028e+01 3.896013701467e+02 5.790498840760e+01 2.292559216915e+01 1.103705463519e+01 5.634094865621e+00 2.643030512330e+00 1.135612050920e+00
+4.991562718715e-13 -5.456968210638e-12 1.235401732913e-05 4.507574966894e+00 7.946826614252e+01 1.181104416796e+01 4.676284185925e+00 2.251456087105e+00 1.149487123191e+00 5.394038268764e-01 2.318799587187e-01
+-1.197351431657e-12 -4.652941373410e-14 4.496138437451e-06 1.640493384848e+00 2.892177728108e+01 4.298523551842e+00 1.701898788539e+00 8.194134097231e-01 4.183689485357e-01 1.963356250794e-01 8.441085554039e-02
+1.664637579314e-12 -1.175879532469e-12 2.161485538213e-06 7.886554109958e-01 1.390394122242e+01 2.066484500591e+00 8.181769783904e-01 3.939300070749e-01 2.011320584638e-01 9.439127967465e-02 4.058350079259e-02
+-1.551835805243e-12 4.462268325475e-13 1.218812479671e-06 4.447049250507e-01 7.840127199784e+00 1.165244994996e+00 4.613523194956e-01 2.221292120036e-01 1.134150897882e-01 5.322633678500e-02 2.288511677918e-02
+
diff --git a/auto/Examples/fit/scatter2d/expfit_galaxi.py b/auto/Examples/fit/scatter2d/expfit_galaxi.py
index 560a99b4c334238f7a555835406c94e0e27be434..c173661b99dd54209cdb68ea9d2eb6da7dc76c3b 100755
--- a/auto/Examples/fit/scatter2d/expfit_galaxi.py
+++ b/auto/Examples/fit/scatter2d/expfit_galaxi.py
@@ -96,7 +96,7 @@ def create_detector(beam):
     """
     nx = pilatus_npx
     ny = pilatus_npy
-    return ba.Detector2D(3.4*deg, 1.84*deg, nx, ny, 0, 0.92*deg)
+    return ba.Detector2D(3.4*deg, 1.84*deg, nx, ny, 0, 0.32*deg)
 
 
 def create_simulation(P):
diff --git a/auto/Examples/scatter2d/RoughAndSpecular.py b/auto/Examples/scatter2d/RoughAndSpecular.py
new file mode 100755
index 0000000000000000000000000000000000000000..1690fe9871c79dbdf93eba7f6b35e550d949a98a
--- /dev/null
+++ b/auto/Examples/scatter2d/RoughAndSpecular.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+import bornagain as ba
+from bornagain import ba_plot as bp, deg, nm
+
+def get_sample():
+    # Define materials
+    material_HMDSO = ba.RefractiveMaterial("HMDSO", 2.0888e-06, 1.3261e-08)
+    material_PTFE = ba.RefractiveMaterial("PTFE", 5.20509e-06, 1.9694e-08)
+    material_Si = ba.RefractiveMaterial("Si", 5.7816e-06, 1.0229e-07)
+    material_Vacuum = ba.RefractiveMaterial("Vacuum", 0.0, 0.0)
+
+    # Define roughness
+    roughness_1 = ba.LayerRoughness(1.1, 0.3, 5*nm)
+    roughness_2 = ba.LayerRoughness(2.3, 0.3, 5*nm)
+
+    # Define layers
+    layer_1 = ba.Layer(material_Vacuum)
+    layer_2 = ba.Layer(material_HMDSO, 18.5*nm)
+    layer_3 = ba.Layer(material_PTFE, 22.1*nm)
+    layer_4 = ba.Layer(material_Si)
+
+    # Define sample
+    sample = ba.MultiLayer()
+    sample.addLayer(layer_1)
+    sample.addLayerWithTopRoughness(layer_2, roughness_1)
+    sample.addLayerWithTopRoughness(layer_3, roughness_2)
+    sample.addLayer(layer_4)
+
+    return sample
+
+
+def get_simulation(sample):
+    beam = ba.Beam(1e9, 0.1*nm, 0.4*deg)
+    n = 200
+    detector = ba.Detector2D(4*deg, 2*deg, n, n, 0, .4*deg)
+    detector.setResolutionFunction(
+        ba.ResolutionFunction2DGaussian(0.02*deg, 0.02*deg))
+    simulation = ba.ScatteringSimulation(beam, sample, detector)
+    simulation.options().setUseAvgMaterials(True)
+    simulation.options().setIncludeSpecular(True)
+    return simulation
+
+
+if __name__ == '__main__':
+    sample = get_sample()
+    simulation = get_simulation(sample)
+    result = simulation.simulate()
+    bp.plot_simulation_result(result)
+    bp.show_or_export()
diff --git a/auto/MiniExamples/fit/scatter2d/expfit_galaxi.py b/auto/MiniExamples/fit/scatter2d/expfit_galaxi.py
index 57b273fc50cf25bb524b272461aa1329d5392b2f..5dd586f210131c37d5df5af136c114f13e46097e 100755
--- a/auto/MiniExamples/fit/scatter2d/expfit_galaxi.py
+++ b/auto/MiniExamples/fit/scatter2d/expfit_galaxi.py
@@ -96,7 +96,7 @@ def create_detector(beam):
     """
     nx = pilatus_npx
     ny = pilatus_npy
-    return ba.Detector2D(3.4*deg, 1.84*deg, nx, ny, 0, 0.92*deg)
+    return ba.Detector2D(3.4*deg, 1.84*deg, nx, ny, 0, 0.32*deg)
 
 
 def create_simulation(P):
diff --git a/auto/MiniExamples/scatter2d/RoughAndSpecular.py b/auto/MiniExamples/scatter2d/RoughAndSpecular.py
new file mode 100755
index 0000000000000000000000000000000000000000..f9c1a73cbd204452c8645b02a757602fe021b671
--- /dev/null
+++ b/auto/MiniExamples/scatter2d/RoughAndSpecular.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+import bornagain as ba
+from bornagain import ba_plot as bp, deg, nm
+
+def get_sample():
+    # Define materials
+    material_HMDSO = ba.RefractiveMaterial("HMDSO", 2.0888e-06, 1.3261e-08)
+    material_PTFE = ba.RefractiveMaterial("PTFE", 5.20509e-06, 1.9694e-08)
+    material_Si = ba.RefractiveMaterial("Si", 5.7816e-06, 1.0229e-07)
+    material_Vacuum = ba.RefractiveMaterial("Vacuum", 0.0, 0.0)
+
+    # Define roughness
+    roughness_1 = ba.LayerRoughness(1.1, 0.3, 5*nm)
+    roughness_2 = ba.LayerRoughness(2.3, 0.3, 5*nm)
+
+    # Define layers
+    layer_1 = ba.Layer(material_Vacuum)
+    layer_2 = ba.Layer(material_HMDSO, 18.5*nm)
+    layer_3 = ba.Layer(material_PTFE, 22.1*nm)
+    layer_4 = ba.Layer(material_Si)
+
+    # Define sample
+    sample = ba.MultiLayer()
+    sample.addLayer(layer_1)
+    sample.addLayerWithTopRoughness(layer_2, roughness_1)
+    sample.addLayerWithTopRoughness(layer_3, roughness_2)
+    sample.addLayer(layer_4)
+
+    return sample
+
+
+def get_simulation(sample):
+    beam = ba.Beam(1e9, 0.1*nm, 0.4*deg)
+    n = 11
+    detector = ba.Detector2D(4*deg, 2*deg, n, n, 0, .4*deg)
+    detector.setResolutionFunction(
+        ba.ResolutionFunction2DGaussian(0.02*deg, 0.02*deg))
+    simulation = ba.ScatteringSimulation(beam, sample, detector)
+    simulation.options().setUseAvgMaterials(True)
+    simulation.options().setIncludeSpecular(True)
+    return simulation
+
+
+if __name__ == '__main__':
+    sample = get_sample()
+    simulation = get_simulation(sample)
+    result = simulation.simulate()
+    bp.plot_simulation_result(result)
+    bp.show_or_export()
diff --git a/rawEx/fit/scatter2d/expfit_galaxi.py b/rawEx/fit/scatter2d/expfit_galaxi.py
index 03714ccde3763f457744f037e30773350a272d7b..d08afe016ed7a73d4d94bdb73d1d57b1ba54a029 100755
--- a/rawEx/fit/scatter2d/expfit_galaxi.py
+++ b/rawEx/fit/scatter2d/expfit_galaxi.py
@@ -96,7 +96,7 @@ def create_detector(beam):
     """
     nx = pilatus_npx
     ny = pilatus_npy
-    return ba.Detector2D(3.4*deg, 1.84*deg, nx, ny, 0, 0.92*deg)
+    return ba.Detector2D(3.4*deg, 1.84*deg, nx, ny, 0, 0.32*deg)
 
 
 def create_simulation(P):
diff --git a/rawEx/scatter2d/RoughAndSpecular.py b/rawEx/scatter2d/RoughAndSpecular.py
new file mode 100755
index 0000000000000000000000000000000000000000..4b2b1b41dc6f134484dfe2a6e67f83a355f59963
--- /dev/null
+++ b/rawEx/scatter2d/RoughAndSpecular.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+import bornagain as ba
+from bornagain import ba_plot as bp, deg, nm
+
+def get_sample():
+    # Define materials
+    material_HMDSO = ba.RefractiveMaterial("HMDSO", 2.0888e-06, 1.3261e-08)
+    material_PTFE = ba.RefractiveMaterial("PTFE", 5.20509e-06, 1.9694e-08)
+    material_Si = ba.RefractiveMaterial("Si", 5.7816e-06, 1.0229e-07)
+    material_Vacuum = ba.RefractiveMaterial("Vacuum", 0.0, 0.0)
+
+    # Define roughness
+    roughness_1 = ba.LayerRoughness(1.1, 0.3, 5*nm)
+    roughness_2 = ba.LayerRoughness(2.3, 0.3, 5*nm)
+
+    # Define layers
+    layer_1 = ba.Layer(material_Vacuum)
+    layer_2 = ba.Layer(material_HMDSO, 18.5*nm)
+    layer_3 = ba.Layer(material_PTFE, 22.1*nm)
+    layer_4 = ba.Layer(material_Si)
+
+    # Define sample
+    sample = ba.MultiLayer()
+    sample.addLayer(layer_1)
+    sample.addLayerWithTopRoughness(layer_2, roughness_1)
+    sample.addLayerWithTopRoughness(layer_3, roughness_2)
+    sample.addLayer(layer_4)
+
+    return sample
+
+
+def get_simulation(sample):
+    beam = ba.Beam(1e9, 0.1*nm, 0.4*deg)
+    n = <%= sm ? 11 : 200 %>
+    detector = ba.Detector2D(4*deg, 2*deg, n, n, 0, .4*deg)
+    detector.setResolutionFunction(
+        ba.ResolutionFunction2DGaussian(0.02*deg, 0.02*deg))
+    simulation = ba.ScatteringSimulation(beam, sample, detector)
+    simulation.options().setUseAvgMaterials(True)
+    simulation.options().setIncludeSpecular(True)
+    return simulation
+
+
+if __name__ == '__main__':
+    sample = get_sample()
+    simulation = get_simulation(sample)
+    result = simulation.simulate()
+    bp.plot_simulation_result(result)
+    bp.show_or_export()