diff --git a/Core/Simulation/SpecularSimulation.cpp b/Core/Simulation/SpecularSimulation.cpp
index 2f087640c3379fa65c8814dba1cc13187fdc9cef..96acc82f5634625da4a4231ced0f3ae8195fba57 100644
--- a/Core/Simulation/SpecularSimulation.cpp
+++ b/Core/Simulation/SpecularSimulation.cpp
@@ -14,6 +14,7 @@
 
 #include "Core/Simulation/SpecularSimulation.h"
 #include "Base/Axis/PointwiseAxis.h"
+#include "Base/Utils/Assert.h"
 #include "Core/Background/IBackground.h"
 #include "Core/Computation/SpecularComputation.h"
 #include "Core/Element/SpecularElement.h"
@@ -70,9 +71,7 @@ SpecularSimulation::~SpecularSimulation() = default;
 
 void SpecularSimulation::prepareSimulation()
 {
-    if (detector().dimension() != 1) // detector must have only one axis
-        throw std::runtime_error("Error in SpecularSimulation::prepareSimulation: the detector was "
-                                 "not properly configured.");
+    ASSERT(detector().dimension() == 1);
     instrument().initDetector();
     ISimulation::prepareSimulation();
 }
@@ -107,9 +106,7 @@ void SpecularSimulation::setScan(const ISpecularScan& scan)
 
     m_scan.reset(scan.clone());
 
-    if (detector().dimension() > 0)
-        throw std::runtime_error("Error in SpecularSimulation::setScan: Axis already set");
-
+    ASSERT(detector().dimension() == 0); // check that axis has not been set before
     detector().addAxis(*scan.coordinateAxis());
 
     // TODO: remove when pointwise resolution is implemented
@@ -119,9 +116,8 @@ void SpecularSimulation::setScan(const ISpecularScan& scan)
 
 const IAxis* SpecularSimulation::coordinateAxis() const
 {
-    if (!m_scan || !m_scan->coordinateAxis())
-        throw std::runtime_error(
-            "Error in SpecularSimulation::getAlphaAxis: coordinate axis was not initialized.");
+    ASSERT(m_scan);
+    ASSERT(m_scan->coordinateAxis());
     return m_scan->coordinateAxis();
 }
 
@@ -145,8 +141,7 @@ ICoordSystem* SpecularSimulation::createCoordSystem() const
 
 void SpecularSimulation::initElementVector()
 {
-    if (!m_scan)
-        throw std::runtime_error("Error in SpecularSimulation: beam parameters were not set.");
+    ASSERT(m_scan);
     m_eles = generateElements(instrument(), *m_scan);
 
     if (!m_cache.empty())
@@ -166,9 +161,7 @@ SpecularSimulation::createComputation(const ProcessedSample& re_sample, size_t s
 
 void SpecularSimulation::checkCache() const
 {
-    if (m_eles.size() != m_cache.size())
-        throw std::runtime_error("Error in SpecularSimulation: the sizes of simulation element "
-                                 "vector and of its cache are different");
+    ASSERT(m_eles.size() == m_cache.size());
 }
 
 void SpecularSimulation::validateParametrization(const ParameterDistribution& par_distr) const
@@ -238,9 +231,7 @@ std::vector<double> SpecularSimulation::rawResults() const
 void SpecularSimulation::setRawResults(const std::vector<double>& raw_data)
 {
     initElementVector();
-    if (raw_data.size() != m_eles.size())
-        throw std::runtime_error("SpecularSimulation::setRawResults: size of vector passed as "
-                                 "argument doesn't match number of elements in this simulation");
+    ASSERT(raw_data.size() == m_eles.size());
     for (unsigned i = 0; i < raw_data.size(); i++)
         m_eles[i].setIntensity(raw_data[i]);
     transferResultsToIntensityMap();
diff --git a/auto/Wrap/doxygenCore.i b/auto/Wrap/doxygenCore.i
index 419d036c46beb0baa65233775a52bde8837e6d84..dbb31555369a6a54d283bbcb9862c3887c4b1970 100644
--- a/auto/Wrap/doxygenCore.i
+++ b/auto/Wrap/doxygenCore.i
@@ -46,7 +46,7 @@ Returns IFootprintFactor object pointer.
 Returns footprint correction factor for a range of simulation elements of size  n_elements and starting from element with index  i. 
 ";
 
-%feature("docstring")  AngularSpecScan::numberOfDiffuseElements "size_t AngularSpecScan::numberOfDiffuseElements() const override
+%feature("docstring")  AngularSpecScan::numberOfElements "size_t AngularSpecScan::numberOfElements() const override
 
 Returns the number of simulation elements. 
 ";
@@ -1162,7 +1162,7 @@ Returns IFootprintFactor object pointer.
 Returns footprint correction factor for a range of simulation elements of size  n_elements and starting from element with index  i. 
 ";
 
-%feature("docstring")  ISpecularScan::numberOfDiffuseElements "virtual size_t ISpecularScan::numberOfDiffuseElements() const =0
+%feature("docstring")  ISpecularScan::numberOfElements "virtual size_t ISpecularScan::numberOfElements() const =0
 
 Returns the number of simulation elements. 
 ";
@@ -1642,7 +1642,7 @@ Returns IFootprintFactor object pointer.
 Returns footprint correction factor for a range of simulation elements of size  n_elements and starting from element with index  i. 
 ";
 
-%feature("docstring")  QSpecScan::numberOfDiffuseElements "size_t QSpecScan::numberOfDiffuseElements() const override
+%feature("docstring")  QSpecScan::numberOfElements "size_t QSpecScan::numberOfElements() const override
 
 Returns the number of simulation elements. 
 ";
diff --git a/auto/Wrap/doxygenDevice.i b/auto/Wrap/doxygenDevice.i
index 5c904268faa10f3e07e3bd3b334be2660b753a37..f0bb4f1a614c394e796d665cd5aca2506149dcc3 100644
--- a/auto/Wrap/doxygenDevice.i
+++ b/auto/Wrap/doxygenDevice.i
@@ -442,7 +442,7 @@ C++ includes: DetectorContext.h
 %feature("docstring")  DetectorContext::DetectorContext "DetectorContext::DetectorContext(const DetectorContext &other)=delete
 ";
 
-%feature("docstring")  DetectorContext::numberOfDiffuseElements "size_t DetectorContext::numberOfDiffuseElements() const
+%feature("docstring")  DetectorContext::numberOfElements "size_t DetectorContext::numberOfElements() const
 ";
 
 %feature("docstring")  DetectorContext::createPixel "std::unique_ptr< IPixel > DetectorContext::createPixel(size_t element_index) const
@@ -1133,7 +1133,7 @@ Returns new intensity map with resolution applied, and cropped to ROI if applica
 Return default axes units. 
 ";
 
-%feature("docstring")  IDetector::numberOfDiffuseElements "size_t IDetector::numberOfDiffuseElements() const
+%feature("docstring")  IDetector::numberOfElements "size_t IDetector::numberOfElements() const
 
 Returns number of simulation elements. 
 ";
diff --git a/auto/Wrap/libBornAgainDevice.py b/auto/Wrap/libBornAgainDevice.py
index af438da7d5bb01ab73056b55d9192114d490126b..f3cdea0fb84f42de9dd2d05a4cb0a6cd5bd49cb2 100644
--- a/auto/Wrap/libBornAgainDevice.py
+++ b/auto/Wrap/libBornAgainDevice.py
@@ -4155,15 +4155,15 @@ class IDetector(libBornAgainBase.ICloneable, libBornAgainParam.INode):
         """
         return _libBornAgainDevice.IDetector_defaultCoords(self)
 
-    def numberOfDiffuseElements(self):
+    def numberOfElements(self):
         r"""
-        numberOfDiffuseElements(IDetector self) -> size_t
-        size_t IDetector::numberOfDiffuseElements() const
+        numberOfElements(IDetector self) -> size_t
+        size_t IDetector::numberOfElements() const
 
         Returns number of simulation elements. 
 
         """
-        return _libBornAgainDevice.IDetector_numberOfDiffuseElements(self)
+        return _libBornAgainDevice.IDetector_numberOfElements(self)
 
     def regionOfInterestBounds(self, iAxis):
         r"""
diff --git a/auto/Wrap/libBornAgainDevice_wrap.cpp b/auto/Wrap/libBornAgainDevice_wrap.cpp
index d1ef4a5727968fa75a476f8e00cc645b9fbea25a..2c8fffa384ae0b2cd008eddf08b7f2c922a19d69 100644
--- a/auto/Wrap/libBornAgainDevice_wrap.cpp
+++ b/auto/Wrap/libBornAgainDevice_wrap.cpp
@@ -36382,7 +36382,7 @@ fail:
 }
 
 
-SWIGINTERN PyObject *_wrap_IDetector_numberOfDiffuseElements(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+SWIGINTERN PyObject *_wrap_IDetector_numberOfElements(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   IDetector *arg1 = (IDetector *) 0 ;
   void *argp1 = 0 ;
@@ -36394,10 +36394,10 @@ SWIGINTERN PyObject *_wrap_IDetector_numberOfDiffuseElements(PyObject *SWIGUNUSE
   swig_obj[0] = args;
   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_IDetector, 0 |  0 );
   if (!SWIG_IsOK(res1)) {
-    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector_numberOfDiffuseElements" "', argument " "1"" of type '" "IDetector const *""'"); 
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "IDetector_numberOfElements" "', argument " "1"" of type '" "IDetector const *""'"); 
   }
   arg1 = reinterpret_cast< IDetector * >(argp1);
-  result = ((IDetector const *)arg1)->numberOfDiffuseElements();
+  result = ((IDetector const *)arg1)->numberOfElements();
   resultobj = SWIG_From_size_t(static_cast< size_t >(result));
   return resultobj;
 fail:
@@ -45770,9 +45770,9 @@ static PyMethodDef SwigMethods[] = {
 		"Return default axes units. \n"
 		"\n"
 		""},
-	 { "IDetector_numberOfDiffuseElements", _wrap_IDetector_numberOfDiffuseElements, METH_O, "\n"
-		"IDetector_numberOfDiffuseElements(IDetector self) -> size_t\n"
-		"size_t IDetector::numberOfDiffuseElements() const\n"
+	 { "IDetector_numberOfElements", _wrap_IDetector_numberOfElements, METH_O, "\n"
+		"IDetector_numberOfElements(IDetector self) -> size_t\n"
+		"size_t IDetector::numberOfElements() const\n"
 		"\n"
 		"Returns number of simulation elements. \n"
 		"\n"